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 { 21 using difference_type = typename It::difference_type; 22 using value_type = typename It::value_type; 23 using pointer = typename It::pointer; 24 using reference = typename It::reference; 25 using iterator_category = typename It::iterator_category; 26 }; 27 28 // This is required as some compilers implement std::iterator_traits in a way that 29 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. 30 template<typename T, typename = void> 31 struct iterator_traits 32 { 33 }; 34 35 template<typename T> 36 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >> 37 : iterator_types<T> 38 { 39 }; 40 41 template<typename T> 42 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>> 43 { 44 using iterator_category = std::random_access_iterator_tag; 45 using value_type = T; 46 using difference_type = ptrdiff_t; 47 using pointer = T*; 48 using reference = T&; 49 }; 50 } // namespace detail 51 } // namespace nlohmann 52