diff --git a/include/nlohmann/detail/iterators/iterator_traits.hpp b/include/nlohmann/detail/iterators/iterator_traits.hpp index 43603988e..607dd49ae 100644 --- a/include/nlohmann/detail/iterators/iterator_traits.hpp +++ b/include/nlohmann/detail/iterators/iterator_traits.hpp @@ -3,16 +3,17 @@ #include // random_access_iterator_tag #include +#include namespace nlohmann { namespace detail { -template -struct _iterator_types {}; +template +struct iterator_types {}; -template -struct _iterator_types< +template +struct iterator_types< It, void_t> { @@ -23,25 +24,26 @@ struct _iterator_types< using iterator_category = typename It::iterator_category; }; -template -struct iterator_traits : _iterator_types {}; +// This is required as some compilers implement std::iterator_traits in a way that +// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. +template +struct iterator_traits +{ +}; -template -struct iterator_traits { +template +struct iterator_traits::value>> + : iterator_types +{ +}; + +template +struct iterator_traits::value>> { typedef std::random_access_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef T& reference; }; - -template -struct iterator_traits { - 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/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 8ef906d68..24ff17b8b 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -344,16 +344,18 @@ template using void_t = typename make_void::type; } // namespace detail } // namespace nlohmann +// #include + namespace nlohmann { namespace detail { -template -struct _iterator_types {}; +template +struct iterator_types {}; -template -struct _iterator_types < +template +struct iterator_types < It, void_t> @@ -365,11 +367,21 @@ struct _iterator_types < using iterator_category = typename It::iterator_category; }; -template -struct iterator_traits : _iterator_types {}; +// This is required due to https://github.com/nlohmann/json/issues/1341 - where some +// compilers implement std::iterator_traits in a way that doesn't work with SFINAE. +template +struct iterator_traits +{ +}; -template -struct iterator_traits +template +struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> + : iterator_types +{ +}; + +template +struct iterator_traits::value>> { typedef std::random_access_iterator_tag iterator_category; typedef T value_type; @@ -377,16 +389,6 @@ struct iterator_traits typedef T* pointer; typedef T& reference; }; - -template -struct iterator_traits -{ - 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