From f6febbe359f0936c411fac9788985118aa82fdef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20DELRIEU?= Date: Tue, 24 Jul 2018 13:22:44 +0200 Subject: [PATCH 1/5] split meta.hpp, add detected_t (used to define concepts) --- Makefile | 5 +- .../nlohmann/detail/conversions/from_json.hpp | 3 +- .../nlohmann/detail/conversions/to_json.hpp | 3 +- .../nlohmann/detail/iterators/iter_impl.hpp | 2 +- include/nlohmann/detail/meta/cpp_future.hpp | 83 ++++++++++++++++ include/nlohmann/detail/meta/detected.hpp | 56 +++++++++++ .../detail/{meta.hpp => meta/type_traits.hpp} | 76 +-------------- include/nlohmann/detail/meta/void_t.hpp | 10 ++ include/nlohmann/detail/output/serializer.hpp | 2 +- include/nlohmann/json.hpp | 3 +- single_include/nlohmann/json.hpp | 96 +++++++++++-------- test/src/unit-inspection.cpp | 4 +- 12 files changed, 222 insertions(+), 121 deletions(-) create mode 100644 include/nlohmann/detail/meta/cpp_future.hpp create mode 100644 include/nlohmann/detail/meta/detected.hpp rename include/nlohmann/detail/{meta.hpp => meta/type_traits.hpp} (74%) create mode 100644 include/nlohmann/detail/meta/void_t.hpp diff --git a/Makefile b/Makefile index 1e12178804..36b01450de 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,10 @@ SRCS = include/nlohmann/json.hpp \ include/nlohmann/detail/json_ref.hpp \ include/nlohmann/detail/macro_scope.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/output_adapters.hpp \ include/nlohmann/detail/output/serializer.hpp \ diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp index b092c8cc32..5956352fb9 100644 --- a/include/nlohmann/detail/conversions/from_json.hpp +++ b/include/nlohmann/detail/conversions/from_json.hpp @@ -15,7 +15,8 @@ #include #include -#include +#include +#include #include namespace nlohmann diff --git a/include/nlohmann/detail/conversions/to_json.hpp b/include/nlohmann/detail/conversions/to_json.hpp index 07946f55ac..35be5de468 100644 --- a/include/nlohmann/detail/conversions/to_json.hpp +++ b/include/nlohmann/detail/conversions/to_json.hpp @@ -8,7 +8,8 @@ #include // valarray #include // vector -#include +#include +#include #include #include diff --git a/include/nlohmann/detail/iterators/iter_impl.hpp b/include/nlohmann/detail/iterators/iter_impl.hpp index f34f7a5540..adcd8a37bb 100644 --- a/include/nlohmann/detail/iterators/iter_impl.hpp +++ b/include/nlohmann/detail/iterators/iter_impl.hpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include namespace nlohmann diff --git a/include/nlohmann/detail/meta/cpp_future.hpp b/include/nlohmann/detail/meta/cpp_future.hpp new file mode 100644 index 0000000000..d12d6bdb76 --- /dev/null +++ b/include/nlohmann/detail/meta/cpp_future.hpp @@ -0,0 +1,83 @@ +#pragma once + +#include // not +#include // size_t +#include // 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 +using enable_if_t = typename std::enable_if::type; + +template +using uncvref_t = typename std::remove_cv::type>::type; + +// implementation of C++14 index_sequence and affiliates +// source: https://stackoverflow.com/a/32223343 +template +struct index_sequence +{ + using type = index_sequence; + using value_type = std::size_t; + static constexpr std::size_t size() noexcept + { + return sizeof...(Ints); + } +}; + +template +struct merge_and_renumber; + +template +struct merge_and_renumber, index_sequence> + : index_sequence < I1..., (sizeof...(I1) + I2)... > {}; + +template +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 +using index_sequence_for = make_index_sequence; + +/* +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::value and has_value_type::value +will not compile when T = void (on MSVC at least). Whereas +conjunction>, has_value_type>::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 struct conjunction : std::true_type {}; +template struct conjunction : B1 {}; +template +struct conjunction : std::conditional, B1>::type {}; + +template struct negation : std::integral_constant {}; + +// dispatch utility (taken from ranges-v3) +template struct priority_tag : priority_tag < N - 1 > {}; +template<> struct priority_tag<0> {}; + +// taken from ranges-v3 +template +struct static_const +{ + static constexpr T value{}; +}; + +template +constexpr T static_const::value; +} +} diff --git a/include/nlohmann/detail/meta/detected.hpp b/include/nlohmann/detail/meta/detected.hpp new file mode 100644 index 0000000000..ed1d6ac71d --- /dev/null +++ b/include/nlohmann/detail/meta/detected.hpp @@ -0,0 +1,56 @@ +#pragma once + +#include + +#include + +// 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 Op, + class... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +template class Op, class... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +template