| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- //
- // facade_traits.h
- // iterator
- //
- // Created by Sam Jaffe on 4/1/23.
- // Copyright © 2023 Sam Jaffe. All rights reserved.
- //
- #pragma once
- #include <iterator>
- #include <type_traits>
- #include <iterator/detail/traits.h>
- #define _val(type) std::declval<type>()
- #define exists(expr) std::void_t<decltype(expr)>
- namespace iterator::detail {
- template <typename, typename = void> struct has_equal_to : std::false_type {};
- template <typename T>
- struct has_equal_to<T, exists(_val(T).equal_to(_val(T)))> : std::true_type {};
- template <typename, typename = void>
- struct has_distance_to : std::false_type {};
- template <typename T>
- struct has_distance_to<T, exists(_val(T).distance_to(_val(T)))>
- : std::true_type {};
- template <typename, typename = void>
- struct is_advanceable_iterator : std::false_type {};
- template <typename T>
- struct is_advanceable_iterator<T, exists(_val(T).advance({}))>
- : std::true_type {};
- template <typename, typename = void>
- struct is_single_pass_iterator : std::false_type {};
- template <typename T>
- struct is_single_pass_iterator<T, std::void_t<typename T::single_pass_iterator>>
- : std::true_type {};
- template <typename, typename = void> struct has_increment : std::false_type {};
- template <typename T>
- struct has_increment<T, exists(_val(T).increment())> : std::true_type {};
- template <typename, typename = void> struct has_decrement : std::false_type {};
- template <typename T>
- struct has_decrement<T, exists(_val(T).decrement())> : std::true_type {};
- template <typename, typename = void> struct distance_to {
- using type = std::ptrdiff_t;
- };
- template <typename T>
- struct distance_to<T, std::enable_if_t<has_distance_to<T>{}>> {
- using type = decltype(_val(T).distance_to(_val(T)));
- };
- template <typename T> using distance_to_t = typename distance_to<T>::type;
- template <typename T> constexpr bool has_equal_to_v = has_equal_to<T>{};
- template <typename T> constexpr bool has_distance_to_v = has_distance_to<T>{};
- template <typename T> constexpr bool has_increment_v = has_increment<T>{};
- template <typename T> constexpr bool has_decrement_v = has_decrement<T>{};
- template <typename T>
- constexpr bool is_advanceable_iterator_v = is_advanceable_iterator<T>{};
- template <typename It>
- constexpr bool is_single_pass_iterator_v = is_single_pass_iterator<It>{};
- template <typename It> struct facade_category {
- constexpr static bool has_random_access =
- has_distance_to_v<It> && is_advanceable_iterator_v<It>;
- constexpr static bool has_bidirectional =
- has_decrement_v<It> && has_increment_v<It> && has_equal_to_v<It>;
- using type = std::conditional_t<
- has_random_access, std::random_access_iterator_tag,
- std::conditional_t<has_bidirectional, std::bidirectional_iterator_tag,
- std::conditional_t<is_single_pass_iterator_v<It>,
- std::input_iterator_tag,
- std::forward_iterator_tag>>>;
- };
- template <typename It>
- using facade_category_t = typename facade_category<It>::type;
- }
|