unioil-loyalty-rn-app/ios/Pods/Flipper-Boost-iOSX/boost/json/detail/value_to.hpp

196 lines
4.3 KiB
C++

//
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
// 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_TO_HPP
#define BOOST_JSON_DETAIL_VALUE_TO_HPP
#include <boost/json/value.hpp>
#include <boost/json/detail/value_traits.hpp>
#include <type_traits>
BOOST_JSON_NS_BEGIN
template<class>
struct value_to_tag { };
template<class, class = void>
struct has_value_to;
template<class T, class U,
typename std::enable_if<
! std::is_reference<T>::value &&
std::is_same<U, value>::value>::type>
T value_to(U const&);
namespace detail {
//----------------------------------------------------------
// Use native conversion
// identity conversion
inline
value
tag_invoke(
value_to_tag<value>,
value const& jv)
{
return jv;
}
// object
inline
object
tag_invoke(
value_to_tag<object>,
value const& jv)
{
return jv.as_object();
}
// array
inline
array
tag_invoke(
value_to_tag<array>,
value const& jv)
{
return jv.as_array();
}
// string
inline
string
tag_invoke(
value_to_tag<string>,
value const& jv)
{
return jv.as_string();
}
// bool
inline
bool
tag_invoke(
value_to_tag<bool>,
value const& jv)
{
return jv.as_bool();
}
// integral and floating point
template<class T, typename std::enable_if<
std::is_arithmetic<T>::value>::type* = nullptr>
T
tag_invoke(
value_to_tag<T>,
value const& jv)
{
return jv.to_number<T>();
}
//----------------------------------------------------------
// Use generic conversion
// string-like types
// NOTE: original check for size used is_convertible but
// MSVC-140 selects wrong specialisation if used
template<class T, typename std::enable_if<
std::is_constructible<T, const char*, std::size_t>::value &&
std::is_convertible<decltype(std::declval<T&>().data()), const char*>::value &&
std::is_integral<decltype(std::declval<T&>().size())>::value
>::type* = nullptr>
T
value_to_generic(
const value& jv,
priority_tag<2>)
{
auto& str = jv.as_string();
return T(str.data(), str.size());
}
// map like containers
template<class T, typename std::enable_if<
has_value_to<typename map_traits<T>::pair_value_type>::value &&
std::is_constructible<typename map_traits<T>::pair_key_type,
string_view>::value>::type* = nullptr>
T
value_to_generic(
const value& jv,
priority_tag<1>)
{
using value_type = typename
container_traits<T>::value_type;
const object& obj = jv.as_object();
T result;
container_traits<T>::try_reserve(
result, obj.size());
for (const auto& val : obj)
result.insert(value_type{typename map_traits<T>::
pair_key_type(val.key()), value_to<typename
map_traits<T>::pair_value_type>(val.value())});
return result;
}
// all other containers
template<class T, typename std::enable_if<
has_value_to<typename container_traits<T>::
value_type>::value>::type* = nullptr>
T
value_to_generic(
const value& jv,
priority_tag<0>)
{
const array& arr = jv.as_array();
T result;
container_traits<T>::try_reserve(
result, arr.size());
for (const auto& val : arr)
result.insert(end(result), value_to<typename
container_traits<T>::value_type>(val));
return result;
}
// Matches containers
template<class T, void_t<typename std::enable_if<
!std::is_constructible<T, const value&>::value &&
!std::is_arithmetic<T>::value>::type, decltype(
value_to_generic<T>(std::declval<const value&>(),
priority_tag<2>()))>* = nullptr>
T
tag_invoke(
value_to_tag<T>,
value const& jv)
{
return value_to_generic<T>(
jv, priority_tag<2>());
}
//----------------------------------------------------------
// Calls to value_to are forwarded to this function
// so we can use ADL and hide the built-in tag_invoke
// overloads in the detail namespace
template<class T, void_t<
decltype(tag_invoke(std::declval<value_to_tag<T>&>(),
std::declval<const value&>()))>* = nullptr>
T
value_to_impl(
value_to_tag<T> tag,
value const& jv)
{
return tag_invoke(tag, jv);
}
} // detail
BOOST_JSON_NS_END
#endif