| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- #pragma once
- #include <iterator>
- #include <string>
- #include <tuple>
- #include <utility>
- namespace iterator { namespace detail {
- struct terminal_layer_tag_t;
- struct continue_layer_tag_t;
- template <typename> struct void_t { using type = void; };
- template <typename IterType>
- using value_iterator = decltype(std::begin(*std::declval<IterType>()));
- template <typename IterType>
- using mapped_iterator =
- decltype(std::begin(std::declval<IterType>()->second));
- /**
- * @class next_layer_type
- * @breif A template metaprogramming type for unifying associative and
- * non-associative containers.
- */
- template <typename V, typename Tag> struct next_layer_type {
- using type = std::tuple<V>;
- };
- template <typename V> struct next_layer_type<V, continue_layer_tag_t> {
- using type = V;
- };
- template <typename T, typename = void>
- struct is_associative : std::false_type {};
- template <typename T>
- struct is_associative<T, std::enable_if_t<std::is_const<
- typename T::value_type::first_type>::value>>
- : std::true_type {};
- template <typename T>
- using is_associative_t = std::enable_if_t<is_associative<T>::value>;
- /**
- * Type deduction guides for constructing recursive iterators.
- */
- enum class typeclass { TERMINAL, CONTAINER, ASSOCIATIVE_CONTAINER };
- template <typename T, typename = void> struct typeclass_t {
- static constexpr typeclass const value{typeclass::TERMINAL};
- };
- template <>
- struct typeclass_t<typename std::string::iterator> : typeclass_t<void> {};
- template <>
- struct typeclass_t<typename std::string::const_iterator> : typeclass_t<void> {
- };
- template <typename T>
- struct typeclass_t<T, typename void_t<value_iterator<T>>::type> {
- static constexpr typeclass const value{typeclass::CONTAINER};
- };
- template <typename T>
- struct typeclass_t<T, typename void_t<mapped_iterator<T>>::type> {
- static constexpr typeclass const value{typeclass::ASSOCIATIVE_CONTAINER};
- };
- }}
|