106 lines
3.5 KiB
C++
106 lines
3.5 KiB
C++
#ifndef ARGPARSE_VALUE_HPP
|
|
#define ARGPARSE_VALUE_HPP
|
|
#include <iostream>
|
|
#include "argparse_error.hpp"
|
|
|
|
namespace argparse {
|
|
|
|
template<class T>
|
|
class ConvertedValue {
|
|
public:
|
|
typedef T value_type;
|
|
public:
|
|
void set_value(T val) { errored_ = false; value_ = val; }
|
|
void set_error(std::string msg) { errored_ = true; error_msg_ = msg; }
|
|
|
|
T value() const { return value_; }
|
|
std::string error() const { return error_msg_; }
|
|
|
|
operator bool() { return valid(); }
|
|
bool valid() const { return !errored_; }
|
|
private:
|
|
T value_;
|
|
std::string error_msg_;
|
|
bool errored_ = true;
|
|
};
|
|
|
|
//How the value associated with an argumetn was initialized
|
|
enum class Provenance {
|
|
UNSPECIFIED,//The value was default constructed
|
|
DEFAULT, //The value was set by a default (e.g. as a command-line argument default value)
|
|
SPECIFIED, //The value was explicitly specified (e.g. explicitly specified on the command-line)
|
|
INFERRED, //The value was inferred, or conditionally set based on other values
|
|
};
|
|
|
|
/*
|
|
* ArgValue represents the 'value' of a command-line option/argument
|
|
*
|
|
* It supports implicit conversion to the underlying value_type, which means it can
|
|
* be seamlessly used as the value_type in most situations.
|
|
*
|
|
* It additionally tracks the provenance off the option, along with it's associated argument group.
|
|
*/
|
|
template<typename T>
|
|
class ArgValue {
|
|
public:
|
|
typedef T value_type;
|
|
|
|
public: //Accessors
|
|
//Automatic conversion to underlying value type
|
|
operator T() const { return value_; }
|
|
|
|
//Returns the value assoicated with this argument
|
|
const T& value() const { return value_; }
|
|
|
|
//Returns the provenance of this argument (i.e. how it was initialized)
|
|
Provenance provenance() const { return provenance_; }
|
|
|
|
//Returns the group this argument is associated with (or an empty string if none)
|
|
const std::string& argument_group() const { return argument_group_; }
|
|
|
|
const std::string& argument_name() const { return argument_name_; }
|
|
|
|
public: //Mutators
|
|
void set(ConvertedValue<T> val, Provenance prov) {
|
|
if (!val.valid()) {
|
|
//If the value didn't convert properly, it should
|
|
//have an error message so raise it
|
|
throw ArgParseConversionError(val.error());
|
|
}
|
|
value_ = val.value();
|
|
provenance_ = prov;
|
|
}
|
|
|
|
void set(T val, Provenance prov) {
|
|
value_ = val;
|
|
provenance_ = prov;
|
|
}
|
|
|
|
T& mutable_value(Provenance prov) {
|
|
provenance_ = prov;
|
|
return value_;
|
|
}
|
|
|
|
void set_argument_group(std::string grp) {
|
|
argument_group_ = grp;
|
|
}
|
|
|
|
void set_argument_name(std::string name_str) {
|
|
argument_name_ = name_str;
|
|
}
|
|
private:
|
|
T value_ = T();
|
|
Provenance provenance_ = Provenance::UNSPECIFIED;
|
|
std::string argument_group_ = "";
|
|
std::string argument_name_ = "";
|
|
};
|
|
|
|
//Automatically convert to the underlying type for ostream output
|
|
template<typename T>
|
|
std::ostream& operator<<(std::ostream& os, const ArgValue<T> t) {
|
|
return os << T(t);
|
|
}
|
|
|
|
}
|
|
#endif
|