// // facade_traits.h // iterator // // Created by Sam Jaffe on 4/1/23. // Copyright © 2023 Sam Jaffe. All rights reserved. // #pragma once #include #include #include #include namespace iterator::detail { template struct has_equal_to : std::false_type {}; template struct has_equal_to : std::true_type {}; template struct has_distance_to : std::false_type {}; template struct has_distance_to : std::true_type { }; template struct is_advanceable_iterator : std::false_type {}; template struct is_advanceable_iterator : std::true_type { }; template struct is_single_pass_iterator : std::false_type {}; template struct is_single_pass_iterator> : std::true_type {}; template struct has_increment : std::false_type {}; template struct has_increment : std::true_type {}; template struct has_decrement : std::false_type {}; template struct has_decrement : std::true_type {}; template struct distance_to { using type = std::ptrdiff_t; }; template struct distance_to{}>> { using type = decltype(VAL(T).distance_to(VAL(T))); }; template using distance_to_t = typename distance_to::type; template constexpr bool has_equal_to_v = has_equal_to{}; template constexpr bool has_distance_to_v = has_distance_to{}; template constexpr bool has_increment_v = has_increment{}; template constexpr bool has_decrement_v = has_decrement{}; template constexpr bool is_advanceable_iterator_v = is_advanceable_iterator{}; template constexpr bool is_single_pass_iterator_v = is_single_pass_iterator{}; template struct facade_category { constexpr static bool has_random_access = has_distance_to_v && is_advanceable_iterator_v; constexpr static bool has_bidirectional = has_decrement_v && has_increment_v && has_equal_to_v; using type = std::conditional_t< has_random_access, std::random_access_iterator_tag, std::conditional_t, std::input_iterator_tag, std::forward_iterator_tag>>>; }; template using facade_category_t = typename facade_category::type; } #include