split meta.hpp, add detected_t (used to define concepts)

This commit is contained in:
Théo DELRIEU 2018-07-24 13:22:44 +02:00
parent 3ac2d81a95
commit f6febbe359
No known key found for this signature in database
GPG key ID: 7D6E00D1DF01DEAF
12 changed files with 222 additions and 121 deletions

View file

@ -21,7 +21,10 @@ SRCS = include/nlohmann/json.hpp \
include/nlohmann/detail/json_ref.hpp \ include/nlohmann/detail/json_ref.hpp \
include/nlohmann/detail/macro_scope.hpp \ include/nlohmann/detail/macro_scope.hpp \
include/nlohmann/detail/macro_unscope.hpp \ include/nlohmann/detail/macro_unscope.hpp \
include/nlohmann/detail/meta.hpp \ include/nlohmann/detail/meta/cpp_future.hpp \
include/nlohmann/detail/meta/detected.hpp \
include/nlohmann/detail/meta/type_traits.hpp \
include/nlohmann/detail/meta/void_t.hpp \
include/nlohmann/detail/output/binary_writer.hpp \ include/nlohmann/detail/output/binary_writer.hpp \
include/nlohmann/detail/output/output_adapters.hpp \ include/nlohmann/detail/output/output_adapters.hpp \
include/nlohmann/detail/output/serializer.hpp \ include/nlohmann/detail/output/serializer.hpp \

View file

@ -15,7 +15,8 @@
#include <nlohmann/detail/exceptions.hpp> #include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/macro_scope.hpp> #include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta.hpp> #include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/value_t.hpp> #include <nlohmann/detail/value_t.hpp>
namespace nlohmann namespace nlohmann

View file

@ -8,7 +8,8 @@
#include <valarray> // valarray #include <valarray> // valarray
#include <vector> // vector #include <vector> // vector
#include <nlohmann/detail/meta.hpp> #include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/value_t.hpp> #include <nlohmann/detail/value_t.hpp>
#include <nlohmann/detail/iterators/iteration_proxy.hpp> #include <nlohmann/detail/iterators/iteration_proxy.hpp>

View file

@ -8,7 +8,7 @@
#include <nlohmann/detail/iterators/internal_iterator.hpp> #include <nlohmann/detail/iterators/internal_iterator.hpp>
#include <nlohmann/detail/iterators/primitive_iterator.hpp> #include <nlohmann/detail/iterators/primitive_iterator.hpp>
#include <nlohmann/detail/macro_scope.hpp> #include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta.hpp> #include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/value_t.hpp> #include <nlohmann/detail/value_t.hpp>
namespace nlohmann namespace nlohmann

View file

@ -0,0 +1,83 @@
#pragma once
#include <ciso646> // not
#include <cstddef> // size_t
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
namespace nlohmann
{
namespace detail
{
// alias templates to reduce boilerplate
template<bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
template<typename T>
using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
// implementation of C++14 index_sequence and affiliates
// source: https://stackoverflow.com/a/32223343
template<std::size_t... Ints>
struct index_sequence
{
using type = index_sequence;
using value_type = std::size_t;
static constexpr std::size_t size() noexcept
{
return sizeof...(Ints);
}
};
template<class Sequence1, class Sequence2>
struct merge_and_renumber;
template<std::size_t... I1, std::size_t... I2>
struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
: index_sequence < I1..., (sizeof...(I1) + I2)... > {};
template<std::size_t N>
struct make_index_sequence
: merge_and_renumber < typename make_index_sequence < N / 2 >::type,
typename make_index_sequence < N - N / 2 >::type > {};
template<> struct make_index_sequence<0> : index_sequence<> {};
template<> struct make_index_sequence<1> : index_sequence<0> {};
template<typename... Ts>
using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
/*
Implementation of two C++17 constructs: conjunction, negation. This is needed
to avoid evaluating all the traits in a condition
For example: not std::is_same<void, T>::value and has_value_type<T>::value
will not compile when T = void (on MSVC at least). Whereas
conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
stop evaluating if negation<...>::value == false
Please note that those constructs must be used with caution, since symbols can
become very long quickly (which can slow down compilation and cause MSVC
internal compiler errors). Only use it when you have to (see example ahead).
*/
template<class...> struct conjunction : std::true_type {};
template<class B1> struct conjunction<B1> : B1 {};
template<class B1, class... Bn>
struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
template<class B> struct negation : std::integral_constant<bool, not B::value> {};
// dispatch utility (taken from ranges-v3)
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
template<> struct priority_tag<0> {};
// taken from ranges-v3
template<typename T>
struct static_const
{
static constexpr T value{};
};
template<typename T>
constexpr T static_const<T>::value;
}
}

View file

@ -0,0 +1,56 @@
#pragma once
#include <type_traits>
#include <nlohmann/detail/meta/void_t.hpp>
// http://en.cppreference.com/w/cpp/experimental/is_detected
namespace nlohmann
{
namespace detail
{
struct nonesuch
{
nonesuch() = delete;
~nonesuch() = delete;
nonesuch(nonesuch const&) = delete;
void operator=(nonesuch const&) = delete;
};
template <class Default,
class AlwaysVoid,
template <class...> class Op,
class... Args>
struct detector
{
using value_t = std::false_type;
using type = Default;
};
template <class Default, template <class...> class Op, class... Args>
struct detector<Default, void_t<Op<Args...>>, Op, Args...>
{
using value_t = std::true_type;
using type = Op<Args...>;
};
template <template <class...> class Op, class... Args>
using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
template <template <class...> class Op, class... Args>
using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
template <class Default, template <class...> class Op, class... Args>
using detected_or = detector<Default, void, Op, Args...>;
template <class Default, template <class...> class Op, class... Args>
using detected_or_t = typename detected_or<Default, Op, Args...>::type;
template <class Expected, template <class...> class Op, class... Args>
using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
template <class To, template <class...> class Op, class... Args>
using is_detected_convertible =
std::is_convertible<detected_t<Op, Args...>, To>;
}
}

View file

@ -1,12 +1,12 @@
#pragma once #pragma once
#include <ciso646> // not #include <ciso646> // not
#include <cstddef> // size_t
#include <limits> // numeric_limits #include <limits> // numeric_limits
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
#include <utility> // declval #include <utility> // declval
#include <nlohmann/json_fwd.hpp> #include <nlohmann/json_fwd.hpp>
#include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/macro_scope.hpp> #include <nlohmann/detail/macro_scope.hpp>
namespace nlohmann namespace nlohmann
@ -30,68 +30,6 @@ template<typename> struct is_basic_json : std::false_type {};
NLOHMANN_BASIC_JSON_TPL_DECLARATION NLOHMANN_BASIC_JSON_TPL_DECLARATION
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {}; struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
// alias templates to reduce boilerplate
template<bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
template<typename T>
using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
// implementation of C++14 index_sequence and affiliates
// source: https://stackoverflow.com/a/32223343
template<std::size_t... Ints>
struct index_sequence
{
using type = index_sequence;
using value_type = std::size_t;
static constexpr std::size_t size() noexcept
{
return sizeof...(Ints);
}
};
template<class Sequence1, class Sequence2>
struct merge_and_renumber;
template<std::size_t... I1, std::size_t... I2>
struct merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
: index_sequence < I1..., (sizeof...(I1) + I2)... > {};
template<std::size_t N>
struct make_index_sequence
: merge_and_renumber < typename make_index_sequence < N / 2 >::type,
typename make_index_sequence < N - N / 2 >::type > {};
template<> struct make_index_sequence<0> : index_sequence<> {};
template<> struct make_index_sequence<1> : index_sequence<0> {};
template<typename... Ts>
using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
/*
Implementation of two C++17 constructs: conjunction, negation. This is needed
to avoid evaluating all the traits in a condition
For example: not std::is_same<void, T>::value and has_value_type<T>::value
will not compile when T = void (on MSVC at least). Whereas
conjunction<negation<std::is_same<void, T>>, has_value_type<T>>::value will
stop evaluating if negation<...>::value == false
Please note that those constructs must be used with caution, since symbols can
become very long quickly (which can slow down compilation and cause MSVC
internal compiler errors). Only use it when you have to (see example ahead).
*/
template<class...> struct conjunction : std::true_type {};
template<class B1> struct conjunction<B1> : B1 {};
template<class B1, class... Bn>
struct conjunction<B1, Bn...> : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
template<class B> struct negation : std::integral_constant<bool, not B::value> {};
// dispatch utility (taken from ranges-v3)
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
template<> struct priority_tag<0> {};
//////////////////////// ////////////////////////
// has_/is_ functions // // has_/is_ functions //
//////////////////////// ////////////////////////
@ -264,15 +202,5 @@ struct is_compatible_type
is_compatible_complete_type<BasicJsonType, CompatibleType>> is_compatible_complete_type<BasicJsonType, CompatibleType>>
{ {
}; };
// taken from ranges-v3
template<typename T>
struct static_const
{
static constexpr T value{};
};
template<typename T>
constexpr T static_const<T>::value;
} }
} }

View file

@ -0,0 +1,10 @@
#pragma once
namespace nlohmann
{
namespace detail
{
template <typename...>
using void_t = void;
}
}

View file

@ -16,7 +16,7 @@
#include <nlohmann/detail/exceptions.hpp> #include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/conversions/to_chars.hpp> #include <nlohmann/detail/conversions/to_chars.hpp>
#include <nlohmann/detail/macro_scope.hpp> #include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta.hpp> #include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/output/output_adapters.hpp> #include <nlohmann/detail/output/output_adapters.hpp>
#include <nlohmann/detail/value_t.hpp> #include <nlohmann/detail/value_t.hpp>

View file

@ -48,7 +48,8 @@ SOFTWARE.
#include <nlohmann/json_fwd.hpp> #include <nlohmann/json_fwd.hpp>
#include <nlohmann/detail/macro_scope.hpp> #include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/meta.hpp> #include <nlohmann/detail/meta/cpp_future.hpp>
#include <nlohmann/detail/meta/type_traits.hpp>
#include <nlohmann/detail/exceptions.hpp> #include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/value_t.hpp> #include <nlohmann/detail/value_t.hpp>
#include <nlohmann/detail/conversions/from_json.hpp> #include <nlohmann/detail/conversions/from_json.hpp>

View file

@ -238,41 +238,17 @@ contains a `mapped_type`, whereas `std::vector` fails the test.
std::is_integral<decltype(detect(std::declval<T>()))>::value; \ std::is_integral<decltype(detect(std::declval<T>()))>::value; \
} }
// #include <nlohmann/detail/meta.hpp> // #include <nlohmann/detail/meta/cpp_future.hpp>
#include <ciso646> // not #include <ciso646> // not
#include <cstddef> // size_t #include <cstddef> // size_t
#include <limits> // numeric_limits
#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
#include <utility> // declval
// #include <nlohmann/json_fwd.hpp>
// #include <nlohmann/detail/macro_scope.hpp>
namespace nlohmann namespace nlohmann
{ {
/*!
@brief detail namespace with internal helper functions
This namespace collects functions that should not be exposed,
implementations of some @ref basic_json methods, and meta-programming helpers.
@since version 2.1.0
*/
namespace detail namespace detail
{ {
/////////////
// helpers //
/////////////
template<typename> struct is_basic_json : std::false_type {};
NLOHMANN_BASIC_JSON_TPL_DECLARATION
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
// alias templates to reduce boilerplate // alias templates to reduce boilerplate
template<bool B, typename T = void> template<bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type; using enable_if_t = typename std::enable_if<B, T>::type;
@ -335,6 +311,54 @@ template<class B> struct negation : std::integral_constant<bool, not B::value> {
template<unsigned N> struct priority_tag : priority_tag < N - 1 > {}; template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
template<> struct priority_tag<0> {}; template<> struct priority_tag<0> {};
// taken from ranges-v3
template<typename T>
struct static_const
{
static constexpr T value{};
};
template<typename T>
constexpr T static_const<T>::value;
}
}
// #include <nlohmann/detail/meta/type_traits.hpp>
#include <ciso646> // not
#include <limits> // numeric_limits
#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
#include <utility> // declval
// #include <nlohmann/json_fwd.hpp>
// #include <nlohmann/detail/meta/cpp_future.hpp>
// #include <nlohmann/detail/macro_scope.hpp>
namespace nlohmann
{
/*!
@brief detail namespace with internal helper functions
This namespace collects functions that should not be exposed,
implementations of some @ref basic_json methods, and meta-programming helpers.
@since version 2.1.0
*/
namespace detail
{
/////////////
// helpers //
/////////////
template<typename> struct is_basic_json : std::false_type {};
NLOHMANN_BASIC_JSON_TPL_DECLARATION
struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
//////////////////////// ////////////////////////
// has_/is_ functions // // has_/is_ functions //
//////////////////////// ////////////////////////
@ -507,16 +531,6 @@ struct is_compatible_type
is_compatible_complete_type<BasicJsonType, CompatibleType>> is_compatible_complete_type<BasicJsonType, CompatibleType>>
{ {
}; };
// taken from ranges-v3
template<typename T>
struct static_const
{
static constexpr T value{};
};
template<typename T>
constexpr T static_const<T>::value;
} }
} }
@ -950,7 +964,9 @@ inline bool operator<(const value_t lhs, const value_t rhs) noexcept
// #include <nlohmann/detail/macro_scope.hpp> // #include <nlohmann/detail/macro_scope.hpp>
// #include <nlohmann/detail/meta.hpp> // #include <nlohmann/detail/meta/cpp_future.hpp>
// #include <nlohmann/detail/meta/type_traits.hpp>
// #include <nlohmann/detail/value_t.hpp> // #include <nlohmann/detail/value_t.hpp>
@ -1335,7 +1351,9 @@ constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::va
#include <valarray> // valarray #include <valarray> // valarray
#include <vector> // vector #include <vector> // vector
// #include <nlohmann/detail/meta.hpp> // #include <nlohmann/detail/meta/cpp_future.hpp>
// #include <nlohmann/detail/meta/type_traits.hpp>
// #include <nlohmann/detail/value_t.hpp> // #include <nlohmann/detail/value_t.hpp>
@ -4873,7 +4891,7 @@ template<typename BasicJsonType> struct internal_iterator
// #include <nlohmann/detail/macro_scope.hpp> // #include <nlohmann/detail/macro_scope.hpp>
// #include <nlohmann/detail/meta.hpp> // #include <nlohmann/detail/meta/cpp_future.hpp>
// #include <nlohmann/detail/value_t.hpp> // #include <nlohmann/detail/value_t.hpp>
@ -9488,7 +9506,7 @@ char* to_chars(char* first, char* last, FloatType value)
// #include <nlohmann/detail/macro_scope.hpp> // #include <nlohmann/detail/macro_scope.hpp>
// #include <nlohmann/detail/meta.hpp> // #include <nlohmann/detail/meta/cpp_future.hpp>
// #include <nlohmann/detail/output/output_adapters.hpp> // #include <nlohmann/detail/output/output_adapters.hpp>

View file

@ -317,8 +317,8 @@ TEST_CASE("object inspection")
SECTION("round trips") SECTION("round trips")
{ {
for (const auto& s : for (const auto& s :
{"3.141592653589793", "1000000000000000010E5" {"3.141592653589793", "1000000000000000010E5"
}) })
{ {
json j1 = json::parse(s); json j1 = json::parse(s);
std::string s1 = j1.dump(); std::string s1 = j1.dump();