// // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // Official repository: https://github.com/boostorg/json // #ifndef BOOST_JSON_DETAIL_VALUE_TRAITS_HPP #define BOOST_JSON_DETAIL_VALUE_TRAITS_HPP #include #include #include #include BOOST_JSON_NS_BEGIN namespace detail { template struct priority_tag : priority_tag { }; template<> struct priority_tag<0> { }; using std::begin; using std::end; #ifdef __cpp_lib_nonmember_container_access using std::size; #endif template struct container_traits { static constexpr bool is_container = false; }; template struct container_traits())), decltype(end(std::declval()))>::value>::type> { private: template().size()), std::size_t>::value>::type* = nullptr> static std::size_t size_impl( U&& cont, priority_tag<2>) { return cont.size(); } template())), std::size_t>::value>::type* = nullptr> static std::size_t size_impl( U& cont, priority_tag<1>) { return size(cont); } template static std::size_t size_impl( U(&)[N], priority_tag<1>) { return N; } template static std::size_t size_impl(U&, priority_tag<0>) { return 0; } template static auto reserve_impl( U& cont, std::size_t size, priority_tag<1>) -> void_t().reserve(0))> { cont.reserve(size); } template static void reserve_impl( U&, std::size_t, priority_tag<0>) { } public: static constexpr bool is_container = true; using value_type = remove_cvref< decltype(*begin(std::declval()))>; template static std::size_t try_size(U& cont) { return container_traits::size_impl( cont, priority_tag<2>()); } template static void try_reserve( U& cont, std::size_t size) { container_traits::reserve_impl( cont, size, priority_tag<1>()); } }; template struct map_traits { static constexpr bool is_map = false; static constexpr bool has_unique_keys = false; }; template struct map_traits::key_type, typename std::enable_if::is_container && std::tuple_size:: value_type>::value == 2>::type>> { private: template struct unique_keys : std::false_type { }; template struct unique_keys&>().emplace(std::declval::value_type>()))>>::value > 0)>::type> : std::true_type { }; public: static constexpr bool is_map = true; static constexpr bool has_unique_keys = unique_keys::value; using pair_key_type = typename std::tuple_element< 0, typename remove_cvref::value_type>::type; using pair_value_type = typename std::tuple_element< 1, typename remove_cvref::value_type>::type; static constexpr bool key_converts_to_string = std::is_convertible::value; }; // does not include std::nullptr_t template using value_constructible = std::integral_constant, value>::value || std::is_same, object>::value || std::is_same, array>::value || std::is_same, string>::value || std::is_same, string_view>::value || std::is_arithmetic>::value || std::is_same, char const*>::value || std::is_same, std::initializer_list>::value || std::is_same, value_ref>::value>; BOOST_STATIC_ASSERT(value_constructible::value); } // detail BOOST_JSON_NS_END #endif