Ported test_config.cpp from upstream Slic3r.

Extended ConfigBase with set() functions similar to the upstream Slic3r.
ConfigBase::set_deserialize() newly throws if the operation fails.
Extrusion width parameters are newly tested for negative values.
This commit is contained in:
bubnikv 2019-10-18 11:53:19 +02:00
parent b7af51fd6d
commit 13cc74ef0a
6 changed files with 298 additions and 15 deletions

View file

@ -52,6 +52,16 @@ public:
std::runtime_error(std::string("No definition exception: ") + opt_key) {}
};
/// Indicate that an unsupported accessor was called on a config option.
class BadOptionTypeException : public std::runtime_error
{
public:
BadOptionTypeException() :
std::runtime_error("Bad option type exception") {}
BadOptionTypeException(const char* message) :
std::runtime_error(message) {}
};
// Type of a configuration value.
enum ConfigOptionType {
coVectorType = 0x4000,
@ -117,10 +127,10 @@ public:
virtual ConfigOption* clone() const = 0;
// Set a value from a ConfigOption. The two options should be compatible.
virtual void set(const ConfigOption *option) = 0;
virtual int getInt() const { throw std::runtime_error("Calling ConfigOption::getInt on a non-int ConfigOption"); }
virtual double getFloat() const { throw std::runtime_error("Calling ConfigOption::getFloat on a non-float ConfigOption"); }
virtual bool getBool() const { throw std::runtime_error("Calling ConfigOption::getBool on a non-boolean ConfigOption"); }
virtual void setInt(int /* val */) { throw std::runtime_error("Calling ConfigOption::setInt on a non-int ConfigOption"); }
virtual int getInt() const { throw BadOptionTypeException("Calling ConfigOption::getInt on a non-int ConfigOption"); }
virtual double getFloat() const { throw BadOptionTypeException("Calling ConfigOption::getFloat on a non-float ConfigOption"); }
virtual bool getBool() const { throw BadOptionTypeException("Calling ConfigOption::getBool on a non-boolean ConfigOption"); }
virtual void setInt(int /* val */) { throw BadOptionTypeException("Calling ConfigOption::setInt on a non-int ConfigOption"); }
virtual bool operator==(const ConfigOption &rhs) const = 0;
bool operator!=(const ConfigOption &rhs) const { return ! (*this == rhs); }
bool is_scalar() const { return (int(this->type()) & int(coVectorType)) == 0; }
@ -1513,32 +1523,48 @@ protected:
public:
// Non-virtual methods:
bool has(const t_config_option_key &opt_key) const { return this->option(opt_key) != nullptr; }
const ConfigOption* option(const t_config_option_key &opt_key) const
{ return const_cast<ConfigBase*>(this)->option(opt_key, false); }
ConfigOption* option(const t_config_option_key &opt_key, bool create = false)
{ return this->optptr(opt_key, create); }
template<typename TYPE>
TYPE* option(const t_config_option_key &opt_key, bool create = false)
{
ConfigOption *opt = this->optptr(opt_key, create);
return (opt == nullptr || opt->type() != TYPE::static_type()) ? nullptr : static_cast<TYPE*>(opt);
}
template<typename TYPE>
const TYPE* option(const t_config_option_key &opt_key) const
{ return const_cast<ConfigBase*>(this)->option<TYPE>(opt_key, false); }
template<typename TYPE>
TYPE* option_throw(const t_config_option_key &opt_key, bool create = false)
ConfigOption* option_throw(const t_config_option_key &opt_key, bool create = false)
{
ConfigOption *opt = this->optptr(opt_key, create);
if (opt == nullptr)
throw UnknownOptionException(opt_key);
return opt;
}
const ConfigOption* option_throw(const t_config_option_key &opt_key) const
{ return const_cast<ConfigBase*>(this)->option_throw(opt_key, false); }
template<typename TYPE>
TYPE* option_throw(const t_config_option_key &opt_key, bool create = false)
{
ConfigOption *opt = this->option_throw(opt_key, create);
if (opt->type() != TYPE::static_type())
throw std::runtime_error("Conversion to a wrong type");
throw BadOptionTypeException("Conversion to a wrong type");
return static_cast<TYPE*>(opt);
}
template<typename TYPE>
const TYPE* option_throw(const t_config_option_key &opt_key) const
{ return const_cast<ConfigBase*>(this)->option_throw<TYPE>(opt_key, false); }
// Apply all keys of other ConfigBase defined by this->def() to this ConfigBase.
// An UnknownOptionException is thrown in case some option keys of other are not defined by this->def(),
// or this ConfigBase is of a StaticConfig type and it does not support some of the keys, and ignore_nonexistent is not set.
@ -1551,9 +1577,25 @@ public:
t_config_option_keys diff(const ConfigBase &other) const;
t_config_option_keys equal(const ConfigBase &other) const;
std::string opt_serialize(const t_config_option_key &opt_key) const;
// Set a value. Convert numeric types using a C style implicit conversion / promotion model.
// Throw if option is not avaiable and create is not enabled,
// or if the conversion is not possible.
// Conversion to string is always possible.
void set(const std::string &opt_key, bool value, bool create = false)
{ this->option_throw<ConfigOptionBool>(opt_key, create)->value = value; }
void set(const std::string &opt_key, int value, bool create = false);
void set(const std::string &opt_key, double value, bool create = false);
void set(const std::string &opt_key, const char *value, bool create = false)
{ this->option_throw<ConfigOptionString>(opt_key, create)->value = value; }
void set(const std::string &opt_key, const std::string &value, bool create = false)
{ this->option_throw<ConfigOptionString>(opt_key, create)->value = value; }
// Set a configuration value from a string, it will call an overridable handle_legacy()
// to resolve renamed and removed configuration keys.
bool set_deserialize(const t_config_option_key &opt_key, const std::string &str, bool append = false);
bool set_deserialize_nothrow(const t_config_option_key &opt_key_src, const std::string &value_src, bool append = false);
// May throw BadOptionTypeException() if the operation fails.
void set_deserialize(const t_config_option_key &opt_key, const std::string &str, bool append = false);
struct SetDeserializeItem {
SetDeserializeItem(const char *opt_key, const char *opt_value, bool append = false) : opt_key(opt_key), opt_value(opt_value), append(append) {}
SetDeserializeItem(const std::string &opt_key, const std::string &opt_value, bool append = false) : opt_key(opt_key), opt_value(opt_value), append(append) {}
@ -1567,7 +1609,8 @@ public:
SetDeserializeItem(const std::string &opt_key, const double value, bool append = false) : opt_key(opt_key), opt_value(std::to_string(value)), append(append) {}
std::string opt_key; std::string opt_value; bool append = false;
};
bool set_deserialize(std::initializer_list<SetDeserializeItem> items);
// May throw BadOptionTypeException() if the operation fails.
void set_deserialize(std::initializer_list<SetDeserializeItem> items);
double get_abs_value(const t_config_option_key &opt_key) const;
double get_abs_value(const t_config_option_key &opt_key, double ratio_over) const;