I want to create efficient and easy to use value type. Base of the Value
is a boost::variant
(and std::variant
in the future), but I'm new in it. And I have some questions:
- In the code below, is it necessary to use recursive variant?
- Is it possible to not inherit from the
boost::variant
? Maybe more efficient way exists? - Do you have any comments or suggestions on the code below (it's not fully completed code, but only a draft)?
class Value;
typedef std::string String;
typedef std::vector<char> BinData;
typedef String URL;
typedef unsigned long long UID;
TSW_STRONG_TYPEDEF(std::time_t, Time)
typedef std::vector<Value> ValueArray;
typedef std::vector<String> StringArray;
//typedef std::pair<String, Value> NameValue;
typedef std::list<Value> ValueList;
typedef std::list<String> StringList;
typedef std::map<String, String> StringStringMap;
typedef std::map<String, Value> NameValueMap;
struct monostate
{
monostate() = default;
};
constexpr bool operator<(monostate, monostate) noexcept { return false; }
constexpr bool operator>(monostate, monostate) noexcept { return false; }
constexpr bool operator<=(monostate, monostate) noexcept { return true; }
constexpr bool operator>=(monostate, monostate) noexcept { return true; }
constexpr bool operator==(monostate, monostate) noexcept { return true; }
constexpr bool operator!=(monostate, monostate) noexcept { return false; }
typedef monostate Null;
struct Object
{
Object() = default;
Object(const Object &other) = default;
Object(Object &&other);
Object &operator=(const Object &other) = default;
Object &operator=(Object &&other);
String name;
NameValueMap fields;
bool operator<(const Object &other) const noexcept;
bool operator>(const Object &other) const noexcept;
bool operator<=(const Object &other) const noexcept;
bool operator>=(const Object &other) const noexcept;
bool operator==(const Object &other) const noexcept;
bool operator!=(const Object &other) const noexcept;
};
enum class ValueType
{
Null = 1, Array, BinData, Boolean, DoubleNumber, Int64Number, String, Time, Object, Undefined
};
// Types ordnung need to be same with ValueType ordnung.
typedef boost::variant<monostate, ValueArray, BinData, bool, double, int64_t, String, Time, Object> ValueBase;
class Value : public ValueBase
{
public:
using ValueBase::ValueBase;
Value() = default;
public:
bool can_convert(ValueType targetTypeId) const;
bool is_array() const;
bool is_bool() const;
bool is_double() const;
bool is_int64() const;
bool is_null() const;
bool is_object() const;
bool is_string() const;
bool is_bindata() const;
bool is_time() const;
bool is_undefined() const;
public:
ValueArray &to_value_array();
bool to_bool() const;
double to_double() const;
int to_int() const;
int64_t to_int64() const;
Object &to_object();
String &to_string();
BinData &to_bindata();
Time &to_time();
ValueType type() const;
public:
template <typename T>
const T& as() const { return boost::get<T> (*this); }
template <typename T>
T& as() { return boost::get<T> (*this); }
private:
// force compile error, prevent Variant(bool) to be called
Value(void *) = delete;
};
Aucun commentaire:
Enregistrer un commentaire