recursive_iterator_traits.hpp 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. #pragma once
  2. #include <iterator>
  3. #include <tuple>
  4. #include <utility>
  5. namespace iterator { namespace detail {
  6. struct terminal_layer_tag_t;
  7. struct continue_layer_tag_t;
  8. template <typename> struct void_t { using type = void; };
  9. template <typename IterType>
  10. using value_iterator = decltype(std::begin(*std::declval<IterType>()));
  11. template <typename IterType>
  12. using mapped_iterator =
  13. decltype(std::begin(std::declval<IterType>()->second));
  14. /**
  15. * @class next_layer_type
  16. * @breif A template metaprogramming type for unifying associative and
  17. * non-associative containers.
  18. */
  19. template <typename V, typename Tag> struct next_layer_type {
  20. using type = std::tuple<V>;
  21. };
  22. template <typename V> struct next_layer_type<V, continue_layer_tag_t> {
  23. using type = V;
  24. };
  25. template <typename T, typename = void>
  26. struct is_associative : std::false_type {};
  27. template <typename T>
  28. struct is_associative<T, std::enable_if_t<std::is_const<
  29. typename T::value_type::first_type>::value>>
  30. : std::true_type {};
  31. template <typename T>
  32. using is_associative_t = std::enable_if_t<is_associative<T>::value>;
  33. }}