diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp index 79a19c17..1d549ecc 100644 --- a/include/nlohmann/detail/input/input_adapters.hpp +++ b/include/nlohmann/detail/input/input_adapters.hpp @@ -331,7 +331,7 @@ class input_adapter /// input adapter for iterator range with contiguous storage template<class IteratorType, typename std::enable_if< - std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value, + std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value, int>::type = 0> input_adapter(IteratorType first, IteratorType last) { @@ -350,7 +350,7 @@ class input_adapter // assertion to check that each element is 1 byte long static_assert( - sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1, + sizeof(typename iterator_traits<IteratorType>::value_type) == 1, "each element in the iterator range must have the size of 1 byte"); const auto len = static_cast<size_t>(std::distance(first, last)); @@ -374,7 +374,7 @@ class input_adapter /// input adapter for contiguous container template<class ContiguousContainer, typename std::enable_if<not std::is_pointer<ContiguousContainer>::value and - std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value, + std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value, int>::type = 0> input_adapter(const ContiguousContainer& c) : input_adapter(std::begin(c), std::end(c)) {} diff --git a/include/nlohmann/detail/iterators/iterator_traits.hpp b/include/nlohmann/detail/iterators/iterator_traits.hpp new file mode 100644 index 00000000..43603988 --- /dev/null +++ b/include/nlohmann/detail/iterators/iterator_traits.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include <iterator> // random_access_iterator_tag + +#include <nlohmann/detail/meta/void_t.hpp> + +namespace nlohmann +{ +namespace detail +{ +template <class It, class = void> +struct _iterator_types {}; + +template <class It> +struct _iterator_types< + It, + void_t<typename It::difference_type, typename It::value_type, typename It::pointer, + typename It::reference, typename It::iterator_category>> { + using difference_type = typename It::difference_type; + using value_type = typename It::value_type; + using pointer = typename It::pointer; + using reference = typename It::reference; + using iterator_category = typename It::iterator_category; +}; + +template <class Iter> +struct iterator_traits : _iterator_types<Iter> {}; + +template <class T> +struct iterator_traits<T*> { + typedef std::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef T* pointer; + typedef T& reference; +}; + +template <class T> +struct iterator_traits<const T*> { + typedef std::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef const T* pointer; + typedef const T& reference; +}; +} +} \ No newline at end of file diff --git a/include/nlohmann/detail/meta/type_traits.hpp b/include/nlohmann/detail/meta/type_traits.hpp index d901f1e0..ee04da22 100644 --- a/include/nlohmann/detail/meta/type_traits.hpp +++ b/include/nlohmann/detail/meta/type_traits.hpp @@ -6,6 +6,7 @@ #include <utility> // declval #include <nlohmann/json_fwd.hpp> +#include <nlohmann/detail/iterators/iterator_traits.hpp> #include <nlohmann/detail/meta/cpp_future.hpp> #include <nlohmann/detail/meta/detected.hpp> #include <nlohmann/detail/macro_scope.hpp> @@ -131,10 +132,10 @@ template <typename T, typename = void> struct is_iterator_traits : std::false_type {}; template <typename T> -struct is_iterator_traits<std::iterator_traits<T>> +struct is_iterator_traits<iterator_traits<T>> { private: - using traits = std::iterator_traits<T>; + using traits = iterator_traits<T>; public: static constexpr auto value = @@ -251,7 +252,7 @@ struct is_compatible_array_type_impl < // Therefore it is detected as a CompatibleArrayType. // The real fix would be to have an Iterable concept. not is_iterator_traits< - std::iterator_traits<CompatibleArrayType>>::value >> + iterator_traits<CompatibleArrayType>>::value >> { static constexpr bool value = std::is_constructible<BasicJsonType, @@ -288,7 +289,7 @@ struct is_constructible_array_type_impl < // Therefore it is detected as a ConstructibleArrayType. // The real fix would be to have an Iterable concept. not is_iterator_traits < - std::iterator_traits<ConstructibleArrayType >>::value and + iterator_traits<ConstructibleArrayType >>::value and (std::is_same<typename ConstructibleArrayType::value_type, typename BasicJsonType::array_t::value_type>::value or has_from_json<BasicJsonType, diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 30e69895..cbb00e03 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -41,7 +41,7 @@ SOFTWARE. #include <functional> // hash, less #include <initializer_list> // initializer_list #include <iosfwd> // istream, ostream -#include <iterator> // iterator_traits, random_access_iterator_tag +#include <iterator> // random_access_iterator_tag #include <numeric> // accumulate #include <string> // string, stoi, to_string #include <utility> // declval, forward, move, pair, swap diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 1e7cf51e..8ef906d6 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -41,7 +41,7 @@ SOFTWARE. #include <functional> // hash, less #include <initializer_list> // initializer_list #include <iosfwd> // istream, ostream -#include <iterator> // iterator_traits, random_access_iterator_tag +#include <iterator> // random_access_iterator_tag #include <numeric> // accumulate #include <string> // string, stoi, to_string #include <utility> // declval, forward, move, pair, swap @@ -324,12 +324,10 @@ constexpr T static_const<T>::value; // #include <nlohmann/json_fwd.hpp> -// #include <nlohmann/detail/meta/cpp_future.hpp> - -// #include <nlohmann/detail/meta/detected.hpp> +// #include <nlohmann/detail/iterators/iterator_traits.hpp> -#include <type_traits> +#include <iterator> // random_access_iterator_tag // #include <nlohmann/detail/meta/void_t.hpp> @@ -347,6 +345,60 @@ template <typename ...Ts> using void_t = typename make_void<Ts...>::type; } // namespace nlohmann +namespace nlohmann +{ +namespace detail +{ +template <class It, class = void> +struct _iterator_types {}; + +template <class It> +struct _iterator_types < + It, + void_t<typename It::difference_type, typename It::value_type, typename It::pointer, + typename It::reference, typename It::iterator_category >> +{ + using difference_type = typename It::difference_type; + using value_type = typename It::value_type; + using pointer = typename It::pointer; + using reference = typename It::reference; + using iterator_category = typename It::iterator_category; +}; + +template <class Iter> +struct iterator_traits : _iterator_types<Iter> {}; + +template <class T> +struct iterator_traits<T*> +{ + typedef std::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef T* pointer; + typedef T& reference; +}; + +template <class T> +struct iterator_traits<const T*> +{ + typedef std::random_access_iterator_tag iterator_category; + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef const T* pointer; + typedef const T& reference; +}; +} +} +// #include <nlohmann/detail/meta/cpp_future.hpp> + +// #include <nlohmann/detail/meta/detected.hpp> + + +#include <type_traits> + +// #include <nlohmann/detail/meta/void_t.hpp> + + // http://en.cppreference.com/w/cpp/experimental/is_detected namespace nlohmann { @@ -522,10 +574,10 @@ template <typename T, typename = void> struct is_iterator_traits : std::false_type {}; template <typename T> -struct is_iterator_traits<std::iterator_traits<T>> +struct is_iterator_traits<iterator_traits<T>> { private: - using traits = std::iterator_traits<T>; + using traits = iterator_traits<T>; public: static constexpr auto value = @@ -642,7 +694,7 @@ struct is_compatible_array_type_impl < // Therefore it is detected as a CompatibleArrayType. // The real fix would be to have an Iterable concept. not is_iterator_traits< - std::iterator_traits<CompatibleArrayType>>::value >> + iterator_traits<CompatibleArrayType>>::value >> { static constexpr bool value = std::is_constructible<BasicJsonType, @@ -679,7 +731,7 @@ struct is_constructible_array_type_impl < // Therefore it is detected as a ConstructibleArrayType. // The real fix would be to have an Iterable concept. not is_iterator_traits < - std::iterator_traits<ConstructibleArrayType >>::value and + iterator_traits<ConstructibleArrayType >>::value and (std::is_same<typename ConstructibleArrayType::value_type, typename BasicJsonType::array_t::value_type>::value or has_from_json<BasicJsonType, @@ -2380,7 +2432,7 @@ class input_adapter /// input adapter for iterator range with contiguous storage template<class IteratorType, typename std::enable_if< - std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value, + std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value, int>::type = 0> input_adapter(IteratorType first, IteratorType last) { @@ -2399,7 +2451,7 @@ class input_adapter // assertion to check that each element is 1 byte long static_assert( - sizeof(typename std::iterator_traits<IteratorType>::value_type) == 1, + sizeof(typename iterator_traits<IteratorType>::value_type) == 1, "each element in the iterator range must have the size of 1 byte"); const auto len = static_cast<size_t>(std::distance(first, last)); @@ -2423,7 +2475,7 @@ class input_adapter /// input adapter for contiguous container template<class ContiguousContainer, typename std::enable_if<not std::is_pointer<ContiguousContainer>::value and - std::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value, + std::is_base_of<std::random_access_iterator_tag, typename iterator_traits<decltype(std::begin(std::declval<ContiguousContainer const>()))>::iterator_category>::value, int>::type = 0> input_adapter(const ContiguousContainer& c) : input_adapter(std::begin(c), std::end(c)) {}