Skip to content

Commit

Permalink
remove now-useless traits. check for is_basic_json where needed
Browse files Browse the repository at this point in the history
  • Loading branch information
theodelrieu committed Sep 7, 2018
1 parent f3dfa0f commit 3f1abad
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 34 deletions.
5 changes: 3 additions & 2 deletions include/nlohmann/detail/conversions/to_json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,8 @@ template <typename BasicJsonType, typename CompatibleArrayType,
CompatibleArrayType>::value and
not is_compatible_object_type<
BasicJsonType, CompatibleArrayType>::value and
not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value,
not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
not is_basic_json<CompatibleArrayType>::value,
int> = 0>
void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
{
Expand All @@ -274,7 +275,7 @@ void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
}

template<typename BasicJsonType, typename CompatibleObjectType,
enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value, int> = 0>
void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
{
external_constructor<value_t::object>::construct(j, obj);
Expand Down
48 changes: 34 additions & 14 deletions include/nlohmann/detail/meta/type_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ using key_type_t = typename T::key_type;
template <typename T>
using value_type_t = typename T::value_type;

template <typename T>
using difference_type_t = typename T::difference_type;

template <typename T>
using pointer_t = typename T::pointer;

template <typename T>
using reference_t = typename T::reference;

template <typename T>
using iterator_category_t = typename T::iterator_category;

template <typename T>
using iterator_t = typename T::iterator;

Expand All @@ -57,6 +69,24 @@ using from_json_function = decltype(T::from_json(std::declval<Args>()...));
// is_ functions //
///////////////////

template <typename T, typename = void>
struct is_iterator_traits : std::false_type {};

template <typename T>
struct is_iterator_traits<std::iterator_traits<T>>
{
private:
using traits = std::iterator_traits<T>;

public:
static constexpr auto value =
is_detected<value_type_t, traits>::value &&
is_detected<difference_type_t, traits>::value &&
is_detected<pointer_t, traits>::value &&
is_detected<iterator_category_t, traits>::value &&
is_detected<reference_t, traits>::value;
};

// source: https://stackoverflow.com/a/37193089/4116453

template <typename T, typename = void>
Expand Down Expand Up @@ -108,15 +138,6 @@ template <typename BasicJsonType, typename CompatibleStringType>
struct is_compatible_string_type
: is_compatible_string_type_impl<BasicJsonType, CompatibleStringType> {};

template<typename BasicJsonType, typename T>
struct is_basic_json_nested_type
{
static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
std::is_same<T, typename BasicJsonType::const_iterator>::value or
std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
};

template <typename BasicJsonType, typename CompatibleArrayType, typename = void>
struct is_compatible_array_type_impl : std::false_type {};

Expand All @@ -126,8 +147,10 @@ struct is_compatible_array_type_impl <
enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
is_detected<iterator_t, CompatibleArrayType>::value >>
{
static constexpr auto value = not(
is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>::value);
// This is needed because json_reverse_iterator has a ::iterator type...
// Therefore it is detected as a CompatibleArrayType.
// The real fix would be to have an Iterable concept.
static constexpr bool value = not is_iterator_traits<std::iterator_traits<CompatibleArrayType>>::value;
};

template <typename BasicJsonType, typename CompatibleArrayType>
Expand Down Expand Up @@ -204,9 +227,6 @@ struct is_compatible_type_impl <
enable_if_t<is_complete_type<CompatibleType>::value >>
{
static constexpr bool value =
not std::is_base_of<std::istream, CompatibleType>::value and
not is_basic_json<CompatibleType>::value and
not is_basic_json_nested_type<BasicJsonType, CompatibleType>::value and
has_to_json<BasicJsonType, CompatibleType>::value;
};

Expand Down
2 changes: 1 addition & 1 deletion include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1243,7 +1243,7 @@ class basic_json
template <typename CompatibleType,
typename U = detail::uncvref_t<CompatibleType>,
detail::enable_if_t<
detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
basic_json(CompatibleType && val) noexcept(noexcept(
JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
std::forward<CompatibleType>(val))))
Expand Down
55 changes: 38 additions & 17 deletions single_include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,18 @@ using key_type_t = typename T::key_type;
template <typename T>
using value_type_t = typename T::value_type;

template <typename T>
using difference_type_t = typename T::difference_type;

template <typename T>
using pointer_t = typename T::pointer;

template <typename T>
using reference_t = typename T::reference;

template <typename T>
using iterator_category_t = typename T::iterator_category;

template <typename T>
using iterator_t = typename T::iterator;

Expand All @@ -417,6 +429,24 @@ using from_json_function = decltype(T::from_json(std::declval<Args>()...));
// is_ functions //
///////////////////

template <typename T, typename = void>
struct is_iterator_traits : std::false_type {};

template <typename T>
struct is_iterator_traits<std::iterator_traits<T>>
{
private:
using traits = std::iterator_traits<T>;

public:
static constexpr auto value =
is_detected<value_type_t, traits>::value &&
is_detected<difference_type_t, traits>::value &&
is_detected<pointer_t, traits>::value &&
is_detected<iterator_category_t, traits>::value &&
is_detected<reference_t, traits>::value;
};

// source: https://stackoverflow.com/a/37193089/4116453

template <typename T, typename = void>
Expand Down Expand Up @@ -468,15 +498,6 @@ template <typename BasicJsonType, typename CompatibleStringType>
struct is_compatible_string_type
: is_compatible_string_type_impl<BasicJsonType, CompatibleStringType> {};

template<typename BasicJsonType, typename T>
struct is_basic_json_nested_type
{
static auto constexpr value = std::is_same<T, typename BasicJsonType::iterator>::value or
std::is_same<T, typename BasicJsonType::const_iterator>::value or
std::is_same<T, typename BasicJsonType::reverse_iterator>::value or
std::is_same<T, typename BasicJsonType::const_reverse_iterator>::value;
};

template <typename BasicJsonType, typename CompatibleArrayType, typename = void>
struct is_compatible_array_type_impl : std::false_type {};

Expand All @@ -486,8 +507,10 @@ struct is_compatible_array_type_impl <
enable_if_t<is_detected<value_type_t, CompatibleArrayType>::value and
is_detected<iterator_t, CompatibleArrayType>::value >>
{
static constexpr auto value = not(
is_basic_json_nested_type<BasicJsonType, CompatibleArrayType>::value);
// This is needed because json_reverse_iterator has a ::iterator type...
// Therefore it is detected as a CompatibleArrayType.
// The real fix would be to have an Iterable concept.
static constexpr bool value = not is_iterator_traits<std::iterator_traits<CompatibleArrayType>>::value;
};

template <typename BasicJsonType, typename CompatibleArrayType>
Expand Down Expand Up @@ -564,9 +587,6 @@ struct is_compatible_type_impl <
enable_if_t<is_complete_type<CompatibleType>::value >>
{
static constexpr bool value =
not std::is_base_of<std::istream, CompatibleType>::value and
not is_basic_json<CompatibleType>::value and
not is_basic_json_nested_type<BasicJsonType, CompatibleType>::value and
has_to_json<BasicJsonType, CompatibleType>::value;
};

Expand Down Expand Up @@ -1752,7 +1772,8 @@ template <typename BasicJsonType, typename CompatibleArrayType,
CompatibleArrayType>::value and
not is_compatible_object_type<
BasicJsonType, CompatibleArrayType>::value and
not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value,
not is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value and
not is_basic_json<CompatibleArrayType>::value,
int> = 0>
void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
{
Expand All @@ -1773,7 +1794,7 @@ void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
}

template<typename BasicJsonType, typename CompatibleObjectType,
enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value, int> = 0>
enable_if_t<is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value and not is_basic_json<CompatibleObjectType>::value, int> = 0>
void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
{
external_constructor<value_t::object>::construct(j, obj);
Expand Down Expand Up @@ -12292,7 +12313,7 @@ class basic_json
template <typename CompatibleType,
typename U = detail::uncvref_t<CompatibleType>,
detail::enable_if_t<
detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
not detail::is_basic_json<U>::value and detail::is_compatible_type<basic_json_t, U>::value, int> = 0>
basic_json(CompatibleType && val) noexcept(noexcept(
JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
std::forward<CompatibleType>(val))))
Expand Down

0 comments on commit 3f1abad

Please sign in to comment.