iterator_traits.hpp 1.4 KB

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