mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-12-16 03:08:52 +08:00
Merge pull request #38 from ToruNiina/get-any-type
extended conversions
This commit is contained in:
20
toml/from.hpp
Normal file
20
toml/from.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright Toru Niina 2019.
|
||||
// Distributed under the MIT License.
|
||||
#ifndef TOML11_FROM_HPP
|
||||
#define TOML11_FROM_HPP
|
||||
#include "traits.hpp"
|
||||
|
||||
namespace toml
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
struct from;
|
||||
// {
|
||||
// static T from_toml(const toml::value& v)
|
||||
// {
|
||||
// // User-defined conversions ...
|
||||
// }
|
||||
// };
|
||||
|
||||
} // toml
|
||||
#endif // TOML11_FROM_HPP
|
||||
38
toml/get.hpp
38
toml/get.hpp
@@ -2,6 +2,7 @@
|
||||
// Distributed under the MIT License.
|
||||
#ifndef TOML11_GET_HPP
|
||||
#define TOML11_GET_HPP
|
||||
#include "from.hpp"
|
||||
#include "result.hpp"
|
||||
#include "value.hpp"
|
||||
#include <algorithm>
|
||||
@@ -173,6 +174,20 @@ template<typename T, typename std::enable_if<detail::conjunction<
|
||||
>::value, std::nullptr_t>::type = nullptr>
|
||||
T get(const toml::value& v);
|
||||
|
||||
template<typename T, typename std::enable_if<detail::conjunction<
|
||||
detail::negation<detail::is_exact_toml_type<T>>, // not a toml::value
|
||||
detail::has_from_toml_method<T>, // but has from_toml(toml::value) memfn
|
||||
std::is_default_constructible<T> // and default constructible
|
||||
>::value, std::nullptr_t>::type = nullptr>
|
||||
T get(const toml::value& v);
|
||||
|
||||
template<typename T, typename std::enable_if<detail::conjunction<
|
||||
detail::negation<detail::is_exact_toml_type<T>> // not a toml::value
|
||||
>::value, std::nullptr_t>::type = nullptr,
|
||||
std::size_t = sizeof(::toml::from<T>) // and has from<T> specialization
|
||||
>
|
||||
T get(const toml::value& v);
|
||||
|
||||
// ============================================================================
|
||||
// array-like types; most likely STL container, like std::vector, etc.
|
||||
|
||||
@@ -297,6 +312,29 @@ T get(const toml::value& v)
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// user-defined, but compatible types.
|
||||
|
||||
template<typename T, typename std::enable_if<detail::conjunction<
|
||||
detail::negation<detail::is_exact_toml_type<T>>, // not a toml::value
|
||||
detail::has_from_toml_method<T>, // but has from_toml(toml::value) memfn
|
||||
std::is_default_constructible<T> // and default constructible
|
||||
>::value, std::nullptr_t>::type>
|
||||
T get(const toml::value& v)
|
||||
{
|
||||
T ud;
|
||||
ud.from_toml(v);
|
||||
return ud;
|
||||
}
|
||||
template<typename T, typename std::enable_if<detail::conjunction<
|
||||
detail::negation<detail::is_exact_toml_type<T>> // not a toml::value
|
||||
>::value, std::nullptr_t>::type, std::size_t> // and has from<T>
|
||||
T get(const toml::value& v)
|
||||
{
|
||||
return ::toml::from<T>::from_toml(v);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// find and get
|
||||
|
||||
|
||||
20
toml/into.hpp
Normal file
20
toml/into.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright Toru Niina 2019.
|
||||
// Distributed under the MIT License.
|
||||
#ifndef TOML11_INTO_HPP
|
||||
#define TOML11_INTO_HPP
|
||||
#include "traits.hpp"
|
||||
|
||||
namespace toml
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
struct into;
|
||||
// {
|
||||
// static toml::value into_toml(const T& user_defined_type)
|
||||
// {
|
||||
// // User-defined conversions ...
|
||||
// }
|
||||
// };
|
||||
|
||||
} // toml
|
||||
#endif // TOML11_INTO_HPP
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
namespace toml
|
||||
{
|
||||
|
||||
class value; // forward decl
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
@@ -45,6 +48,22 @@ struct has_resize_method_impl
|
||||
template<typename T> static std::false_type check(...);
|
||||
};
|
||||
|
||||
struct has_from_toml_method_impl
|
||||
{
|
||||
template<typename T>
|
||||
static std::true_type check(
|
||||
decltype(std::declval<T>().from_toml(std::declval<::toml::value>()))*);
|
||||
template<typename T>
|
||||
static std::false_type check(...);
|
||||
};
|
||||
struct has_into_toml_method_impl
|
||||
{
|
||||
template<typename T>
|
||||
static std::true_type check(decltype(std::declval<T>().into_toml())*);
|
||||
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
|
||||
@@ -62,6 +81,14 @@ struct has_mapped_type : decltype(has_mapped_type_impl::check<T>(nullptr)){};
|
||||
template<typename T>
|
||||
struct has_resize_method : decltype(has_resize_method_impl::check<T>(nullptr)){};
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct has_from_toml_method
|
||||
: decltype(has_from_toml_method_impl::check<T>(nullptr)){};
|
||||
template<typename T>
|
||||
struct has_into_toml_method
|
||||
: decltype(has_into_toml_method_impl::check<T>(nullptr)){};
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
#undef decltype(...)
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#ifndef TOML11_VALUE_HPP
|
||||
#define TOML11_VALUE_HPP
|
||||
#include "traits.hpp"
|
||||
#include "into.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "exception.hpp"
|
||||
#include "storage.hpp"
|
||||
@@ -533,6 +534,46 @@ class value
|
||||
return *this;
|
||||
}
|
||||
|
||||
// user-defined =========================================================
|
||||
|
||||
// convert using into_toml() method -------------------------------------
|
||||
|
||||
template<typename T, typename std::enable_if<detail::conjunction<
|
||||
detail::negation<detail::is_exact_toml_type<T>>, // not a toml::value
|
||||
detail::has_into_toml_method<T> // but has `into_toml` method
|
||||
>::value, std::nullptr_t>::type = nullptr>
|
||||
value(const T& ud): value(ud.into_toml()) {}
|
||||
|
||||
template<typename T, typename std::enable_if<detail::conjunction<
|
||||
detail::negation<detail::is_exact_toml_type<T>>, // not a toml::value
|
||||
detail::has_into_toml_method<T> // but has `into_toml` method
|
||||
>::value, std::nullptr_t>::type = nullptr>
|
||||
value& operator=(const T& ud)
|
||||
{
|
||||
*this = ud.into_toml();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// convert using into<T> struct -----------------------------------------
|
||||
|
||||
template<typename T, typename std::enable_if<
|
||||
detail::negation<detail::is_exact_toml_type<T>>::value,
|
||||
std::nullptr_t>::type = nullptr,
|
||||
std::size_t S = sizeof(::toml::into<T>)>
|
||||
value(const T& ud): value(::toml::into<T>::into_toml(ud)) {}
|
||||
|
||||
template<typename T, typename std::enable_if<
|
||||
detail::negation<detail::is_exact_toml_type<T>>::value,
|
||||
std::nullptr_t>::type = nullptr,
|
||||
std::size_t S = sizeof(::toml::into<T>)>
|
||||
value& operator=(const T& ud)
|
||||
{
|
||||
*this = ::toml::into<T>::into_toml(ud);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// type checking and casting ============================================
|
||||
|
||||
template<typename T>
|
||||
bool is() const noexcept {return value_traits<T>::type_index == this->type_;}
|
||||
bool is(value_t t) const noexcept {return t == this->type_;}
|
||||
|
||||
Reference in New Issue
Block a user