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