#pragma once #include #include "traits.h" namespace iterator::recursive { // Type deduction guides for constructing recursive iterators. enum class recursion_type { END, THRU, ASSOC }; // Helpers for condensing type deductions template using value = decltype(std::begin(*std::declval())); template using mapped = decltype(std::begin(std::declval()->second)); template using val_key_t = typename T::value_type::first_type; // Type trait to identify value_type ~~ std::pair, which is // a safe bet towards 'this is an associative container type' template struct is_associative : std::false_type {}; template struct is_associative>>> : std::true_type {}; template struct typeclass_t { static constexpr recursion_type const value{recursion_type::END}; }; template struct is_string_iter : std::false_type {}; template <> struct is_string_iter : std::true_type {}; template <> struct is_string_iter : std::true_type {}; template constexpr bool is_string_iter_v = is_string_iter{}; template struct typeclass_t>>> { constexpr static recursion_type value{recursion_type::THRU}; }; template struct typeclass_t>>> { constexpr static recursion_type value{recursion_type::END}; }; template struct typeclass_t>> { constexpr static recursion_type value{recursion_type::ASSOC}; }; }