recursive_traits.h 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #pragma once
  2. #include <iterator>
  3. #include "traits.h"
  4. namespace iterator::recursive {
  5. // Type deduction guides for constructing recursive iterators.
  6. enum class recursion_type { END, THRU, ASSOC };
  7. // Helpers for condensing type deductions
  8. template <typename It>
  9. using value = decltype(std::begin(*std::declval<It>()));
  10. template <typename It>
  11. using mapped = decltype(std::begin(std::declval<It>()->second));
  12. template <typename T> using val_key_t = typename T::value_type::first_type;
  13. // Type trait to identify value_type ~~ std::pair<K const, V>, which is
  14. // a safe bet towards 'this is an associative container type'
  15. template <typename T, typename = void>
  16. struct is_associative : std::false_type {};
  17. template <typename T>
  18. struct is_associative<T, std::enable_if_t<std::is_const_v<val_key_t<T>>>>
  19. : std::true_type {};
  20. template <typename T, typename = void> struct typeclass_t {
  21. static constexpr recursion_type const value{recursion_type::END};
  22. };
  23. template <typename T> struct is_string_iter : std::false_type {};
  24. template <> struct is_string_iter<std::string::iterator> : std::true_type {};
  25. template <>
  26. struct is_string_iter<std::string::const_iterator> : std::true_type {};
  27. template <typename T> constexpr bool is_string_iter_v = is_string_iter<T>{};
  28. template <typename T>
  29. struct typeclass_t<T, std::enable_if_t<!is_string_iter_v<value<T>>>> {
  30. constexpr static recursion_type value{recursion_type::THRU};
  31. };
  32. template <typename T>
  33. struct typeclass_t<T, std::enable_if_t<is_string_iter_v<value<T>>>> {
  34. constexpr static recursion_type value{recursion_type::END};
  35. };
  36. template <typename T> struct typeclass_t<T, detail::void_t<mapped<T>>> {
  37. constexpr static recursion_type value{recursion_type::ASSOC};
  38. };
  39. }