1
0
mirror of https://github.com/nlohmann/json.git synced 2025-07-13 20:21:48 +03:00

anonymous namespace renamed to detail

This commit is contained in:
Théo DELRIEU
2016-10-17 23:41:53 +02:00
committed by Théo DELRIEU
parent b443edf49e
commit fe628b585b
2 changed files with 292 additions and 19 deletions

View File

@ -106,6 +106,14 @@ SOFTWARE.
*/
namespace nlohmann
{
// TODO add real documentation before PR
// Traits structure declaration, users can specialize it for their own types
//
// constructing a json object from a user-defined type will call the
// 'json to_json(T)' function
//
// whereas calling json::get<T> will call 'T from_json(json const&)'
template <typename T, typename = void>
struct json_traits;
@ -113,8 +121,8 @@ struct json_traits;
@brief unnamed namespace with internal helper functions
@since version 1.0.0
*/
// TODO transform this anon ns to detail?
namespace
namespace detail
{
/*!
@brief Helper to determine whether there's a key_type for T.
@ -140,6 +148,7 @@ struct has_mapped_type
};
// taken from http://stackoverflow.com/questions/10711952/how-to-detect-existence-of-a-class-using-sfinae
// used to determine if json_traits is defined for a given type T
template <typename T>
struct has_destructor
{
@ -158,7 +167,23 @@ struct has_json_traits
static constexpr bool value = has_destructor<json_traits<T>>::value;
};
template <> struct has_json_traits<void> : std::false_type {};
struct to_json_fn
{
template <typename T>
constexpr auto operator()(T&& val) const -> decltype(to_json(std::forward<T>(val)))
{
return to_json(std::forward<T>(val));
}
};
struct from_json_fn
{
template <typename Json, typename T>
constexpr auto operator()(Json const& from, T& to) const -> decltype(from_json(from, to))
{
return from_json(from, to);
}
};
/*!
@brief helper class to create locales with decimal point
@ -181,6 +206,23 @@ struct DecimalSeparator : std::numpunct<char>
};
// taken from ranges-v3
// TODO add doc
template <typename T>
struct __static_const
{
static constexpr T value{};
};
template <typename T>
constexpr T __static_const<T>::value;
inline namespace
{
constexpr auto const& to_json = __static_const<detail::to_json_fn>::value;
constexpr auto const& from_json = __static_const<detail::from_json_fn>::value;
}
/*!
@brief a class to store JSON values
@ -1337,10 +1379,24 @@ class basic_json
assert_invariant();
}
// constructor chosen if json_traits is specialized for type T
// note: constructor is marked explicit to avoid the following issue:
//
// struct not_equality_comparable{};
//
// not_equality_comparable{} == not_equality_comparable{};
//
// this will construct implicitely 2 json objects and call operator== on them
// which can cause nasty bugs on the user's in json-unrelated code
//
// the trade-off is expressivety in initializer-lists
// auto j = json{{"a", json(not_equality_comparable{})}};
//
// we can remove this constraint though, since lots of ctor are not explicit already
template <
typename T,
typename =
typename std::enable_if<has_json_traits<typename std::remove_cv<
typename std::enable_if<detail::has_json_traits<typename std::remove_cv<
typename std::remove_reference<T>::type>::type>::value>::type>
explicit basic_json(T &&val)
: basic_json(json_traits<typename std::remove_cv<
@ -2705,10 +2761,13 @@ class basic_json
// value access //
//////////////////
// get_impl overload chosen if json_traits struct is specialized for type T
// simply returns json_traits<T>::from_json(*this);
// TODO add alias templates (enable_if_t etc)
template <
typename T,
typename =
typename std::enable_if<has_json_traits<typename std::remove_cv<
typename = typename std::enable_if<
detail::has_json_traits<typename std::remove_cv<
typename std::remove_reference<T>::type>::type>::value>::type>
auto get_impl(T *) const -> decltype(
json_traits<typename std::remove_cv<typename std::remove_reference<
@ -2717,6 +2776,24 @@ class basic_json
typename std::remove_reference<T>::type>::type>::from_json(*this);
}
// this one is quite atrocious
// this overload is chosen ONLY if json_traits struct is not specialized, and if the expression nlohmann::from_json(*this, T&) is valid
// I chose to prefer the json_traits specialization if it exists, since it's a more advanced use.
// But we can of course change this behaviour
template <typename T>
auto get_impl(T *) const -> typename std::enable_if<
not detail::has_json_traits<typename std::remove_cv<T>::type>::value,
typename std::remove_cv<typename std::remove_reference<
decltype(::nlohmann::from_json(std::declval<basic_json>(),
std::declval<T &>()),
std::declval<T>())>::type>::type>::type
{
typename std::remove_cv<typename std::remove_reference<T>::type>::type
ret;
::nlohmann::from_json(*this, ret);
return ret;
}
/// get an object (explicit)
template <class T,
typename std::enable_if<
@ -2750,7 +2827,7 @@ class basic_json
not std::is_same<basic_json_t, typename T::value_type>::value and
not std::is_arithmetic<T>::value and
not std::is_convertible<std::string, T>::value and
not has_mapped_type<T>::value, int>::type = 0>
not detail::has_mapped_type<T>::value, int>::type = 0>
T get_impl(T* /*unused*/) const
{
if (is_array())
@ -2791,7 +2868,7 @@ class basic_json
/// get an array (explicit)
template<class T, typename std::enable_if<
std::is_same<basic_json, typename T::value_type>::value and
not has_mapped_type<T>::value, int>::type = 0>
not detail::has_mapped_type<T>::value, int>::type = 0>
T get_impl(T* /*unused*/) const
{
if (is_array())