facade_traits.h 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. //
  2. // facade_traits.h
  3. // iterator
  4. //
  5. // Created by Sam Jaffe on 4/1/23.
  6. // Copyright © 2023 Sam Jaffe. All rights reserved.
  7. //
  8. #pragma once
  9. #include <iterator>
  10. #include <type_traits>
  11. #include <iterator/detail/macro.h>
  12. #include <iterator/detail/traits.h>
  13. namespace iterator::detail {
  14. template <typename, typename = void> struct has_equal_to : std::false_type {};
  15. template <typename T>
  16. struct has_equal_to<T, EXISTS(VAL(T).equal_to(VAL(T)))> : std::true_type {};
  17. template <typename, typename = void>
  18. struct has_distance_to : std::false_type {};
  19. template <typename T>
  20. struct has_distance_to<T, EXISTS(VAL(T).distance_to(VAL(T)))> : std::true_type {
  21. };
  22. template <typename, typename = void>
  23. struct is_advanceable_iterator : std::false_type {};
  24. template <typename T>
  25. struct is_advanceable_iterator<T, EXISTS(VAL(T).advance({}))> : std::true_type {
  26. };
  27. template <typename, typename = void>
  28. struct is_single_pass_iterator : std::false_type {};
  29. template <typename T>
  30. struct is_single_pass_iterator<T, std::void_t<typename T::single_pass_iterator>>
  31. : std::true_type {};
  32. template <typename, typename = void> struct has_increment : std::false_type {};
  33. template <typename T>
  34. struct has_increment<T, EXISTS(VAL(T).increment())> : std::true_type {};
  35. template <typename, typename = void> struct has_decrement : std::false_type {};
  36. template <typename T>
  37. struct has_decrement<T, EXISTS(VAL(T).decrement())> : std::true_type {};
  38. template <typename, typename = void> struct distance_to {
  39. using type = std::ptrdiff_t;
  40. };
  41. template <typename T>
  42. struct distance_to<T, std::enable_if_t<has_distance_to<T>{}>> {
  43. using type = decltype(VAL(T).distance_to(VAL(T)));
  44. };
  45. template <typename T> using distance_to_t = typename distance_to<T>::type;
  46. template <typename T> constexpr bool has_equal_to_v = has_equal_to<T>{};
  47. template <typename T> constexpr bool has_distance_to_v = has_distance_to<T>{};
  48. template <typename T> constexpr bool has_increment_v = has_increment<T>{};
  49. template <typename T> constexpr bool has_decrement_v = has_decrement<T>{};
  50. template <typename T>
  51. constexpr bool is_advanceable_iterator_v = is_advanceable_iterator<T>{};
  52. template <typename It>
  53. constexpr bool is_single_pass_iterator_v = is_single_pass_iterator<It>{};
  54. template <typename It> struct facade_category {
  55. constexpr static bool has_random_access =
  56. has_distance_to_v<It> && is_advanceable_iterator_v<It>;
  57. constexpr static bool has_bidirectional =
  58. has_decrement_v<It> && has_increment_v<It> && has_equal_to_v<It>;
  59. using type = std::conditional_t<
  60. has_random_access, std::random_access_iterator_tag,
  61. std::conditional_t<has_bidirectional, std::bidirectional_iterator_tag,
  62. std::conditional_t<is_single_pass_iterator_v<It>,
  63. std::input_iterator_tag,
  64. std::forward_iterator_tag>>>;
  65. };
  66. template <typename It>
  67. using facade_category_t = typename facade_category<It>::type;
  68. }
  69. #include <iterator/detail/undef.h>