mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-12-16 03:08:52 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1a55b1331 | ||
|
|
170b0d6b3f | ||
|
|
433636a06f | ||
|
|
9555817901 | ||
|
|
e54deacf1a | ||
|
|
b6f53cae7a | ||
|
|
f953a9cf23 | ||
|
|
117549bf70 | ||
|
|
4287160254 |
@@ -4,6 +4,7 @@ toml11
|
|||||||
[](https://travis-ci.org/ToruNiina/toml11)
|
[](https://travis-ci.org/ToruNiina/toml11)
|
||||||
[](https://ci.appveyor.com/project/ToruNiina/toml11)
|
[](https://ci.appveyor.com/project/ToruNiina/toml11)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
|
[](https://doi.org/10.5281/zenodo.1209136)
|
||||||
|
|
||||||
c++11 header-only toml parser depending only on c++11 standard library.
|
c++11 header-only toml parser depending only on c++11 standard library.
|
||||||
|
|
||||||
|
|||||||
@@ -170,3 +170,22 @@ BOOST_AUTO_TEST_CASE(test_from_toml_tie)
|
|||||||
BOOST_CHECK_EQUAL(ut["val4"].cast<toml::value_t::String >(), "piyo");
|
BOOST_CHECK_EQUAL(ut["val4"].cast<toml::value_t::String >(), "piyo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_from_toml_tuple)
|
||||||
|
{
|
||||||
|
toml::Array a;
|
||||||
|
a.emplace_back(2);
|
||||||
|
a.emplace_back(7);
|
||||||
|
a.emplace_back(1);
|
||||||
|
a.emplace_back(8);
|
||||||
|
a.emplace_back(2);
|
||||||
|
toml::value v(a);
|
||||||
|
|
||||||
|
std::tuple<int, int, int, int, int> t;
|
||||||
|
toml::from_toml(t, v);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(std::get<0>(t), 2);
|
||||||
|
BOOST_CHECK_EQUAL(std::get<1>(t), 7);
|
||||||
|
BOOST_CHECK_EQUAL(std::get<2>(t), 1);
|
||||||
|
BOOST_CHECK_EQUAL(std::get<3>(t), 8);
|
||||||
|
BOOST_CHECK_EQUAL(std::get<4>(t), 2);
|
||||||
|
}
|
||||||
|
|||||||
@@ -74,16 +74,11 @@ BOOST_AUTO_TEST_CASE(test_is_xxx)
|
|||||||
BOOST_CHECK(toml::detail::is_container<std_array_type>::value);
|
BOOST_CHECK(toml::detail::is_container<std_array_type>::value);
|
||||||
BOOST_CHECK(toml::detail::is_container<std::set<dummy_type>>::value);
|
BOOST_CHECK(toml::detail::is_container<std::set<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::is_container<std::unordered_set<std::string>>::value);
|
BOOST_CHECK(toml::detail::is_container<std::unordered_set<std::string>>::value);
|
||||||
BOOST_CHECK(toml::detail::is_container<std_map_type>::value);
|
|
||||||
BOOST_CHECK(toml::detail::is_container<std_unordered_map_type>::value);
|
|
||||||
BOOST_CHECK(toml::detail::is_container<dummy_container<dummy_type>>::value);
|
BOOST_CHECK(toml::detail::is_container<dummy_container<dummy_type>>::value);
|
||||||
|
|
||||||
|
BOOST_CHECK(!toml::detail::is_container<std_map_type>::value);
|
||||||
|
BOOST_CHECK(!toml::detail::is_container<std_unordered_map_type>::value);
|
||||||
|
|
||||||
BOOST_CHECK(toml::detail::is_map<std_map_type>::value);
|
BOOST_CHECK(toml::detail::is_map<std_map_type>::value);
|
||||||
BOOST_CHECK(toml::detail::is_map<std_unordered_map_type>::value);
|
BOOST_CHECK(toml::detail::is_map<std_unordered_map_type>::value);
|
||||||
|
|
||||||
BOOST_CHECK(toml::detail::is_key_convertible<std_map_type>::value);
|
|
||||||
BOOST_CHECK(toml::detail::is_key_convertible<std_unordered_map_type>::value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,66 +1,14 @@
|
|||||||
#ifndef TOML11_FROM_TOML
|
#ifndef TOML11_FROM_TOML
|
||||||
#define TOML11_FROM_TOML
|
#define TOML11_FROM_TOML
|
||||||
#include "value.hpp"
|
#include "get.hpp"
|
||||||
|
|
||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename T, toml::value_t vT = toml::detail::check_type<T>(),
|
template<typename T>
|
||||||
typename std::enable_if<(vT != toml::value_t::Unknown &&
|
|
||||||
vT != value_t::Empty), std::nullptr_t>::type = nullptr>
|
|
||||||
void from_toml(T& x, const toml::value& v)
|
void from_toml(T& x, const toml::value& v)
|
||||||
{
|
{
|
||||||
if(v.type() != vT)
|
x = toml::get<T>(v);
|
||||||
throw type_error("from_toml: value type: " + stringize(v.type()) +
|
|
||||||
std::string(" is not arguemnt type: ") + stringize(vT));
|
|
||||||
x = v.cast<vT>();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, toml::value_t vT = toml::detail::check_type<T>(),
|
|
||||||
typename std::enable_if<(vT == toml::value_t::Unknown) &&
|
|
||||||
(!toml::detail::is_map<T>::value) &&
|
|
||||||
toml::detail::is_container<T>::value, std::nullptr_t>::type = nullptr>
|
|
||||||
void from_toml(T& x, const toml::value& v)
|
|
||||||
{
|
|
||||||
// TODO the case of x is not dynamic container case
|
|
||||||
if(v.type() != value_t::Array)
|
|
||||||
throw type_error("from_toml: value type: " + stringize(v.type()) +
|
|
||||||
std::string(" is not argument type: Array"));
|
|
||||||
const auto& ar = v.cast<value_t::Array>();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
toml::resize(x, ar.size());
|
|
||||||
}
|
|
||||||
catch(std::invalid_argument& iv)
|
|
||||||
{
|
|
||||||
throw toml::type_error("toml::from_toml: static array size is not enough");
|
|
||||||
}
|
|
||||||
auto iter = x.begin();
|
|
||||||
for(const auto& val : ar)
|
|
||||||
{
|
|
||||||
typename T::value_type v;
|
|
||||||
from_toml(v, val);
|
|
||||||
*iter = std::move(v);
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, toml::value_t vT = toml::detail::check_type<T>(),
|
|
||||||
typename std::enable_if<(vT == toml::value_t::Unknown) &&
|
|
||||||
toml::detail::is_map<T>::value, std::nullptr_t>::type = nullptr>
|
|
||||||
void from_toml(T& x, const toml::value& v)
|
|
||||||
{
|
|
||||||
if(v.type() != value_t::Table)
|
|
||||||
throw type_error("from_toml: value type: " + stringize(v.type()) +
|
|
||||||
std::string(" is not argument type: Table"));
|
|
||||||
x.clear();
|
|
||||||
const auto& tb = v.cast<value_t::Table>();
|
|
||||||
for(const auto& kv : tb)
|
|
||||||
{
|
|
||||||
x.insert(kv);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
114
toml/get.hpp
114
toml/get.hpp
@@ -6,55 +6,121 @@
|
|||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename T, toml::value_t vT = toml::detail::check_type<T>(),
|
template<typename T, typename std::enable_if<
|
||||||
typename std::enable_if<(vT != toml::value_t::Unknown &&
|
detail::is_exact_toml_type<T>::value, std::nullptr_t>::type = nullptr>
|
||||||
vT != value_t::Empty), std::nullptr_t>::type = nullptr>
|
inline T& get(value& v)
|
||||||
inline T get(const toml::value& v)
|
|
||||||
{
|
{
|
||||||
return static_cast<T>(v.cast<vT>());
|
constexpr value_t kind = detail::check_type<T>();
|
||||||
|
return v.cast<kind>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
detail::is_exact_toml_type<T>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
inline T const& get(const value& v)
|
||||||
|
{
|
||||||
|
constexpr value_t kind = detail::check_type<T>();
|
||||||
|
return v.cast<kind>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if<detail::conjunction<
|
||||||
|
detail::negation<detail::is_exact_toml_type<T>>,
|
||||||
|
detail::negation<std::is_same<T, bool>>, std::is_integral<T>
|
||||||
|
>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
inline T get(const value& v)
|
||||||
|
{
|
||||||
|
return static_cast<T>(v.cast<value_t::Integer>());
|
||||||
|
}
|
||||||
|
template<typename T, typename std::enable_if<detail::conjunction<
|
||||||
|
detail::negation<detail::is_exact_toml_type<T>>, std::is_floating_point<T>
|
||||||
|
>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
inline T get(const value& v)
|
||||||
|
{
|
||||||
|
return static_cast<T>(v.cast<value_t::Float>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// array-like type
|
// array-like type
|
||||||
template<typename T, toml::value_t vT = toml::detail::check_type<T>(),
|
template<typename T, typename std::enable_if<detail::conjunction<
|
||||||
typename std::enable_if<(vT == toml::value_t::Unknown) &&
|
detail::negation<detail::is_exact_toml_type<T>>, detail::is_container<T>
|
||||||
(!toml::detail::is_map<T>::value) &&
|
>::value, std::nullptr_t>::type = nullptr>
|
||||||
toml::detail::is_container<T>::value, std::nullptr_t>::type = nullptr>
|
T get(const value& v)
|
||||||
T get(const toml::value& v)
|
|
||||||
{
|
{
|
||||||
if(v.type() != value_t::Array)
|
|
||||||
throw type_error("get: value type: " + stringize(v.type()) +
|
|
||||||
std::string(" is not argument type: Array"));
|
|
||||||
|
|
||||||
const auto& ar = v.cast<value_t::Array>();
|
const auto& ar = v.cast<value_t::Array>();
|
||||||
T tmp;
|
T tmp;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
toml::resize(tmp, ar.size());
|
::toml::resize(tmp, ar.size());
|
||||||
}
|
}
|
||||||
catch(std::invalid_argument& iv)
|
catch(std::invalid_argument& iv)
|
||||||
{
|
{
|
||||||
throw toml::type_error("toml::get: static array size is not enough");
|
throw type_error("toml::get: static array: size is not enough");
|
||||||
}
|
}
|
||||||
std::transform(ar.cbegin(), ar.cend(), tmp.begin(),
|
std::transform(ar.cbegin(), ar.cend(), tmp.begin(),
|
||||||
[](toml::value const& elem){return get<typename T::value_type>(elem);});
|
[](value const& elem){return get<typename T::value_type>(elem);});
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// table-like case
|
// table-like case
|
||||||
template<typename T, toml::value_t vT = toml::detail::check_type<T>(),
|
template<typename T, typename std::enable_if<detail::conjunction<
|
||||||
typename std::enable_if<(vT == toml::value_t::Unknown) &&
|
detail::negation<detail::is_exact_toml_type<T>>, detail::is_map<T>
|
||||||
toml::detail::is_map<T>::value, std::nullptr_t>::type = nullptr>
|
>::value, std::nullptr_t>::type = nullptr>
|
||||||
T get(const toml::value& v)
|
T get(const toml::value& v)
|
||||||
{
|
{
|
||||||
if(v.type() != value_t::Table)
|
|
||||||
throw type_error("get: value type: " + stringize(v.type()) +
|
|
||||||
std::string(" is not argument type: Table"));
|
|
||||||
T tmp;
|
|
||||||
const auto& tb = v.cast<value_t::Table>();
|
const auto& tb = v.cast<value_t::Table>();
|
||||||
|
T tmp;
|
||||||
for(const auto& kv : tb){tmp.insert(kv);}
|
for(const auto& kv : tb){tmp.insert(kv);}
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// array -> pair
|
||||||
|
template<typename T, typename std::enable_if<detail::is_std_pair<T>::value,
|
||||||
|
std::nullptr_t>::type = nullptr>
|
||||||
|
T get(const value& v)
|
||||||
|
{
|
||||||
|
using first_type = typename T::first_type;
|
||||||
|
using second_type = typename T::second_type;
|
||||||
|
const auto& ar = v.cast<value_t::Array>();
|
||||||
|
if(ar.size() != 2)
|
||||||
|
{
|
||||||
|
throw std::out_of_range(
|
||||||
|
"toml::get<std::pair>: value does not have 2 elements.");
|
||||||
|
}
|
||||||
|
|
||||||
|
T tmp;
|
||||||
|
tmp.first = get<first_type >(ar.at(0));
|
||||||
|
tmp.second = get<second_type>(ar.at(1));
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename T, std::size_t ...I>
|
||||||
|
T get_tuple_impl(const toml::Array& a, index_sequence<I...>)
|
||||||
|
{
|
||||||
|
return std::make_tuple(
|
||||||
|
::toml::get<typename std::tuple_element<I, T>::type>(a.at(I))...);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // detail
|
||||||
|
|
||||||
|
// array -> tuple
|
||||||
|
template<typename T, typename std::enable_if<detail::is_std_tuple<T>::value,
|
||||||
|
std::nullptr_t>::type = nullptr>
|
||||||
|
T get(const value& v)
|
||||||
|
{
|
||||||
|
const auto& ar = v.cast<value_t::Array>();
|
||||||
|
if(ar.size() != std::tuple_size<T>::value)
|
||||||
|
{
|
||||||
|
throw std::out_of_range(
|
||||||
|
"toml::get<std::tuple>: array value does not have " +
|
||||||
|
std::to_string(std::tuple_size<T>::value) +
|
||||||
|
std::string(" elements (array has ") + std::to_string(ar.size()) +
|
||||||
|
std::string(" elements)."));
|
||||||
|
}
|
||||||
|
return detail::get_tuple_impl<T>(ar,
|
||||||
|
detail::make_index_sequence<std::tuple_size<T>::value>{});
|
||||||
|
}
|
||||||
|
|
||||||
// get_or -----------------------------------------------------------------
|
// get_or -----------------------------------------------------------------
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|||||||
@@ -5,47 +5,76 @@
|
|||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename T, toml::value_t vT = toml::detail::check_type<T>(),
|
template<typename T, typename std::enable_if<
|
||||||
typename std::enable_if<(vT != toml::value_t::Unknown &&
|
detail::is_exact_toml_type<T>::value, std::nullptr_t>::type = nullptr>
|
||||||
vT != value_t::Empty), std::nullptr_t>::type = nullptr>
|
inline value to_toml(const T& x)
|
||||||
inline toml::value to_toml(T&& x)
|
|
||||||
{
|
{
|
||||||
return toml::value(std::forward<T>(x));
|
return value(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, toml::value_t vT = toml::detail::check_type<T>(),
|
template<typename T, typename std::enable_if<detail::conjunction<
|
||||||
typename std::enable_if<(vT == toml::value_t::Unknown) &&
|
detail::negation<detail::is_exact_toml_type<T>>, std::is_integral<T>
|
||||||
(!toml::detail::is_map<T>::value) &&
|
>::value, std::nullptr_t>::type = nullptr>
|
||||||
toml::detail::is_container<T>::value, std::nullptr_t>::type = nullptr>
|
inline value to_toml(const T& x)
|
||||||
toml::value to_toml(T&& x)
|
|
||||||
{
|
{
|
||||||
toml::Array tmp; tmp.reserve(std::distance(std::begin(x), std::end(x)));
|
return value(::toml::Integer(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if<detail::conjunction<
|
||||||
|
detail::negation<detail::is_exact_toml_type<T>>, std::is_floating_point<T>
|
||||||
|
>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
inline value to_toml(const T& x)
|
||||||
|
{
|
||||||
|
return value(::toml::Float(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline value to_toml(const char* str)
|
||||||
|
{
|
||||||
|
return value(::toml::String(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if<detail::conjunction<
|
||||||
|
detail::negation<detail::is_exact_toml_type<T>>, detail::is_container<T>
|
||||||
|
>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
value to_toml(const T& x)
|
||||||
|
{
|
||||||
|
Array tmp;
|
||||||
|
tmp.reserve(std::distance(std::begin(x), std::end(x)));
|
||||||
for(auto iter = std::begin(x); iter != std::end(x); ++iter)
|
for(auto iter = std::begin(x); iter != std::end(x); ++iter)
|
||||||
|
{
|
||||||
tmp.emplace_back(*iter);
|
tmp.emplace_back(*iter);
|
||||||
return toml::value(std::move(tmp));
|
}
|
||||||
|
return value(std::move(tmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, toml::value_t vT = toml::detail::check_type<T>(),
|
template<typename T, typename std::enable_if<detail::conjunction<
|
||||||
typename std::enable_if<(vT == toml::value_t::Unknown) &&
|
detail::negation<detail::is_exact_toml_type<T>>, detail::is_map<T>
|
||||||
toml::detail::is_map<T>::value, std::nullptr_t>::type = nullptr>
|
>::value, std::nullptr_t>::type = nullptr>
|
||||||
toml::value to_toml(T&& x)
|
value to_toml(const T& x)
|
||||||
{
|
{
|
||||||
toml::Table tmp;
|
Table tmp;
|
||||||
for(auto iter = std::begin(x); iter != std::end(x); ++iter)
|
for(auto iter = std::begin(x); iter != std::end(x); ++iter)
|
||||||
|
{
|
||||||
tmp.emplace(iter->first, to_toml(iter->second));
|
tmp.emplace(iter->first, to_toml(iter->second));
|
||||||
return toml::value(std::move(tmp));
|
}
|
||||||
|
return value(std::move(tmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline toml::value to_toml(std::initializer_list<T> init)
|
inline value to_toml(std::initializer_list<T> init)
|
||||||
{
|
{
|
||||||
return toml::value(std::move(init));
|
return value(std::move(init));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline toml::value
|
inline value to_toml(std::initializer_list<std::pair<std::string, value>> init)
|
||||||
to_toml(std::initializer_list<std::pair<std::string, toml::value>> init)
|
|
||||||
{
|
{
|
||||||
return toml::value(std::move(init));
|
return value(std::move(init));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline value to_toml(const value& x)
|
||||||
|
{
|
||||||
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // toml
|
} // toml
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#ifndef TOML11_TRAITS
|
#ifndef TOML11_TRAITS
|
||||||
#define TOML11_TRAITS
|
#define TOML11_TRAITS
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
@@ -58,14 +60,54 @@ struct has_resize_method : decltype(has_resize_method_impl::check<T>(nullptr)){}
|
|||||||
#undef decltype(...)
|
#undef decltype(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T>
|
template<typename ...> struct conjunction : std::true_type{};
|
||||||
struct is_container : std::integral_constant<bool,
|
template<typename T> struct conjunction<T> : T{};
|
||||||
has_iterator<T>::value && has_value_type<T>::value>{};
|
template<typename T, typename ... Ts>
|
||||||
|
struct conjunction<T, Ts...> :
|
||||||
|
std::conditional<static_cast<bool>(T::value), conjunction<Ts...>, T>::type
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<typename ...> struct disjunction : std::false_type{};
|
||||||
|
template<typename T> struct disjunction<T> : T {};
|
||||||
|
template<typename T, typename ... Ts>
|
||||||
|
struct disjunction<T, Ts...> :
|
||||||
|
std::conditional<static_cast<bool>(T::value), T, disjunction<Ts...>>::type
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_map : std::integral_constant<bool,
|
struct negation : std::integral_constant<bool, !static_cast<bool>(T::value)>{};
|
||||||
has_iterator<T>::value && has_key_type<T>::value &&
|
|
||||||
has_mapped_type<T>::value>{};
|
template<typename T> struct is_std_pair : std::false_type{};
|
||||||
|
template<typename T1, typename T2>
|
||||||
|
struct is_std_pair<std::pair<T1, T2>> : std::true_type{};
|
||||||
|
|
||||||
|
template<typename T> struct is_std_tuple : std::false_type{};
|
||||||
|
template<typename ... Ts>
|
||||||
|
struct is_std_tuple<std::tuple<Ts...>> : std::true_type{};
|
||||||
|
|
||||||
|
// to use toml::get<std::tuple<T1, T2, ...>> in C++11
|
||||||
|
template<std::size_t ... Ns> struct index_sequence{};
|
||||||
|
|
||||||
|
template<typename IS, std::size_t N> struct push_back_index_sequence{};
|
||||||
|
template<std::size_t N, std::size_t ... Ns>
|
||||||
|
struct push_back_index_sequence<index_sequence<Ns...>, N>
|
||||||
|
{
|
||||||
|
typedef index_sequence<Ns..., N> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<std::size_t N>
|
||||||
|
struct index_sequence_maker
|
||||||
|
{
|
||||||
|
typedef typename push_back_index_sequence<
|
||||||
|
typename index_sequence_maker<N-1>::type, N>::type type;
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct index_sequence_maker<0>
|
||||||
|
{
|
||||||
|
typedef index_sequence<0> type;
|
||||||
|
};
|
||||||
|
template<std::size_t N>
|
||||||
|
using make_index_sequence = typename index_sequence_maker<N-1>::type;
|
||||||
|
|
||||||
}// detail
|
}// detail
|
||||||
}//toml
|
}//toml
|
||||||
|
|||||||
@@ -99,33 +99,6 @@ constexpr inline bool is_valid(value_t vt)
|
|||||||
return vt != value_t::Unknown;
|
return vt != value_t::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> struct is_toml_array : std::false_type{};
|
|
||||||
template<> struct is_toml_array<toml::Array> : std::true_type {};
|
|
||||||
template<typename T> struct is_toml_table : std::false_type{};
|
|
||||||
template<> struct is_toml_table<toml::Table> : std::true_type {};
|
|
||||||
|
|
||||||
struct is_key_convertible_impl
|
|
||||||
{
|
|
||||||
template<typename T>
|
|
||||||
static std::is_convertible<typename T::key_type, toml::key>
|
|
||||||
check(typename T::key_type*);
|
|
||||||
|
|
||||||
template<typename T> static std::false_type check(...);
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Intel C++ compiler can not use decltype in parent class declaration, here
|
|
||||||
/// is a hack to work around it. https://stackoverflow.com/a/23953090/4692076
|
|
||||||
#ifdef __INTEL_COMPILER
|
|
||||||
#define decltype(...) std::enable_if<true, decltype(__VA_ARGS__)>::type
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct is_key_convertible : decltype(is_key_convertible_impl::check<T>(nullptr)){};
|
|
||||||
|
|
||||||
#ifdef __INTEL_COMPILER
|
|
||||||
#undef decltype(...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<value_t t> struct toml_default_type{};
|
template<value_t t> struct toml_default_type{};
|
||||||
template<> struct toml_default_type<value_t::Boolean >{typedef Boolean type;};
|
template<> struct toml_default_type<value_t::Boolean >{typedef Boolean type;};
|
||||||
template<> struct toml_default_type<value_t::Integer >{typedef Integer type;};
|
template<> struct toml_default_type<value_t::Integer >{typedef Integer type;};
|
||||||
@@ -137,6 +110,33 @@ template<> struct toml_default_type<value_t::Table >{typedef Table type;};
|
|||||||
template<> struct toml_default_type<value_t::Empty >{typedef void type;};
|
template<> struct toml_default_type<value_t::Empty >{typedef void type;};
|
||||||
template<> struct toml_default_type<value_t::Unknown >{typedef void type;};
|
template<> struct toml_default_type<value_t::Unknown >{typedef void type;};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_exact_toml_type : disjunction<
|
||||||
|
std::is_same<T, Boolean >,
|
||||||
|
std::is_same<T, Integer >,
|
||||||
|
std::is_same<T, Float >,
|
||||||
|
std::is_same<T, String >,
|
||||||
|
std::is_same<T, Datetime>,
|
||||||
|
std::is_same<T, Array >,
|
||||||
|
std::is_same<T, Table >
|
||||||
|
>{};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_map : conjunction<
|
||||||
|
has_iterator<T>,
|
||||||
|
has_value_type<T>,
|
||||||
|
has_key_type<T>,
|
||||||
|
has_mapped_type<T>
|
||||||
|
>{};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_container : conjunction<
|
||||||
|
negation<is_map<T>>,
|
||||||
|
negation<std::is_same<T, String>>,
|
||||||
|
has_iterator<T>,
|
||||||
|
has_value_type<T>
|
||||||
|
>{};
|
||||||
|
|
||||||
struct storage_base
|
struct storage_base
|
||||||
{
|
{
|
||||||
storage_base(): type(toml::value_t::Empty){}
|
storage_base(): type(toml::value_t::Empty){}
|
||||||
@@ -148,7 +148,8 @@ struct storage_base
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct storage : public storage_base
|
struct storage : public storage_base
|
||||||
{
|
{
|
||||||
static_assert(is_toml_array<T>::value || is_toml_table<T>::value,
|
static_assert(std::is_same<T, toml::Array>::value ||
|
||||||
|
std::is_same<T, toml::Table>::value,
|
||||||
"toml::detail::storage is for toml::Array or toml::Table!");
|
"toml::detail::storage is for toml::Array or toml::Table!");
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
|
|
||||||
@@ -591,21 +592,21 @@ template<typename T, typename std::enable_if<
|
|||||||
value_traits<T>::is_toml_type, std::nullptr_t>::type>
|
value_traits<T>::is_toml_type, std::nullptr_t>::type>
|
||||||
value::value(T&& v) : type_(toml::detail::check_type<T>())
|
value::value(T&& v) : type_(toml::detail::check_type<T>())
|
||||||
{
|
{
|
||||||
switch_assign<toml::detail::check_type<T>()>::invoke(
|
constexpr value_t kind = toml::detail::check_type<T>();
|
||||||
*this, std::forward<T>(v));
|
switch_assign<kind>::invoke(*this, std::forward<T>(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename std::enable_if<
|
template<typename T, typename std::enable_if<
|
||||||
value_traits<T>::is_toml_type, std::nullptr_t>::type>
|
value_traits<T>::is_toml_type, std::nullptr_t>::type>
|
||||||
value& value::operator=(T&& v)
|
value& value::operator=(T&& v)
|
||||||
{
|
{
|
||||||
|
constexpr value_t kind = toml::detail::check_type<T>();
|
||||||
if(should_be_cleaned(this->type_))
|
if(should_be_cleaned(this->type_))
|
||||||
{
|
{
|
||||||
switch_clean(this->type_);
|
switch_clean(this->type_);
|
||||||
}
|
}
|
||||||
this->type_ = toml::detail::check_type<T>();
|
this->type_ = kind;
|
||||||
switch_assign<toml::detail::check_type<T>()>::invoke(
|
switch_assign<kind>::invoke(*this, std::forward<T>(v));
|
||||||
*this, std::forward<T>(v));
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user