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