| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- //
- // concepts.h
- // iterator
- //
- // Created by Sam Jaffe on 9/20/25.
- // Copyright © 2025 Sam Jaffe. All rights reserved.
- //
- #pragma once
- #include <concepts>
- namespace iterator {
- template <typename It>
- concept implements_distance_to = requires(It const &it) {
- { it.distance_to(it) } -> std::integral;
- };
- template <typename> struct infer_difference_type {
- using type = std::ptrdiff_t;
- };
- template <implements_distance_to It>
- struct infer_difference_type<It> {
- static const It& _it;
- using type = decltype(_it.distance_to(_it));
- };
- template <typename It>
- using infer_difference_type_t = typename infer_difference_type<It>::type;
- template <typename D, typename It>
- concept difference_type_arg = std::convertible_to<D, infer_difference_type_t<It>>;
- template <typename It>
- struct infer_value_type {
- static const It& _it;
- using type = std::remove_cvref_t<decltype(*_it)>;
- };
- template <typename It>
- requires requires { typename It::value_type; }
- struct infer_value_type<It> {
- using type = typename It::value_type;
- };
- template <typename It>
- using infer_value_type_t = infer_value_type<It>::type;
- template <typename T, typename U> concept not_same_as = not std::same_as<T, U>;
- template <typename It>
- concept has_sentinel = requires(It const &it) {
- { it.as_end() } -> std::same_as<bool>;
- };
- template <typename It>
- concept single_pass = bool(It::single_pass_iterator);
- template <typename It>
- concept forward = requires(It &it) {
- { it.dereference() } -> not_same_as<void>;
- { it.equal_to(it) } -> std::same_as<bool>;
- { it.increment() } -> std::same_as<void>;
- };
- template <typename It>
- concept bidirectional = forward<It> && requires(It &it) {
- { it.decrement() } -> std::same_as<void>;
- };
- template <typename It>
- concept random_access = requires(It &it, infer_difference_type_t<It> offset) {
- { it.dereference() } -> not_same_as<void>;
- { it.equal_to(it) } -> std::same_as<bool>;
- { it.advance(offset) } -> std::same_as<void>;
- };
- }
|