229 lines
10 KiB
229 lines
10 KiB
#ifndef STORM_SETTINGS_ARGUMENTBUILDER_H_
|
|
#define STORM_SETTINGS_ARGUMENTBUILDER_H_
|
|
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <list>
|
|
#include <utility>
|
|
#include <functional>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
#include "src/settings/ArgumentType.h"
|
|
#include "src/settings/ArgumentBase.h"
|
|
#include "src/settings/Argument.h"
|
|
#include "src/settings/ArgumentValidators.h"
|
|
|
|
#include "src/utility/macros.h"
|
|
#include "src/exceptions/IllegalFunctionCallException.h"
|
|
#include "src/exceptions/IllegalArgumentTypeException.h"
|
|
|
|
namespace storm {
|
|
namespace settings {
|
|
|
|
/*!
|
|
* This class serves as an API for creating arguments.
|
|
*/
|
|
class ArgumentBuilder {
|
|
public:
|
|
/*!
|
|
* Creates a string argument with the given parameters.
|
|
*
|
|
* @param name The name of the argument.
|
|
* @param description The description of the argument.
|
|
* @return The builder of the argument.
|
|
*/
|
|
static ArgumentBuilder createStringArgument(std::string const& name, std::string const& description) {
|
|
ArgumentBuilder ab(ArgumentType::String, name, description);
|
|
return ab;
|
|
}
|
|
|
|
/*!
|
|
* Creates an integer argument with the given parameters.
|
|
*
|
|
* @param name The name of the argument.
|
|
* @param description The description of the argument.
|
|
* @return The builder of the argument.
|
|
*/
|
|
static ArgumentBuilder createIntegerArgument(std::string const& name, std::string const& description) {
|
|
ArgumentBuilder ab(ArgumentType::Integer, name, description);
|
|
return ab;
|
|
}
|
|
|
|
/*!
|
|
* Creates an unsigned integer argument with the given parameters.
|
|
*
|
|
* @param name The name of the argument.
|
|
* @param description The description of the argument.
|
|
* @return The builder of the argument.
|
|
*/
|
|
static ArgumentBuilder createUnsignedIntegerArgument(std::string const& name, std::string const& description) {
|
|
ArgumentBuilder ab(ArgumentType::UnsignedInteger, name, description);
|
|
return ab;
|
|
}
|
|
|
|
/*!
|
|
* Creates a double argument with the given parameters.
|
|
*
|
|
* @param name The name of the argument.
|
|
* @param description The description of the argument.
|
|
* @return The builder of the argument.
|
|
*/
|
|
static ArgumentBuilder createDoubleArgument(std::string const& name, std::string const& description) {
|
|
ArgumentBuilder ab(ArgumentType::Double, name, description);
|
|
return ab;
|
|
}
|
|
|
|
/*!
|
|
* Creates a boolean argument with the given parameters.
|
|
*
|
|
* @param name The name of the argument.
|
|
* @param description The description of the argument.
|
|
* @return The builder of the argument.
|
|
*/
|
|
static ArgumentBuilder createBooleanArgument(std::string const& name, std::string const& description) {
|
|
ArgumentBuilder ab(ArgumentType::Boolean, name, description);
|
|
return ab;
|
|
}
|
|
|
|
/*!
|
|
* Sets whether the argument is to be optional.
|
|
*
|
|
* @param isOptional A flag that indicates whether the argument is to be optional.
|
|
* @return A reference to the argument builder.
|
|
*/
|
|
ArgumentBuilder& setIsOptional(bool isOptional) {
|
|
this->isOptional = isOptional;
|
|
STORM_LOG_THROW(this->hasDefaultValue, storm::exceptions::IllegalFunctionCallException, "Unable to make argument '" << this->name << "' optional without default value.");
|
|
return *this;
|
|
}
|
|
|
|
#define PPCAT_NX(A, B) A ## B
|
|
#define PPCAT(A, B) PPCAT_NX(A, B)
|
|
#define MACROaddValidationFunction(funcName, funcType) ArgumentBuilder& PPCAT(addValidationFunction, funcName) (storm::settings::Argument< funcType >::userValidationFunction_t userValidationFunction) { \
|
|
STORM_LOG_THROW(this->type == ArgumentType::funcName, storm::exceptions::IllegalFunctionCallException, "Illegal validation function for argument, because it takes arguments of different type."); \
|
|
( PPCAT(this->userValidationFunctions_, funcName) ).push_back(userValidationFunction); \
|
|
return *this; \
|
|
}
|
|
|
|
// Add the methods to add validation functions.
|
|
MACROaddValidationFunction(String, std::string)
|
|
MACROaddValidationFunction(Integer, int_fast64_t)
|
|
MACROaddValidationFunction(UnsignedInteger, uint_fast64_t)
|
|
MACROaddValidationFunction(Double, double)
|
|
MACROaddValidationFunction(Boolean, bool)
|
|
|
|
|
|
#define MACROsetDefaultValue(funcName, funcType) ArgumentBuilder& PPCAT(setDefaultValue, funcName) (funcType const& defaultValue) { \
|
|
STORM_LOG_THROW(this->type == ArgumentType::funcName, storm::exceptions::IllegalFunctionCallException, "Illegal default value for argument" << this->name << ", because it is of different type."); \
|
|
PPCAT(this->defaultValue_, funcName) = defaultValue; \
|
|
this->hasDefaultValue = true; \
|
|
return *this; \
|
|
}
|
|
|
|
// Add the methods to set a default value.
|
|
MACROsetDefaultValue(String, std::string)
|
|
MACROsetDefaultValue(Integer, int_fast64_t)
|
|
MACROsetDefaultValue(UnsignedInteger, uint_fast64_t)
|
|
MACROsetDefaultValue(Double, double)
|
|
MACROsetDefaultValue(Boolean, bool)
|
|
|
|
/*!
|
|
* Builds an argument based on the information that was added to the builder object.
|
|
*
|
|
* @return The resulting argument.
|
|
*/
|
|
std::shared_ptr<ArgumentBase> build() {
|
|
STORM_LOG_THROW(!this->hasBeenBuilt, storm::exceptions::IllegalFunctionCallException, "Cannot rebuild argument with builder that was already used to build an argument.");
|
|
this->hasBeenBuilt = true;
|
|
switch (this->type) {
|
|
case ArgumentType::String: {
|
|
if (this->hasDefaultValue) {
|
|
return std::shared_ptr<ArgumentBase>(new Argument<std::string>(this->name, this->description, this->userValidationFunctions_String, this->isOptional, this->defaultValue_String));
|
|
} else {
|
|
return std::shared_ptr<ArgumentBase>(new Argument<std::string>(this->name, this->description, this->userValidationFunctions_String));
|
|
}
|
|
break;
|
|
}
|
|
case ArgumentType::Integer:
|
|
if (this->hasDefaultValue) {
|
|
return std::shared_ptr<ArgumentBase>(new Argument<int_fast64_t>(this->name, this->description, this->userValidationFunctions_Integer, this->isOptional, this->defaultValue_Integer));
|
|
} else {
|
|
return std::shared_ptr<ArgumentBase>(new Argument<int_fast64_t>(this->name, this->description, this->userValidationFunctions_Integer));
|
|
}
|
|
break;
|
|
case ArgumentType::UnsignedInteger:
|
|
if (this->hasDefaultValue) {
|
|
return std::shared_ptr<ArgumentBase>(new Argument<uint_fast64_t>(this->name, this->description, this->userValidationFunctions_UnsignedInteger, this->isOptional, this->defaultValue_UnsignedInteger));
|
|
} else {
|
|
return std::shared_ptr<ArgumentBase>(new Argument<uint_fast64_t>(this->name, this->description, this->userValidationFunctions_UnsignedInteger));
|
|
}
|
|
break;
|
|
case ArgumentType::Double:
|
|
if (this->hasDefaultValue) {
|
|
return std::shared_ptr<ArgumentBase>(new Argument<double>(this->name, this->description, this->userValidationFunctions_Double, this->isOptional, this->defaultValue_Double));
|
|
} else {
|
|
return std::shared_ptr<ArgumentBase>(new Argument<double>(this->name, this->description, this->userValidationFunctions_Double));
|
|
}
|
|
break;
|
|
case ArgumentType::Boolean:
|
|
if (this->hasDefaultValue) {
|
|
return std::shared_ptr<ArgumentBase>(new Argument<bool>(this->name, this->description, this->userValidationFunctions_Boolean, this->isOptional, this->defaultValue_Boolean));
|
|
} else {
|
|
return std::shared_ptr<ArgumentBase>(new Argument<bool>(this->name, this->description, this->userValidationFunctions_Boolean));
|
|
}
|
|
break;
|
|
}
|
|
STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentTypeException, "Argument has illegal type.");
|
|
}
|
|
|
|
private:
|
|
/*!
|
|
* Creates an argument builder for an argument with the given parameters.
|
|
*
|
|
* @param type The type of the argument.
|
|
* @param name The name of the argument.
|
|
* @param description The description of the argument.
|
|
*/
|
|
ArgumentBuilder(ArgumentType type, std::string const& name, std::string const& description) : hasBeenBuilt(false), type(type), name(name), description(description), isOptional(false), hasDefaultValue(false), defaultValue_String(), defaultValue_Integer(), defaultValue_UnsignedInteger(), defaultValue_Double(), defaultValue_Boolean(), userValidationFunctions_String(), userValidationFunctions_Integer(), userValidationFunctions_UnsignedInteger(), userValidationFunctions_Double(), userValidationFunctions_Boolean() {
|
|
// Intentionally left empty.
|
|
}
|
|
|
|
// A flag that stores whether an argument has been built using this builder.
|
|
bool hasBeenBuilt;
|
|
|
|
// The type of the argument.
|
|
ArgumentType type;
|
|
|
|
// The name of te argument.
|
|
std::string name;
|
|
|
|
// The description of the argument.
|
|
std::string description;
|
|
|
|
// A flag indicating whether the argument is optional.
|
|
bool isOptional;
|
|
|
|
// A flag that stores whether the argument has a default value.
|
|
bool hasDefaultValue;
|
|
|
|
// The default value of the argument separated by its type.
|
|
std::string defaultValue_String;
|
|
int_fast64_t defaultValue_Integer;
|
|
uint_fast64_t defaultValue_UnsignedInteger;
|
|
double defaultValue_Double;
|
|
bool defaultValue_Boolean;
|
|
|
|
// The validation functions separated by their type.
|
|
std::vector<storm::settings::Argument<std::string>::userValidationFunction_t> userValidationFunctions_String;
|
|
std::vector<storm::settings::Argument<int_fast64_t>::userValidationFunction_t> userValidationFunctions_Integer;
|
|
std::vector<storm::settings::Argument<uint_fast64_t>::userValidationFunction_t> userValidationFunctions_UnsignedInteger;
|
|
std::vector<storm::settings::Argument<double>::userValidationFunction_t> userValidationFunctions_Double;
|
|
std::vector<storm::settings::Argument<bool>::userValidationFunction_t> userValidationFunctions_Boolean;
|
|
};
|
|
}
|
|
}
|
|
|
|
#endif // STORM_SETTINGS_ARGUMENTBUILDER_H_
|