#pragma once #include #include namespace misc { // Concept describing a const Container through which you can iterate // Needs methods begin() and end(). template concept ConstIterable = requires(Container c) { { c.begin() != c.end() } -> std::same_as; { c.begin() } -> std::convertible_to; { *c.begin() } -> std::convertible_to; }; // Concept describing a Container through which you can iterate // Needs methods begin() and end(). template concept Iterable = ConstIterable && requires(Container c) { { c.begin() } -> std::same_as; { *c.begin() } -> std::same_as; }; // Concept discribing a map. // Needs methods lower_bound() and emplace(key, value). template concept Map = requires(M map, const typename M::key_type key, const typename M::mapped_type value, const typename M::iterator i) { { map.lower_bound(key) } -> std::same_as; { map.key_comp() }; { map.emplace(key, value) } -> std::same_as>; requires std::same_as< std::remove_cvref_t, std::pair>; }; // Concept describing a ConstIterable but adds a constraint on the value_type // the held type should be convertible into T template concept ConstIterableType = ConstIterable && std::convertible_to; // Concept describing an Iterable but adds a constraint on the value_type // the held type should be convertible into T template concept IterableType = Iterable && std::convertible_to; // Concept describing an iterator on a type T template concept Iterator = std::forward_iterator && std::same_as; } // namespace misc