2017-04-21 04:14:53 +00:00
|
|
|
#ifndef TOML11_VALUE
|
|
|
|
#define TOML11_VALUE
|
|
|
|
#include "traits.hpp"
|
|
|
|
#include "utility.hpp"
|
|
|
|
#include "exception.hpp"
|
2018-12-05 11:55:25 +00:00
|
|
|
#include "types.hpp"
|
2017-04-16 06:12:39 +00:00
|
|
|
#include <vector>
|
2017-04-20 07:13:06 +00:00
|
|
|
#include <tuple>
|
2017-04-16 06:12:39 +00:00
|
|
|
#include <unordered_map>
|
|
|
|
#include <cassert>
|
2017-04-21 03:56:39 +00:00
|
|
|
#include <cstdint>
|
2017-04-16 06:12:39 +00:00
|
|
|
|
|
|
|
namespace toml
|
|
|
|
{
|
|
|
|
|
|
|
|
namespace detail
|
|
|
|
{
|
2017-04-19 04:37:02 +00:00
|
|
|
struct storage_base
|
|
|
|
{
|
|
|
|
storage_base(): type(toml::value_t::Empty){}
|
|
|
|
storage_base(toml::value_t t): type(t){}
|
|
|
|
virtual ~storage_base() = default;
|
|
|
|
toml::value_t type;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
struct storage : public storage_base
|
|
|
|
{
|
2018-05-05 02:36:47 +00:00
|
|
|
static_assert(std::is_same<T, toml::Array>::value ||
|
|
|
|
std::is_same<T, toml::Table>::value,
|
2017-04-19 04:37:02 +00:00
|
|
|
"toml::detail::storage is for toml::Array or toml::Table!");
|
|
|
|
typedef T value_type;
|
2017-04-16 06:12:39 +00:00
|
|
|
|
2017-04-19 04:37:02 +00:00
|
|
|
storage() = default;
|
2017-06-12 13:04:59 +00:00
|
|
|
~storage() noexcept override = default;
|
2017-04-19 04:37:02 +00:00
|
|
|
storage(storage const&) = default;
|
|
|
|
storage(storage&&) = default;
|
|
|
|
storage& operator=(storage const&) = default;
|
|
|
|
storage& operator=(storage&&) = default;
|
|
|
|
|
|
|
|
storage(value_type const& v) : value(v){}
|
|
|
|
storage(value_type&& v) : value(std::move(v)){}
|
|
|
|
|
|
|
|
value_type value;
|
|
|
|
};
|
2017-04-16 06:12:39 +00:00
|
|
|
} // detail
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
struct value_traits
|
|
|
|
{
|
2017-04-16 07:37:19 +00:00
|
|
|
constexpr static value_t type_index = detail::check_type<T>();
|
2017-06-12 13:04:59 +00:00
|
|
|
constexpr static bool is_toml_type = detail::is_valid(detail::check_type<T>());
|
2017-04-16 07:37:19 +00:00
|
|
|
typedef typename detail::toml_default_type<type_index>::type type;
|
2017-04-16 06:12:39 +00:00
|
|
|
};
|
2018-07-08 09:58:38 +00:00
|
|
|
template<typename T>
|
|
|
|
constexpr value_t value_traits<T>::type_index;
|
|
|
|
template<typename T>
|
|
|
|
constexpr bool value_traits<T>::is_toml_type;
|
2017-04-16 06:12:39 +00:00
|
|
|
|
|
|
|
class value
|
|
|
|
{
|
2017-04-19 04:37:02 +00:00
|
|
|
typedef std::unique_ptr<detail::storage_base> storage_ptr;
|
2017-04-16 07:37:45 +00:00
|
|
|
|
2017-04-19 04:37:02 +00:00
|
|
|
public:
|
2017-04-16 07:37:45 +00:00
|
|
|
|
2017-04-19 04:37:02 +00:00
|
|
|
value() : type_(value_t::Empty){}
|
|
|
|
~value();
|
2017-04-16 07:37:45 +00:00
|
|
|
|
2017-04-19 04:37:02 +00:00
|
|
|
value(const value& v);
|
|
|
|
value(value&& v);
|
|
|
|
value& operator=(const value& v);
|
|
|
|
value& operator=(value&& v);
|
2017-04-16 07:37:45 +00:00
|
|
|
|
2017-04-19 04:37:02 +00:00
|
|
|
template<typename T, typename std::enable_if<
|
|
|
|
value_traits<T>::is_toml_type, std::nullptr_t>::type = nullptr>
|
|
|
|
value(T&& v);
|
2017-04-19 11:18:16 +00:00
|
|
|
|
2017-04-19 04:37:02 +00:00
|
|
|
template<typename T, typename std::enable_if<
|
|
|
|
value_traits<T>::is_toml_type, std::nullptr_t>::type = nullptr>
|
|
|
|
value& operator=(T&& v);
|
2017-04-16 07:37:45 +00:00
|
|
|
|
2017-04-20 01:44:11 +00:00
|
|
|
template<typename T, typename std::enable_if<
|
|
|
|
value_traits<T>::is_toml_type, std::nullptr_t>::type = nullptr>
|
|
|
|
value(std::initializer_list<T> init);
|
|
|
|
|
|
|
|
value(std::initializer_list<std::pair<toml::key, toml::value>> init);
|
|
|
|
|
2017-04-16 07:37:45 +00:00
|
|
|
value_t type() const {return type_;}
|
2017-04-16 06:12:39 +00:00
|
|
|
|
2017-04-16 07:37:19 +00:00
|
|
|
template<value_t T>
|
2017-04-19 04:37:02 +00:00
|
|
|
typename detail::toml_default_type<T>::type const& cast() const;
|
2017-04-16 07:37:19 +00:00
|
|
|
template<value_t T>
|
2017-04-19 04:37:02 +00:00
|
|
|
typename detail::toml_default_type<T>::type& cast();
|
2017-04-16 06:12:39 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
2017-04-19 04:37:02 +00:00
|
|
|
void switch_clean(value_t t);
|
2017-04-16 07:37:19 +00:00
|
|
|
template<value_t t> struct switch_assign;
|
|
|
|
template<value_t t> struct switch_cast;
|
2017-04-16 06:12:39 +00:00
|
|
|
|
2017-04-19 04:37:02 +00:00
|
|
|
static bool should_be_cleaned(value_t vt)
|
|
|
|
{
|
|
|
|
return (vt == value_t::String) || (vt == value_t::Array) ||
|
|
|
|
(vt == value_t::Table) || (vt == value_t::Datetime);
|
|
|
|
}
|
|
|
|
|
2017-04-16 06:12:39 +00:00
|
|
|
private:
|
|
|
|
|
2017-04-16 07:37:19 +00:00
|
|
|
value_t type_;
|
2017-04-16 06:12:39 +00:00
|
|
|
union
|
|
|
|
{
|
2017-04-19 04:37:02 +00:00
|
|
|
Boolean boolean_;
|
|
|
|
Integer integer_;
|
|
|
|
Float float_;
|
|
|
|
String string_;
|
|
|
|
Datetime datetime_;
|
|
|
|
storage_ptr storage_; //ptr to table or array
|
2017-04-16 06:12:39 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2017-04-16 07:37:19 +00:00
|
|
|
template<> struct value::switch_assign<value_t::Boolean>
|
2017-04-16 06:12:39 +00:00
|
|
|
{
|
|
|
|
template<typename valT>
|
|
|
|
static void invoke(value& v, valT&& val)
|
|
|
|
{
|
2017-04-19 04:37:02 +00:00
|
|
|
v.boolean_ = static_cast<Boolean>(val);
|
2017-04-16 06:12:39 +00:00
|
|
|
}
|
|
|
|
};
|
2017-04-16 07:37:19 +00:00
|
|
|
template<> struct value::switch_assign<value_t::Integer>
|
2017-04-16 06:12:39 +00:00
|
|
|
{
|
|
|
|
template<typename valT>
|
|
|
|
static void invoke(value& v, valT&& val)
|
|
|
|
{
|
2017-04-19 04:37:02 +00:00
|
|
|
v.integer_ = static_cast<Integer>(val);
|
2017-04-16 06:12:39 +00:00
|
|
|
}
|
|
|
|
};
|
2017-04-16 07:37:19 +00:00
|
|
|
template<> struct value::switch_assign<value_t::Float>
|
2017-04-16 06:12:39 +00:00
|
|
|
{
|
|
|
|
template<typename valT>
|
|
|
|
static void invoke(value& v, valT&& val)
|
|
|
|
{
|
2017-04-19 04:37:02 +00:00
|
|
|
v.float_ = static_cast<Float>(val);
|
2017-04-16 06:12:39 +00:00
|
|
|
}
|
|
|
|
};
|
2017-04-16 07:37:19 +00:00
|
|
|
template<> struct value::switch_assign<value_t::String>
|
2017-04-16 06:12:39 +00:00
|
|
|
{
|
|
|
|
template<typename valT>
|
|
|
|
static void invoke(value& v, valT&& val)
|
|
|
|
{
|
|
|
|
new(&v.string_) String(val);
|
|
|
|
}
|
|
|
|
};
|
2017-04-16 07:37:19 +00:00
|
|
|
template<> struct value::switch_assign<value_t::Datetime>
|
2017-04-16 06:12:39 +00:00
|
|
|
{
|
|
|
|
template<typename valT>
|
|
|
|
static void invoke(value& v, valT&& val)
|
|
|
|
{
|
|
|
|
new(&v.datetime_) Datetime(val);
|
|
|
|
}
|
|
|
|
};
|
2017-04-16 07:37:19 +00:00
|
|
|
template<> struct value::switch_assign<value_t::Array>
|
2017-04-16 06:12:39 +00:00
|
|
|
{
|
|
|
|
template<typename valT>
|
|
|
|
static void invoke(value& v, valT&& val)
|
|
|
|
{
|
2017-04-19 04:37:02 +00:00
|
|
|
new(&v.storage_) storage_ptr(
|
|
|
|
toml::make_unique<detail::storage<Array>>(val));
|
2017-04-16 06:12:39 +00:00
|
|
|
}
|
|
|
|
};
|
2017-04-16 07:37:19 +00:00
|
|
|
template<> struct value::switch_assign<value_t::Table>
|
2017-04-16 06:12:39 +00:00
|
|
|
{
|
|
|
|
template<typename valT>
|
|
|
|
static void invoke(value& v, valT&& val)
|
|
|
|
{
|
2017-04-19 04:37:02 +00:00
|
|
|
new(&v.storage_) storage_ptr(
|
|
|
|
toml::make_unique<detail::storage<Table>>(val));
|
2017-04-16 06:12:39 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-04-16 07:37:19 +00:00
|
|
|
template<> struct value::switch_cast<value_t::Boolean>
|
2017-04-16 06:12:39 +00:00
|
|
|
{
|
|
|
|
static Boolean& invoke(value& v) {return v.boolean_;}
|
|
|
|
static Boolean const& invoke(value const& v) {return v.boolean_;}
|
|
|
|
};
|
2017-04-16 07:37:19 +00:00
|
|
|
template<> struct value::switch_cast<value_t::Integer>
|
2017-04-16 06:12:39 +00:00
|
|
|
{
|
|
|
|
static Integer& invoke(value& v) {return v.integer_;}
|
|
|
|
static Integer const& invoke(value const& v) {return v.integer_;}
|
|
|
|
};
|
2017-04-16 07:37:19 +00:00
|
|
|
template<> struct value::switch_cast<value_t::Float>
|
2017-04-16 06:12:39 +00:00
|
|
|
{
|
|
|
|
static Float& invoke(value& v) {return v.float_;}
|
|
|
|
static Float const& invoke(value const& v) {return v.float_;}
|
|
|
|
};
|
2017-04-16 07:37:19 +00:00
|
|
|
template<> struct value::switch_cast<value_t::String>
|
2017-04-16 06:12:39 +00:00
|
|
|
{
|
|
|
|
static String& invoke(value& v) {return v.string_;}
|
|
|
|
static String const& invoke(value const& v) {return v.string_;}
|
|
|
|
};
|
2017-04-16 07:37:19 +00:00
|
|
|
template<> struct value::switch_cast<value_t::Datetime>
|
2017-04-16 06:12:39 +00:00
|
|
|
{
|
|
|
|
static Datetime& invoke(value& v) {return v.datetime_;}
|
|
|
|
static Datetime const& invoke(value const& v) {return v.datetime_;}
|
|
|
|
};
|
2017-04-16 07:37:19 +00:00
|
|
|
template<> struct value::switch_cast<value_t::Array>
|
2017-04-16 06:12:39 +00:00
|
|
|
{
|
2017-04-19 04:37:02 +00:00
|
|
|
// switch_cast assumes tmeplate argument is correct.
|
|
|
|
// if not, the behaviour is undefined.
|
|
|
|
static Array& invoke(value& v)
|
|
|
|
{
|
|
|
|
return static_cast<detail::storage<Array>*>(v.storage_.get())->value;
|
|
|
|
}
|
|
|
|
static Array const& invoke(value const& v)
|
|
|
|
{
|
|
|
|
return static_cast<detail::storage<Array>*>(v.storage_.get())->value;
|
|
|
|
}
|
2017-04-16 06:12:39 +00:00
|
|
|
};
|
2017-04-16 07:37:19 +00:00
|
|
|
template<> struct value::switch_cast<value_t::Table>
|
2017-04-16 06:12:39 +00:00
|
|
|
{
|
2017-04-19 04:37:02 +00:00
|
|
|
static Table& invoke(value& v)
|
|
|
|
{
|
|
|
|
return static_cast<detail::storage<Table>*>(v.storage_.get())->value;
|
|
|
|
}
|
|
|
|
static Table const& invoke(value const& v)
|
|
|
|
{
|
|
|
|
return static_cast<detail::storage<Table>*>(v.storage_.get())->value;
|
|
|
|
}
|
2017-04-16 06:12:39 +00:00
|
|
|
};
|
|
|
|
|
2017-04-19 04:37:02 +00:00
|
|
|
inline void value::switch_clean(value_t t)
|
|
|
|
{
|
|
|
|
switch(t)
|
|
|
|
{
|
|
|
|
case value_t::Boolean : {boolean_.~Boolean(); return;}
|
|
|
|
case value_t::Integer : {integer_.~Integer(); return;}
|
|
|
|
case value_t::Float : {float_.~Float(); return;}
|
|
|
|
case value_t::String : {string_.~String(); return;}
|
|
|
|
case value_t::Datetime : {datetime_.~Datetime(); return;}
|
|
|
|
case value_t::Array : {storage_.~storage_ptr(); return;}
|
|
|
|
case value_t::Table : {storage_.~storage_ptr(); return;}
|
|
|
|
case value_t::Empty : return;
|
|
|
|
case value_t::Unknown : assert(false);
|
|
|
|
default : assert(false);
|
|
|
|
}
|
|
|
|
}
|
2017-04-16 06:12:39 +00:00
|
|
|
|
2017-04-19 04:37:02 +00:00
|
|
|
inline value::~value()
|
|
|
|
{
|
|
|
|
switch_clean(this->type_);
|
|
|
|
}
|
2017-04-16 06:12:39 +00:00
|
|
|
|
2017-04-19 04:37:02 +00:00
|
|
|
inline value::value(const value& v) : type_(v.type())
|
|
|
|
{
|
|
|
|
switch(v.type())
|
|
|
|
{
|
|
|
|
case value_t::Boolean :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Boolean>::invoke(
|
|
|
|
*this, v.cast<value_t::Boolean>());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Integer :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Integer>::invoke(
|
|
|
|
*this, v.cast<value_t::Integer>());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Float :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Float>::invoke(
|
|
|
|
*this, v.cast<value_t::Float>());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::String :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::String>::invoke(
|
|
|
|
*this, v.cast<value_t::String>());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Datetime:
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Datetime>::invoke(
|
|
|
|
*this, v.cast<value_t::Datetime>());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Array :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Array>::invoke(
|
|
|
|
*this, v.cast<value_t::Array>());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Table :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Table>::invoke(
|
|
|
|
*this, v.cast<value_t::Table>());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Empty : break;
|
|
|
|
case value_t::Unknown : assert(false);
|
|
|
|
default: assert(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline value::value(value&& v)
|
|
|
|
{
|
|
|
|
this->type_ = v.type_;
|
|
|
|
switch(this->type_)
|
|
|
|
{
|
|
|
|
case value_t::Boolean :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Boolean>::invoke(*this,
|
|
|
|
std::move(v.cast<value_t::Boolean>()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Integer :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Integer>::invoke(*this,
|
|
|
|
std::move(v.cast<value_t::Integer>()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Float :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Float>::invoke(*this,
|
|
|
|
std::move(v.cast<value_t::Float>()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::String :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::String>::invoke(*this,
|
|
|
|
std::move(v.cast<value_t::String>()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Datetime:
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Datetime>::invoke(*this,
|
|
|
|
std::move(v.cast<value_t::Datetime>()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Array :
|
|
|
|
{
|
|
|
|
new(&this->storage_) storage_ptr(std::move(v.storage_));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Table :
|
|
|
|
{
|
|
|
|
new(&this->storage_) storage_ptr(std::move(v.storage_));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Empty : break;
|
|
|
|
case value_t::Unknown : assert(false);
|
|
|
|
default: assert(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline value& value::operator=(const value& v)
|
|
|
|
{
|
|
|
|
if(should_be_cleaned(this->type_))
|
|
|
|
{
|
|
|
|
this->switch_clean(this->type_);
|
|
|
|
}
|
|
|
|
this->type_ = v.type();
|
|
|
|
|
|
|
|
switch(this->type_)
|
|
|
|
{
|
|
|
|
case value_t::Boolean :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Boolean>::invoke(*this,
|
|
|
|
v.cast<value_t::Boolean>());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Integer :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Integer>::invoke(*this,
|
|
|
|
v.cast<value_t::Integer>());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Float :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Float>::invoke(*this,
|
|
|
|
v.cast<value_t::Float>());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::String :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::String>::invoke(*this,
|
|
|
|
v.cast<value_t::String>());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Datetime:
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Datetime>::invoke(*this,
|
|
|
|
v.cast<value_t::Datetime>());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Array :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Array>::invoke(*this,
|
|
|
|
v.cast<value_t::Array>());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Table :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Table>::invoke(*this,
|
|
|
|
v.cast<value_t::Table>());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Empty : break;
|
|
|
|
case value_t::Unknown : assert(false);
|
|
|
|
default: assert(false);
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline value& value::operator=(value&& v)
|
|
|
|
{
|
|
|
|
if(should_be_cleaned(this->type_))
|
|
|
|
{
|
|
|
|
this->switch_clean(this->type_);
|
|
|
|
}
|
|
|
|
this->type_ = v.type_;
|
|
|
|
|
|
|
|
switch(this->type_)
|
|
|
|
{
|
|
|
|
case value_t::Boolean :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Boolean>::invoke(*this,
|
|
|
|
std::move(v.cast<value_t::Boolean>()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Integer :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Integer>::invoke(*this,
|
|
|
|
std::move(v.cast<value_t::Integer>()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Float :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Float>::invoke(*this,
|
|
|
|
std::move(v.cast<value_t::Float>()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::String :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::String>::invoke(*this,
|
|
|
|
std::move(v.cast<value_t::String>()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Datetime:
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Datetime>::invoke(*this,
|
|
|
|
std::move(v.cast<value_t::Datetime>()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Array :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Array>::invoke(*this,
|
|
|
|
std::move(v.cast<value_t::Array>()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Table :
|
|
|
|
{
|
|
|
|
switch_assign<value_t::Table>::invoke(*this,
|
|
|
|
std::move(v.cast<value_t::Table>()));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case value_t::Empty : break;
|
|
|
|
case value_t::Unknown : assert(false);
|
|
|
|
default: assert(false);
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T, typename std::enable_if<
|
|
|
|
value_traits<T>::is_toml_type, std::nullptr_t>::type>
|
|
|
|
value::value(T&& v) : type_(toml::detail::check_type<T>())
|
|
|
|
{
|
2018-05-05 03:06:06 +00:00
|
|
|
constexpr value_t kind = toml::detail::check_type<T>();
|
|
|
|
switch_assign<kind>::invoke(*this, std::forward<T>(v));
|
2017-04-19 04:37:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T, typename std::enable_if<
|
|
|
|
value_traits<T>::is_toml_type, std::nullptr_t>::type>
|
|
|
|
value& value::operator=(T&& v)
|
|
|
|
{
|
2018-05-05 03:06:06 +00:00
|
|
|
constexpr value_t kind = toml::detail::check_type<T>();
|
2017-04-19 04:37:02 +00:00
|
|
|
if(should_be_cleaned(this->type_))
|
|
|
|
{
|
|
|
|
switch_clean(this->type_);
|
|
|
|
}
|
2018-05-05 03:06:06 +00:00
|
|
|
this->type_ = kind;
|
|
|
|
switch_assign<kind>::invoke(*this, std::forward<T>(v));
|
2017-04-19 04:37:02 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2017-04-20 01:44:11 +00:00
|
|
|
template<typename T, typename std::enable_if<
|
|
|
|
value_traits<T>::is_toml_type, std::nullptr_t>::type>
|
|
|
|
value::value(std::initializer_list<T> init)
|
|
|
|
: type_(toml::value_t::Array)
|
|
|
|
{
|
|
|
|
toml::Array arr; arr.reserve(init.size());
|
|
|
|
for(auto&& item : init)
|
|
|
|
arr.emplace_back(std::move(item));
|
|
|
|
switch_assign<toml::value_t::Array>::invoke(*this, std::move(arr));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline value::value(
|
|
|
|
std::initializer_list<std::pair<toml::key, toml::value>> init)
|
|
|
|
: type_(toml::value_t::Table)
|
|
|
|
{
|
|
|
|
toml::Table tmp;
|
|
|
|
for(auto&& item : init)
|
|
|
|
tmp.emplace(std::move(item.first), std::move(item.second));
|
|
|
|
switch_assign<toml::value_t::Table>::invoke(*this, std::move(tmp));
|
|
|
|
}
|
|
|
|
|
2017-04-19 04:37:02 +00:00
|
|
|
template<value_t T>
|
|
|
|
inline typename detail::toml_default_type<T>::type const&
|
|
|
|
value::cast() const
|
|
|
|
{
|
|
|
|
if(T != this->type_)
|
2017-04-20 03:49:36 +00:00
|
|
|
throw type_error("current type: " + stringize(this->type_) +
|
|
|
|
std::string(" is not query type: ") + stringize(T));
|
2017-04-19 04:37:02 +00:00
|
|
|
return switch_cast<T>::invoke(*this);
|
|
|
|
}
|
|
|
|
template<value_t T>
|
|
|
|
inline typename detail::toml_default_type<T>::type&
|
|
|
|
value::cast()
|
|
|
|
{
|
|
|
|
if(T != this->type_)
|
2017-04-20 03:49:36 +00:00
|
|
|
throw type_error("current type: " + stringize(this->type_) +
|
|
|
|
std::string(" is not query type: ") + stringize(T));
|
2017-04-19 04:37:02 +00:00
|
|
|
return switch_cast<T>::invoke(*this);
|
|
|
|
}
|
2017-04-19 04:37:39 +00:00
|
|
|
|
2017-04-20 05:22:22 +00:00
|
|
|
inline bool operator==(const toml::value& lhs, const toml::value& rhs)
|
|
|
|
{
|
|
|
|
if(lhs.type() != rhs.type()) return false;
|
|
|
|
switch(lhs.type())
|
|
|
|
{
|
|
|
|
case value_t::Boolean :
|
|
|
|
return lhs.cast<value_t::Boolean >() == rhs.cast<value_t::Boolean >();
|
|
|
|
case value_t::Integer :
|
|
|
|
return lhs.cast<value_t::Integer >() == rhs.cast<value_t::Integer >();
|
|
|
|
case value_t::Float :
|
|
|
|
return lhs.cast<value_t::Float >() == rhs.cast<value_t::Float >();
|
|
|
|
case value_t::String :
|
|
|
|
return lhs.cast<value_t::String >() == rhs.cast<value_t::String >();
|
|
|
|
case value_t::Datetime:
|
|
|
|
return lhs.cast<value_t::Datetime>() == rhs.cast<value_t::Datetime>();
|
|
|
|
case value_t::Array :
|
|
|
|
return lhs.cast<value_t::Array >() == rhs.cast<value_t::Array >();
|
|
|
|
case value_t::Table :
|
|
|
|
return lhs.cast<value_t::Table >() == rhs.cast<value_t::Table >();
|
|
|
|
case value_t::Empty : return true;
|
|
|
|
case value_t::Unknown : return false;
|
2017-04-20 05:37:51 +00:00
|
|
|
default: return false;
|
2017-04-20 05:22:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
inline bool operator<(const toml::value& lhs, const toml::value& rhs)
|
|
|
|
{
|
|
|
|
if(lhs.type() != rhs.type()) return (lhs.type() < rhs.type());
|
|
|
|
switch(lhs.type())
|
|
|
|
{
|
|
|
|
case value_t::Boolean :
|
|
|
|
return lhs.cast<value_t::Boolean >() < rhs.cast<value_t::Boolean >();
|
|
|
|
case value_t::Integer :
|
|
|
|
return lhs.cast<value_t::Integer >() < rhs.cast<value_t::Integer >();
|
|
|
|
case value_t::Float :
|
|
|
|
return lhs.cast<value_t::Float >() < rhs.cast<value_t::Float >();
|
|
|
|
case value_t::String :
|
|
|
|
return lhs.cast<value_t::String >() < rhs.cast<value_t::String >();
|
|
|
|
case value_t::Datetime:
|
|
|
|
return lhs.cast<value_t::Datetime>() < rhs.cast<value_t::Datetime>();
|
|
|
|
case value_t::Array :
|
|
|
|
return lhs.cast<value_t::Array >() < rhs.cast<value_t::Array >();
|
|
|
|
case value_t::Table :
|
|
|
|
return lhs.cast<value_t::Table >() < rhs.cast<value_t::Table >();
|
|
|
|
case value_t::Empty : return false;
|
|
|
|
case value_t::Unknown : return false;
|
2017-04-20 05:37:51 +00:00
|
|
|
default: return false;
|
2017-04-20 05:22:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator!=(const toml::value& lhs, const toml::value& rhs)
|
|
|
|
{
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|
|
|
|
inline bool operator<=(const toml::value& lhs, const toml::value& rhs)
|
|
|
|
{
|
|
|
|
return (lhs < rhs) || (lhs == rhs);
|
|
|
|
}
|
|
|
|
inline bool operator>(const toml::value& lhs, const toml::value& rhs)
|
|
|
|
{
|
|
|
|
return !(lhs <= rhs);
|
|
|
|
}
|
|
|
|
inline bool operator>=(const toml::value& lhs, const toml::value& rhs)
|
|
|
|
{
|
|
|
|
return !(lhs < rhs);
|
|
|
|
}
|
|
|
|
|
2017-04-16 06:12:39 +00:00
|
|
|
}// toml
|
2017-04-21 04:14:53 +00:00
|
|
|
#endif// TOML11_VALUE
|