1 #pragma once 2 3 #include <iterator> // random_access_iterator_tag 4 5 #include <nlohmann/detail/meta/void_t.hpp> 6 #include <nlohmann/detail/meta/cpp_future.hpp> 7 8 namespace nlohmann 9 { 10 namespace detail 11 { 12 template <typename It, typename = void> 13 struct iterator_types {}; 14 15 template <typename It> 16 struct iterator_types< 17 It, 18 void_t<typename It::difference_type, typename It::value_type, typename It::pointer, 19 typename It::reference, typename It::iterator_category>> { 20 using difference_type = typename It::difference_type; 21 using value_type = typename It::value_type; 22 using pointer = typename It::pointer; 23 using reference = typename It::reference; 24 using iterator_category = typename It::iterator_category; 25 }; 26 27 // This is required as some compilers implement std::iterator_traits in a way that 28 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. 29 template <typename T, typename = void> 30 struct iterator_traits 31 { 32 }; 33 34 template <typename T> 35 struct iterator_traits<T, enable_if_t<!std::is_pointer<T>::value>> 36 : iterator_types<T> 37 { 38 }; 39 40 template <typename T> 41 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>> { 42 using iterator_category = std::random_access_iterator_tag; 43 using value_type = T; 44 using difference_type = ptrdiff_t; 45 using pointer = T*; 46 using reference = T&; 47 }; 48 } // namespace detail 49 } // namespace nlohmann 50