impl/conversion.hpp

100.0% Lines (18/0/18) 95.8% List of functions (69/1/73)
conversion.hpp
f(x) Functions (73)
Function Calls Lines Blocks
unsigned long boost::json::detail::try_size<std::array<int, 4ul> const&>(std::array<int, 4ul> const&, std::integral_constant<int, 3>) :130 4x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::array<int, 500ul>&>(std::array<int, 500ul>&, std::integral_constant<int, 3>) :130 12x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::map<boost::core::basic_string_view<char>, int, std::less<boost::core::basic_string_view<char> >, std::allocator<std::pair<boost::core::basic_string_view<char> const, int> > >&>(std::map<boost::core::basic_string_view<char>, int, std::less<boost::core::basic_string_view<char> >, std::allocator<std::pair<boost::core::basic_string_view<char> const, int> > >&, std::integral_constant<int, 3>) :130 6x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >&>(std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >&, std::integral_constant<int, 3>) :130 12x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, double, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > > const&>(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, double, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > > const&, std::integral_constant<int, 3>) :130 1x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > > const&>(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > > const&, std::integral_constant<int, 3>) :130 9x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >&>(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >&, std::integral_constant<int, 3>) :130 6x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > > > > > const&>(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > > > > > const&, std::integral_constant<int, 3>) :130 2x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<int, bool>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::pair<int, bool> > > > const&>(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<int, bool>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::pair<int, bool> > > > const&, std::integral_constant<int, 3>) :130 2x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<int, bool>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::pair<int, bool> > > >&>(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<int, bool>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::pair<int, bool> > > >&, std::integral_constant<int, 3>) :130 1x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<int, std::allocator<int> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<int, std::allocator<int> > > > > const&>(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<int, std::allocator<int> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<int, std::allocator<int> > > > > const&, std::integral_constant<int, 3>) :130 2x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > > > > > const&>(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > > > > > const&, std::integral_constant<int, 3>) :130 3x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, user_ns2::ip_address, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, user_ns2::ip_address> > >&>(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, user_ns2::ip_address, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, user_ns2::ip_address> > >&, std::integral_constant<int, 3>) :130 1x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, user_ns::ip_address, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, user_ns::ip_address> > >&>(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, user_ns::ip_address, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, user_ns::ip_address> > >&, std::integral_constant<int, 3>) :130 1x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::multimap<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >&>(std::multimap<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >&, std::integral_constant<int, 3>) :130 6x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, int> > >&>(std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, int> > >&, std::integral_constant<int, 3>) :130 6x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >&>(std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >&, std::integral_constant<int, 3>) :130 12x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::vector<bool, std::allocator<bool> > const&>(std::vector<bool, std::allocator<bool> > const&, std::integral_constant<int, 3>) :130 2x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::vector<bool, std::allocator<bool> >&>(std::vector<bool, std::allocator<bool> >&, std::integral_constant<int, 3>) :130 6x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::vector<boost::json::my_app::customer, std::allocator<boost::json::my_app::customer> >&>(std::vector<boost::json::my_app::customer, std::allocator<boost::json::my_app::customer> >&, std::integral_constant<int, 3>) :130 0 0.0% 0.0% unsigned long boost::json::detail::try_size<std::vector<boost::variant2::variant<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<boost::variant2::variant<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&>(std::vector<boost::variant2::variant<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<boost::variant2::variant<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > const&, std::integral_constant<int, 3>) :130 1x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::vector<decltype(nullptr), std::allocator<decltype(nullptr)> > const&>(std::vector<decltype(nullptr), std::allocator<decltype(nullptr)> > const&, std::integral_constant<int, 3>) :130 1x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::vector<float, std::allocator<float> > const&>(std::vector<float, std::allocator<float> > const&, std::integral_constant<int, 3>) :130 2x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::vector<int, std::allocator<int> > const&>(std::vector<int, std::allocator<int> > const&, std::integral_constant<int, 3>) :130 14x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::vector<int, std::allocator<int> >&>(std::vector<int, std::allocator<int> >&, std::integral_constant<int, 3>) :130 11x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&>(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, std::integral_constant<int, 3>) :130 2x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::vector<std::array<int, 4ul>, std::allocator<std::array<int, 4ul> > > const&>(std::vector<std::array<int, 4ul>, std::allocator<std::array<int, 4ul> > > const&, std::integral_constant<int, 3>) :130 1x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::vector<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >, std::allocator<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > > > > const&>(std::vector<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >, std::allocator<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > > > > const&, std::integral_constant<int, 3>) :130 1x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > > const&>(std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > > const&, std::integral_constant<int, 3>) :130 7x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::vector<std::pair<std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > >, user_ns::ip_address>, std::allocator<std::pair<std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > >, user_ns::ip_address> > >&>(std::vector<std::pair<std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > >, user_ns::ip_address>, std::allocator<std::pair<std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > >, user_ns::ip_address> > >&, std::integral_constant<int, 3>) :130 1x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&>(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > const&, std::integral_constant<int, 3>) :130 2x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::vector<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > >, std::allocator<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > > > > const&>(std::vector<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > >, std::allocator<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > > > > const&, std::integral_constant<int, 3>) :130 3x 100.0% 100.0% unsigned long boost::json::detail::try_size<std::vector<unsigned long, std::allocator<unsigned long> > const&>(std::vector<unsigned long, std::allocator<unsigned long> > const&, std::integral_constant<int, 3>) :130 1x 100.0% 100.0% unsigned long boost::json::detail::try_size<value_from_test_ns::T6>(value_from_test_ns::T6&, std::integral_constant<int, 2>) :137 1x 100.0% 100.0% unsigned long boost::json::detail::try_size<int, 4ul>(int (&) [4ul], std::integral_constant<int, 1>) :144 1x 100.0% 100.0% unsigned long boost::json::detail::try_size<int [4]>(int (&) [4], std::integral_constant<int, 0>) :151 6x 100.0% 100.0% unsigned long boost::json::detail::try_size<value_from_test_ns::T1>(value_from_test_ns::T1&, std::integral_constant<int, 0>) :151 1x 100.0% 100.0% decltype (begin((declval<std::array<int, 4ul>&>)())) boost::json::detail::inserter<std::array<int, 4ul> >(std::array<int, 4ul>&, std::integral_constant<int, 2>) :169 50x 100.0% 100.0% decltype (begin((declval<std::array<int, 500ul>&>)())) boost::json::detail::inserter<std::array<int, 500ul> >(std::array<int, 500ul>&, std::integral_constant<int, 2>) :169 6x 100.0% 100.0% decltype (begin((declval<value_to_test_ns::T4&>)())) boost::json::detail::inserter<value_to_test_ns::T4>(value_to_test_ns::T4&, std::integral_constant<int, 2>) :169 0 0.0% 0.0% std::back_insert_iterator<std::vector<bool, std::allocator<bool> > > boost::json::detail::inserter<std::vector<bool, std::allocator<bool> > >(std::vector<bool, std::allocator<bool> >&, std::integral_constant<int, 1>) :178 36x 100.0% 100.0% std::back_insert_iterator<std::vector<boost::json::my_app::customer, std::allocator<boost::json::my_app::customer> > > boost::json::detail::inserter<std::vector<boost::json::my_app::customer, std::allocator<boost::json::my_app::customer> > >(std::vector<boost::json::my_app::customer, std::allocator<boost::json::my_app::customer> >&, std::integral_constant<int, 1>) :178 0 0.0% 0.0% std::back_insert_iterator<std::vector<boost::variant2::variant<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<boost::variant2::variant<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > boost::json::detail::inserter<std::vector<boost::variant2::variant<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<boost::variant2::variant<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >(std::vector<boost::variant2::variant<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<boost::variant2::variant<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&, std::integral_constant<int, 1>) :178 15x 100.0% 100.0% std::back_insert_iterator<std::vector<char, std::allocator<char> > > boost::json::detail::inserter<std::vector<char, std::allocator<char> > >(std::vector<char, std::allocator<char> >&, std::integral_constant<int, 1>) :178 2x 100.0% 100.0% std::back_insert_iterator<std::vector<decltype(nullptr), std::allocator<decltype(nullptr)> > > boost::json::detail::inserter<std::vector<decltype(nullptr), std::allocator<decltype(nullptr)> > >(std::vector<decltype(nullptr), std::allocator<decltype(nullptr)> >&, std::integral_constant<int, 1>) :178 15x 100.0% 100.0% std::back_insert_iterator<std::vector<float, std::allocator<float> > > boost::json::detail::inserter<std::vector<float, std::allocator<float> > >(std::vector<float, std::allocator<float> >&, std::integral_constant<int, 1>) :178 30x 100.0% 100.0% std::back_insert_iterator<std::vector<int, std::allocator<int> > > boost::json::detail::inserter<std::vector<int, std::allocator<int> > >(std::vector<int, std::allocator<int> >&, std::integral_constant<int, 1>) :178 195x 100.0% 100.0% std::back_insert_iterator<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > boost::json::detail::inserter<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::integral_constant<int, 1>) :178 30x 100.0% 100.0% std::back_insert_iterator<std::vector<std::array<int, 4ul>, std::allocator<std::array<int, 4ul> > > > boost::json::detail::inserter<std::vector<std::array<int, 4ul>, std::allocator<std::array<int, 4ul> > > >(std::vector<std::array<int, 4ul>, std::allocator<std::array<int, 4ul> > >&, std::integral_constant<int, 1>) :178 15x 100.0% 100.0% std::back_insert_iterator<std::vector<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >, std::allocator<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > > > > > boost::json::detail::inserter<std::vector<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >, std::allocator<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > > > > >(std::vector<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >, std::allocator<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > > > >&, std::integral_constant<int, 1>) :178 15x 100.0% 100.0% std::back_insert_iterator<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > > > boost::json::detail::inserter<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > > >(std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > >&, std::integral_constant<int, 1>) :178 112x 100.0% 100.0% std::back_insert_iterator<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > > boost::json::detail::inserter<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > >(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, std::integral_constant<int, 1>) :178 32x 100.0% 100.0% std::back_insert_iterator<std::vector<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > >, std::allocator<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > > > > > boost::json::detail::inserter<std::vector<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > >, std::allocator<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > > > > >(std::vector<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > >, std::allocator<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > > > >&, std::integral_constant<int, 1>) :178 45x 100.0% 100.0% std::back_insert_iterator<std::vector<unsigned long, std::allocator<unsigned long> > > boost::json::detail::inserter<std::vector<unsigned long, std::allocator<unsigned long> > >(std::vector<unsigned long, std::allocator<unsigned long> >&, std::integral_constant<int, 1>) :178 15x 100.0% 100.0% std::back_insert_iterator<std::vector<value_to_test_ns::T2, std::allocator<value_to_test_ns::T2> > > boost::json::detail::inserter<std::vector<value_to_test_ns::T2, std::allocator<value_to_test_ns::T2> > >(std::vector<value_to_test_ns::T2, std::allocator<value_to_test_ns::T2> >&, std::integral_constant<int, 1>) :178 12x 100.0% 100.0% std::insert_iterator<std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > > > boost::json::detail::inserter<std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > > >(std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >&, std::integral_constant<int, 0>) :187 6x 100.0% 100.0% std::insert_iterator<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > > > boost::json::detail::inserter<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > > >(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >&, std::integral_constant<int, 0>) :187 12x 100.0% 100.0% std::insert_iterator<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, value_to_test_ns::T2, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, value_to_test_ns::T2> > > > boost::json::detail::inserter<std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, value_to_test_ns::T2, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, value_to_test_ns::T2> > > >(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, value_to_test_ns::T2, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, value_to_test_ns::T2> > >&, std::integral_constant<int, 0>) :187 12x 100.0% 100.0% std::insert_iterator<std::multimap<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > > > boost::json::detail::inserter<std::multimap<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > > >(std::multimap<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >&, std::integral_constant<int, 0>) :187 6x 100.0% 100.0% std::insert_iterator<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > > > boost::json::detail::inserter<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > > >(std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >&, std::integral_constant<int, 0>) :187 6x 100.0% 100.0% <unknown function 606> :606 boost::json::detail::supported_context<user_ns::as_iso_8601, std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > > const&, std::integral_constant<bool, true> >::get(user_ns::as_iso_8601 const&) :606 3x 100.0% 100.0% boost::json::detail::supported_context<user_ns::as_iso_8601, std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > >&, std::integral_constant<bool, true> >::get(user_ns::as_iso_8601 const&) :606 5x 100.0% 100.0% boost::json::detail::supported_context<user_ns::as_string, user_ns::ip_address const&, std::integral_constant<bool, true> >::get(user_ns::as_string const&) :606 3x 100.0% 100.0% boost::json::detail::supported_context<user_ns::as_string, user_ns::ip_address&, std::integral_constant<bool, true> >::get(user_ns::as_string const&) :606 7x 100.0% 100.0% boost::json::detail::supported_context<user_ns::as_string, user_ns::ip_address, std::integral_constant<bool, false> >::get(user_ns::as_string const&) :606 1x 100.0% 100.0% boost::json::detail::supported_context<user_ns::date_format, std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > >&, std::integral_constant<bool, true> >::get(user_ns::date_format const&) :606 1x 100.0% 100.0% boost::json::detail::supported_context<user_ns::maps_as_objects, std::map<std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > >, user_ns::ip_address, std::less<std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > > >, std::allocator<std::pair<std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > > const, user_ns::ip_address> > >&, std::integral_constant<bool, true> >::get(user_ns::maps_as_objects const&) :606 1x 100.0% 100.0% boost::json::detail::supported_context<value_from_test_ns::another_context, std::vector<value_from_test_ns::T12, std::allocator<value_from_test_ns::T12> >, std::integral_constant<bool, true> >::get(value_from_test_ns::another_context const&) :606 1x 100.0% 100.0% boost::json::detail::supported_context<value_from_test_ns::another_context, value_from_test_ns::T13, std::integral_constant<bool, true> >::get(value_from_test_ns::another_context const&) :606 2x 100.0% 100.0% boost::json::detail::supported_context<value_from_test_ns::custom_context, value_from_test_ns::T12 const&, std::integral_constant<bool, true> >::get(value_from_test_ns::custom_context const&) :606 2x 100.0% 100.0% boost::json::detail::supported_context<value_from_test_ns::custom_context, value_from_test_ns::T12, std::integral_constant<bool, true> >::get(value_from_test_ns::custom_context const&) :606 2x 100.0% 100.0% boost::json::detail::supported_context<value_to_test_ns::custom_context, value_to_test_ns::T9, std::integral_constant<bool, false> >::get(value_to_test_ns::custom_context const&) :606 2x 100.0% 100.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
3 // Copyright (c) 2022 Dmitry Arkhipov (grisumbras@yandex.ru)
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/boostorg/json
9 //
10
11 #ifndef BOOST_JSON_IMPL_CONVERSION_HPP
12 #define BOOST_JSON_IMPL_CONVERSION_HPP
13
14 #include <boost/json/fwd.hpp>
15 #include <boost/json/string_view.hpp>
16 #include <boost/describe/enumerators.hpp>
17 #include <boost/describe/members.hpp>
18 #include <boost/describe/bases.hpp>
19 #include <boost/mp11/algorithm.hpp>
20 #include <boost/mp11/utility.hpp>
21 #include <boost/system/result.hpp>
22
23 #include <iterator>
24 #include <tuple>
25 #include <utility>
26
27 #ifndef BOOST_NO_CXX17_HDR_VARIANT
28 # include <variant>
29 #endif // BOOST_NO_CXX17_HDR_VARIANT
30
31 #ifdef BOOST_JSON_HAS_REFLECTION
32 # include <meta>
33 #endif // BOOST_JSON_HAS_REFLECTION
34
35 namespace boost {
36 namespace json {
37
38 class value_ref;
39
40 namespace detail {
41
42 #ifdef __cpp_lib_nonmember_container_access
43 using std::size;
44 #endif
45
46 template<std::size_t I, class T>
47 using tuple_element_t = typename std::tuple_element<I, T>::type;
48
49 template<class T>
50 using iterator_type = decltype(std::begin(std::declval<T&>()));
51 template<class T>
52 using iterator_traits = std::iterator_traits< iterator_type<T> >;
53
54 template<class T>
55 using value_type = typename iterator_traits<T>::value_type;
56 template<class T>
57 using mapped_type = tuple_element_t< 1, value_type<T> >;
58
59 // had to make the metafunction always succeeding in order to make it work
60 // with msvc 14.0
61 template<class T>
62 using key_type_helper = tuple_element_t< 0, value_type<T> >;
63 template<class T>
64 using key_type = mp11::mp_eval_or<
65 void,
66 key_type_helper,
67 T>;
68
69 template<class T>
70 using are_begin_and_end_same = std::is_same<
71 iterator_type<T>,
72 decltype(std::end(std::declval<T&>()))>;
73
74 // msvc 14.0 gets confused when std::is_same is used directly
75 template<class A, class B>
76 using is_same_msvc_140 = std::is_same<A, B>;
77 template<class T>
78 using is_its_own_value = is_same_msvc_140<value_type<T>, T>;
79
80 template<class T>
81 using not_its_own_value = mp11::mp_not< is_its_own_value<T> >;
82
83 template<class T>
84 using begin_iterator_category = typename std::iterator_traits<
85 iterator_type<T>>::iterator_category;
86
87 template<class T>
88 using has_positive_tuple_size = mp11::mp_bool<
89 (std::tuple_size<T>::value > 0) >;
90
91 template<class T>
92 using has_unique_keys = has_positive_tuple_size<decltype(
93 std::declval<T&>().emplace(
94 std::declval<value_type<T>>()))>;
95
96 template<class T>
97 using has_string_type = std::is_same<
98 typename T::string_type, std::basic_string<typename T::value_type> >;
99
100 template<class T>
101 struct is_value_type_pair_helper : std::false_type
102 { };
103 template<class T1, class T2>
104 struct is_value_type_pair_helper<std::pair<T1, T2>> : std::true_type
105 { };
106 template<class T>
107 using is_value_type_pair = is_value_type_pair_helper<value_type<T>>;
108
109 template<class T>
110 using has_size_member_helper
111 = std::is_convertible<decltype(std::declval<T&>().size()), std::size_t>;
112 template<class T>
113 using has_size_member = mp11::mp_valid_and_true<has_size_member_helper, T>;
114 template<class T>
115 using has_free_size_helper
116 = std::is_convertible<
117 decltype(size(std::declval<T const&>())),
118 std::size_t>;
119 template<class T>
120 using has_free_size = mp11::mp_valid_and_true<has_free_size_helper, T>;
121 template<class T>
122 using size_implementation = mp11::mp_cond<
123 has_size_member<T>, mp11::mp_int<3>,
124 has_free_size<T>, mp11::mp_int<2>,
125 std::is_array<T>, mp11::mp_int<1>,
126 mp11::mp_true, mp11::mp_int<0>>;
127
128 template<class T>
129 std::size_t
130 141x try_size(T&& cont, mp11::mp_int<3>)
131 {
132 141x return cont.size();
133 }
134
135 template<class T>
136 std::size_t
137 1x try_size(T& cont, mp11::mp_int<2>)
138 {
139 1x return size(cont);
140 }
141
142 template<class T, std::size_t N>
143 std::size_t
144 1x try_size(T(&)[N], mp11::mp_int<1>)
145 {
146 1x return N;
147 }
148
149 template<class T>
150 std::size_t
151 7x try_size(T&, mp11::mp_int<0>)
152 {
153 7x return 0;
154 }
155
156 template<class T>
157 using has_push_back_helper
158 = decltype(std::declval<T&>().push_back(std::declval<value_type<T>>()));
159 template<class T>
160 using has_push_back = mp11::mp_valid<has_push_back_helper, T>;
161 template<class T>
162 using inserter_implementation = mp11::mp_cond<
163 is_tuple_like<T>, mp11::mp_int<2>,
164 has_push_back<T>, mp11::mp_int<1>,
165 mp11::mp_true, mp11::mp_int<0>>;
166
167 template<class T>
168 iterator_type<T>
169 56x inserter(
170 T& target,
171 mp11::mp_int<2>)
172 {
173 56x return target.begin();
174 }
175
176 template<class T>
177 std::back_insert_iterator<T>
178 569x inserter(
179 T& target,
180 mp11::mp_int<1>)
181 {
182 569x return std::back_inserter(target);
183 }
184
185 template<class T>
186 std::insert_iterator<T>
187 62x inserter(
188 T& target,
189 mp11::mp_int<0>)
190 {
191 62x return std::inserter( target, target.end() );
192 }
193
194 using boolean_category = std::integral_constant<
195 conversion_category, conversion_category::boolean>;
196
197 using integer_category = std::integral_constant<
198 conversion_category, conversion_category::integer>;
199
200 using floating_point_category = std::integral_constant<
201 conversion_category, conversion_category::floating_point>;
202
203 } // namespace detail
204
205
206 template<class T, class Ctx, class Enable>
207 struct use_category : unknown_category {};
208
209 namespace detail {
210
211 using value_from_conversion = mp11::mp_true;
212 using value_to_conversion = mp11::mp_false;
213
214 using user_category = std::integral_constant<
215 conversion_category, conversion_category::user>;
216 using user_context_category = std::integral_constant<
217 conversion_category, conversion_category::user_context>;
218 using user_full_context_category = std::integral_constant<
219 conversion_category, conversion_category::user_full_context>;
220 using json_value_category = std::integral_constant<
221 conversion_category, conversion_category::json_value>;
222 using json_object_category = std::integral_constant<
223 conversion_category, conversion_category::json_object>;
224 using json_array_category = std::integral_constant<
225 conversion_category, conversion_category::json_array>;
226 using json_string_category = std::integral_constant<
227 conversion_category, conversion_category::json_string>;
228 using json_value_ref_category = std::integral_constant<
229 conversion_category, conversion_category::json_value_ref>;
230
231 template< class Cat >
232 using is_user_conversion = mp11::mp_bool<
233 Cat::value == conversion_category::user
234 || Cat::value == conversion_category::user_context
235 || Cat::value == conversion_category::user_full_context>;
236
237 template< class Cat >
238 using is_native_conversion = mp11::mp_bool<
239 Cat::value == conversion_category::user
240 || Cat::value == conversion_category::json_value
241 || Cat::value == conversion_category::json_object
242 || Cat::value == conversion_category::json_array
243 || Cat::value == conversion_category::json_string
244 || Cat::value == conversion_category::json_value_ref
245 || Cat::value == conversion_category::boolean
246 || Cat::value == conversion_category::integer
247 || Cat::value == conversion_category::floating_point>;
248
249 template<class... Args>
250 using supports_tag_invoke = decltype(tag_invoke( std::declval<Args>()... ));
251
252 template<class T>
253 using has_user_conversion_from_impl = supports_tag_invoke<
254 value_from_tag, value&, T&& >;
255 template<class T>
256 using has_user_conversion_to_impl = supports_tag_invoke<
257 value_to_tag<T>, value const& >;
258 template<class T>
259 using has_nonthrowing_user_conversion_to_impl = supports_tag_invoke<
260 try_value_to_tag<T>, value const& >;
261 template< class T, class Dir >
262 using has_user_conversion1 = mp11::mp_if<
263 std::is_same<Dir, value_from_conversion>,
264 mp11::mp_valid<has_user_conversion_from_impl, T>,
265 mp11::mp_or<
266 mp11::mp_valid<has_user_conversion_to_impl, T>,
267 mp11::mp_valid<has_nonthrowing_user_conversion_to_impl, T>>>;
268
269 template< class Ctx, class T >
270 using has_context_conversion_from_impl = supports_tag_invoke<
271 value_from_tag, value&, T&&, Ctx const& >;
272 template< class Ctx, class T >
273 using has_context_conversion_to_impl = supports_tag_invoke<
274 value_to_tag<T>, value const&, Ctx const& >;
275 template< class Ctx, class T >
276 using has_nonthrowing_context_conversion_to_impl = supports_tag_invoke<
277 try_value_to_tag<T>, value const&, Ctx const& >;
278 template< class Ctx, class T, class Dir >
279 using has_user_conversion2 = mp11::mp_if<
280 std::is_same<Dir, value_from_conversion>,
281 mp11::mp_valid<has_context_conversion_from_impl, Ctx, T>,
282 mp11::mp_or<
283 mp11::mp_valid<has_context_conversion_to_impl, Ctx, T>,
284 mp11::mp_valid<has_nonthrowing_context_conversion_to_impl, Ctx, T>>>;
285
286 template< class Ctx, class T >
287 using has_full_context_conversion_from_impl = supports_tag_invoke<
288 value_from_tag, value&, T&&, Ctx const&, Ctx const& >;
289 template< class Ctx, class T >
290 using has_full_context_conversion_to_impl = supports_tag_invoke<
291 value_to_tag<T>, value const&, Ctx const&, Ctx const& >;
292 template< class Ctx, class T >
293 using has_nonthrowing_full_context_conversion_to_impl = supports_tag_invoke<
294 try_value_to_tag<T>, value const&, Ctx const&, Ctx const& >;
295 template< class Ctx, class T, class Dir >
296 using has_user_conversion3 = mp11::mp_if<
297 std::is_same<Dir, value_from_conversion>,
298 mp11::mp_valid<has_full_context_conversion_from_impl, Ctx, T>,
299 mp11::mp_or<
300 mp11::mp_valid<has_full_context_conversion_to_impl, Ctx, T>,
301 mp11::mp_valid<
302 has_nonthrowing_full_context_conversion_to_impl, Ctx, T>>>;
303
304 template< class T >
305 using described_non_public_members = describe::describe_members<
306 T,
307 describe::mod_private
308 | describe::mod_protected
309 | boost::describe::mod_inherited>;
310
311 #if defined(BOOST_MSVC) && BOOST_MSVC < 1920
312
313 template< class T >
314 struct described_member_t_impl;
315
316 template< class T, class C >
317 struct described_member_t_impl<T C::*>
318 {
319 using type = T;
320 };
321
322 template< class T, class D >
323 using described_member_t = remove_cvref<
324 typename described_member_t_impl<
325 remove_cvref<decltype(D::pointer)> >::type>;
326
327 #else
328
329 template< class T, class D >
330 using described_member_t = remove_cvref<decltype(
331 std::declval<T&>().* D::pointer )>;
332
333 #endif
334
335 template< class T >
336 using described_members = describe::describe_members<
337 T, describe::mod_any_access | describe::mod_inherited>;
338
339 #ifdef BOOST_DESCRIBE_CXX14
340
341 constexpr
342 bool
343 compare_strings(char const* l, char const* r)
344 {
345 #if defined(_MSC_VER) && (_MSC_VER <= 1900) && !defined(__clang__)
346 return *l == *r && ( (*l == 0) | compare_strings(l + 1, r + 1) );
347 #else
348 do
349 {
350 if( *l != *r )
351 return false;
352 if( *l == 0 )
353 return true;
354 ++l;
355 ++r;
356 } while(true);
357 #endif
358 }
359
360 template< class L, class R >
361 struct equal_member_names
362 : mp11::mp_bool< compare_strings(L::name, R::name) >
363 {};
364
365 template< class T >
366 using uniquely_named_members = mp11::mp_same<
367 mp11::mp_unique_if< described_members<T>, equal_member_names >,
368 described_members<T> >;
369
370 #else
371
372 // we only check this in C++14, but the template should exist nevertheless
373 template< class T >
374 using uniquely_named_members = std::true_type;
375
376 #endif // BOOST_DESCRIBE_CXX14
377
378 // user conversion (via tag_invoke)
379 template< class T, class Ctx, class Dir >
380 using tag_invoke_with_context_category = mp11::mp_cond<
381 has_user_conversion3<Ctx, T, Dir>, user_full_context_category,
382 has_user_conversion2<Ctx, T, Dir>, user_context_category>;
383
384 template< class T, class Dir >
385 using tag_invoke_category = mp11::mp_cond<
386 has_user_conversion1<T, Dir>, user_category>;
387
388 // native conversions (constructors and member functions of value)
389 template< class T >
390 using native_conversion_category = mp11::mp_cond<
391 std::is_same<T, value_ref>, json_value_ref_category,
392 std::is_same<T, value>, json_value_category,
393 std::is_same<T, array>, json_array_category,
394 std::is_same<T, object>, json_object_category,
395 std::is_same<T, string>, json_string_category>;
396
397 template<class T>
398 struct deduced_category
399 : mp11::mp_cond<
400 std::is_same<T, bool>, detail::boolean_category,
401 std::is_integral<T>, detail::integer_category,
402 std::is_floating_point<T>, detail::floating_point_category,
403 is_null_like<T>, null_category,
404 is_string_like<T>, string_category,
405 is_variant_like<T>, variant_category,
406 is_optional_like<T>, optional_category,
407 is_map_like<T>, map_category,
408 is_sequence_like<T>, sequence_category,
409 is_tuple_like<T>, tuple_category,
410 is_described_class<T>, described_class_category,
411 is_described_enum<T>, described_enum_category,
412 is_path_like<T>, path_category,
413 // failed to find a suitable implementation
414 mp11::mp_true, unknown_category>
415 { };
416
417 struct no_context {};
418
419 #ifdef BOOST_JSON_HAS_REFLECTION
420
421 template<class T, class Ctx>
422 constexpr
423 conversion_category
424 annotated_category_impl()
425 {
426 static constexpr auto annotations = std::define_static_array(
427 std::meta::annotations_of_with_type(^^T, ^^conversion_category));
428 template for (constexpr std::meta::info a_info: annotations)
429 {
430 return std::meta::extract<conversion_category>(a_info);
431 }
432 return conversion_category::unknown;
433 }
434
435 template <class T, class Ctx>
436 using annotated_category = std::integral_constant<
437 conversion_category, annotated_category_impl<T, Ctx>()>;
438
439 #endif // BOOST_JSON_HAS_REFLECTION
440 //
441 template <class T, class Ctx>
442 using use_category_helper = use_category<
443 T, mp11::mp_if<std::is_same<Ctx, no_context>, void, Ctx>>;
444
445 template< class Dir >
446 struct all_custom_checks
447 {
448 template <class T, class Ctx>
449 using fn = mp11::mp_list<
450 mp11::mp_defer<use_category_helper, T, Ctx>,
451 #ifdef BOOST_JSON_HAS_REFLECTION
452 mp11::mp_defer<annotated_category, T, Ctx>,
453 #endif // BOOST_JSON_HAS_REFLECTION
454 mp11::mp_defer<tag_invoke_with_context_category, T, Ctx, Dir>>;
455 };
456
457 template< class Dir >
458 struct all_fallback_checks
459 {
460 template <class T>
461 using fn = mp11::mp_list<
462 mp11::mp_defer<use_category_helper, T, void>,
463 #ifdef BOOST_JSON_HAS_REFLECTION
464 mp11::mp_defer<annotated_category, T, void>,
465 #endif // BOOST_JSON_HAS_REFLECTION
466 mp11::mp_defer<tag_invoke_category, T, Dir>,
467 mp11::mp_defer<native_conversion_category, T>,
468 mp11::mp_defer<deduced_category, T>>;
469 };
470
471 template <class T, class Ctx>
472 using direct_custom_checks = mp11::mp_list<
473 mp11::mp_defer<use_category_helper, T, Ctx>
474 #ifdef BOOST_JSON_HAS_REFLECTION
475 ,
476 mp11::mp_defer<annotated_category, T, Ctx>
477 #endif // BOOST_JSON_HAS_REFLECTION
478 >;
479
480 template <class T>
481 using direct_fallback_checks = mp11::mp_list<
482 mp11::mp_defer<use_category_helper, T, void>,
483 #ifdef BOOST_JSON_HAS_REFLECTION
484 mp11::mp_defer<annotated_category, T, void>,
485 #endif // BOOST_JSON_HAS_REFLECTION
486 mp11::mp_defer<deduced_category, T>>;
487
488 template <class>
489 using no_checks = mp11::mp_list<>;
490
491 template< class T >
492 using nested_type = typename T::type;
493
494 template< class T1, class T2 >
495 using get_conversion_category_helper = mp11::mp_eval_if_c<
496 conversion_category::unknown != T1::value,
497 T1,
498 mp11::mp_eval_or_q, T1, mp11::mp_quote<nested_type>, T2>;
499
500 template<
501 class T,
502 class Ctx,
503 template<class, class> class CustomChecks,
504 template<class> class FallbackChecks>
505 struct get_conversion_category_impl
506 {
507 using type = std::integral_constant<
508 conversion_category,
509 mp11::mp_fold<
510 mp11::mp_append< CustomChecks<T, Ctx>, FallbackChecks<T> >,
511 unknown_category,
512 get_conversion_category_helper>::value>;
513 };
514
515 template<
516 class T,
517 class Ctx,
518 template<class, class> class CustomChecks,
519 template<class> class FallbackChecks>
520 using get_conversion_category = typename get_conversion_category_impl<
521 T, Ctx, CustomChecks, FallbackChecks>::type;
522
523 template< class T >
524 using any_conversion_tag = mp11::mp_not< std::is_same<T, unknown_category> >;
525
526 template<
527 class T,
528 template<class, class> class CustomChecks,
529 template<class> class FallbackChecks,
530 class... Ctxs >
531 struct get_conversion_category_impl<
532 T, std::tuple<Ctxs...>, CustomChecks, FallbackChecks>
533 {
534 using ctxs = mp11::mp_list< remove_cvref<Ctxs>... >;
535 using cats = mp11::mp_list<
536 get_conversion_category<
537 T, remove_cvref<Ctxs>, CustomChecks, no_checks>... >;
538
539 using custom_index = mp11::mp_find_if< cats, any_conversion_tag >;
540 using is_custom = mp11::mp_less< custom_index, mp11::mp_size<cats> >;
541
542 using index = mp11::mp_if< is_custom, custom_index, mp11::mp_size_t<0> >;
543
544 using fallback_cat = mp11::mp_fold<
545 FallbackChecks<T>, unknown_category, get_conversion_category_helper>;
546
547 using type = std::integral_constant<
548 conversion_category,
549 mp11::mp_eval_if_not<
550 is_custom, fallback_cat, mp11::mp_at, cats, index>::value>;
551 };
552
553 template <class T, class Dir>
554 using can_convert = mp11::mp_not<
555 std::is_same<
556 get_conversion_category<
557 T,
558 no_context,
559 all_custom_checks<Dir>::template fn,
560 all_fallback_checks<Dir>::template fn>,
561 unknown_category>>;
562
563 template< class T1, class T2 >
564 struct copy_cref_helper
565 {
566 using type = remove_cvref<T2>;
567 };
568 template< class T1, class T2 >
569 using copy_cref = typename copy_cref_helper< T1, T2 >::type;
570
571 template< class T1, class T2 >
572 struct copy_cref_helper<T1 const, T2>
573 {
574 using type = remove_cvref<T2> const;
575 };
576 template< class T1, class T2 >
577 struct copy_cref_helper<T1&, T2>
578 {
579 using type = copy_cref<T1, T2>&;
580 };
581 template< class T1, class T2 >
582 struct copy_cref_helper<T1&&, T2>
583 {
584 using type = copy_cref<T1, T2>&&;
585 };
586
587 template< class Rng, class Traits >
588 using forwarded_value_helper = mp11::mp_if<
589 std::is_convertible<
590 typename Traits::reference,
591 copy_cref<Rng, typename Traits::value_type> >,
592 copy_cref<Rng, typename Traits::value_type>,
593 typename Traits::value_type >;
594
595 template< class Rng >
596 using forwarded_value = forwarded_value_helper<
597 Rng, iterator_traits< Rng > >;
598
599 template< class Ctx, class T, class Dir >
600 struct supported_context
601 {
602 using type = Ctx;
603
604 static
605 type const&
606 32x get( Ctx const& ctx ) noexcept
607 {
608 32x return ctx;
609 }
610 };
611
612 template< class T, class Dir, class... Ctxs >
613 struct supported_context< std::tuple<Ctxs...>, T, Dir >
614 {
615 using Ctx = std::tuple<Ctxs...>;
616 using impl = get_conversion_category_impl<
617 T,
618 Ctx,
619 all_custom_checks<Dir>::template fn,
620 all_fallback_checks<Dir>::template fn>;
621 using index = typename impl::index;
622 using next_supported = supported_context<
623 mp11::mp_at< typename impl::ctxs, index >, T, Dir >;
624 using type = typename next_supported::type;
625
626 static
627 type const&
628 19x get( Ctx const& ctx ) noexcept
629 {
630 19x return next_supported::get( std::get<index::value>( ctx ) );
631 }
632 };
633
634 template< class T >
635 using value_result_type = typename std::decay<
636 decltype( std::declval<T&>().value() )>::type;
637
638 template< class T >
639 using can_reset = decltype( std::declval<T&>().reset() );
640
641 template< class T >
642 using has_valueless_by_exception =
643 decltype( std::declval<T const&>().valueless_by_exception() );
644
645 } // namespace detail
646
647 template <class T>
648 struct result_for<T, value>
649 {
650 using type = system::result< detail::remove_cvref<T> >;
651 };
652
653 template<class T>
654 struct is_string_like
655 : std::is_convertible<T, string_view>
656 { };
657
658 template<class T>
659 struct is_path_like
660 : mp11::mp_all<
661 mp11::mp_valid_and_true<detail::is_its_own_value, T>,
662 mp11::mp_valid_and_true<detail::has_string_type, T>>
663 { };
664 template<class T>
665 struct is_sequence_like
666 : mp11::mp_all<
667 mp11::mp_valid_and_true<detail::are_begin_and_end_same, T>,
668 mp11::mp_valid_and_true<detail::not_its_own_value, T>,
669 mp11::mp_valid<detail::begin_iterator_category, T>>
670 { };
671
672 template<class T>
673 struct is_map_like
674 : mp11::mp_all<
675 is_sequence_like<T>,
676 mp11::mp_valid_and_true<detail::is_value_type_pair, T>,
677 is_string_like<detail::key_type<T>>,
678 mp11::mp_valid_and_true<detail::has_unique_keys, T>>
679 { };
680
681 template<class T>
682 struct is_tuple_like
683 : mp11::mp_valid_and_true<detail::has_positive_tuple_size, T>
684 { };
685
686 template<>
687 struct is_null_like<std::nullptr_t>
688 : std::true_type
689 { };
690
691 #ifndef BOOST_NO_CXX17_HDR_VARIANT
692 template<>
693 struct is_null_like<std::monostate>
694 : std::true_type
695 { };
696 #endif // BOOST_NO_CXX17_HDR_VARIANT
697
698 template<class T>
699 struct is_described_class
700 : mp11::mp_and<
701 describe::has_describe_members<T>,
702 mp11::mp_not< std::is_union<T> >,
703 mp11::mp_empty<
704 mp11::mp_eval_or<
705 mp11::mp_list<>, detail::described_non_public_members, T>>>
706 { };
707
708 template<class T>
709 struct is_described_enum
710 : describe::has_describe_enumerators<T>
711 { };
712
713 template<class T>
714 struct is_variant_like : mp11::mp_valid<detail::has_valueless_by_exception, T>
715 { };
716
717 template<class T>
718 struct is_optional_like
719 : mp11::mp_and<
720 mp11::mp_not<std::is_void<
721 mp11::mp_eval_or<void, detail::value_result_type, T>>>,
722 mp11::mp_valid<detail::can_reset, T>>
723 { };
724
725 } // namespace json
726 } // namespace boost
727
728 #endif // BOOST_JSON_IMPL_CONVERSION_HPP
729