Templa 0.0.1-alpha
C++ Metaprogramming Utilities
Loading...
Searching...
No Matches
concepts.hpp
Go to the documentation of this file.
1#pragma once
2#include <iostream>
6
11namespace templa::concepts
12{
13
21 template <typename T>
22 concept Hashable = requires(T x) {
23 { std::hash<T>{}(x) } -> std::convertible_to<std::size_t>;
24 };
25
33 template <typename T>
34 concept Integral = std::is_integral_v<T>;
35
44 template <typename F, typename... T>
45 concept CallableWith = requires(F f, T &&...t) {
46 { f(std::forward<T>(t)...) };
47 };
48
56 template <typename T>
57 concept Comparable = requires(T a, T b) {
58 { a < b };
59 { a == b };
60 { a > b };
61 { a != b };
62 { a >= b };
63 { a <= b };
64 };
65
73 template <typename T>
74 concept UnsignedIntegral = std::is_unsigned_v<T> && std::is_integral_v<T>;
75
83 template <typename T>
84 concept SignedIntegral = std::is_signed_v<T> && std::is_integral_v<T>;
85
93 template <typename T>
94 concept Addable = requires(T a, T b) {
95 { a + b };
96 { a += b };
97 };
98
106 template <typename T>
107 concept Subtractable = requires(T a, T b) {
108 { a - b };
109 { a -= b };
110 };
111
119 template <typename T>
120 concept Multipliable = requires(T a, T b) {
121 { a * b };
122 { a *= b };
123 };
124
132 template <typename T>
133 concept Divisible = requires(T a, T b) {
134 { a / b };
135 { a /= b };
136 };
137
145 template <typename T>
147
155 template <typename T>
156 concept Streamable = requires(std::ostream &os, T t) {
157 { os << t };
158 };
159
165 template <class E>
166 concept DefaultErasable = requires(E *p) {
167 std::destroy_at(p);
168 };
169
179 template <class E, class T, class A>
180 concept AllocatorErasable = requires(A m, E *p) {
181 requires std::same_as<typename T::allocator_type, typename std::allocator_traits<A>::rebind_alloc<E>>;
182 std::allocator_traits<A>::destroy(m, p);
183 };
184
190 template <class T>
191 concept AllocatorAware = requires(T a) {
192 { a.get_allocator() } -> std::same_as<typename T::allocator_type>;
193 };
194
202 template <class T>
203 struct is_basic_string : std::false_type
204 {
205 };
206
207 template <class C, class T, class A>
208 struct is_basic_string<std::basic_string<C, T, A>> : std::true_type
209 {
210 };
211
215 template <class T>
217
229 template <class E, class T>
231
244 template <class T>
245 concept Container = requires(T a, const T b) {
246 requires std::regular<T>;
247 requires std::swappable<T>;
249 requires std::same_as<typename T::reference, typename T::value_type &>;
250 requires std::same_as<typename T::const_reference, const typename T::value_type &>;
251 requires std::forward_iterator<typename T::iterator>;
252 requires std::forward_iterator<typename T::const_iterator>;
253 requires std::signed_integral<typename T::difference_type>;
254 requires std::same_as<typename T::difference_type, typename std::iterator_traits<typename T::iterator>::difference_type>;
255 requires std::same_as<typename T::difference_type, typename std::iterator_traits<typename T::const_iterator>::difference_type>;
256 { a.begin() } -> std::same_as<typename T::iterator>;
257 { a.end() } -> std::same_as<typename T::iterator>;
258 { b.begin() } -> std::same_as<typename T::const_iterator>;
259 { b.end() } -> std::same_as<typename T::const_iterator>;
260 { a.cbegin() } -> std::same_as<typename T::const_iterator>;
261 { a.cend() } -> std::same_as<typename T::const_iterator>;
262 { a.size() } -> std::same_as<typename T::size_type>;
263 { a.max_size() } -> std::same_as<typename T::size_type>;
264 { a.empty() } -> std::convertible_to<bool>;
265 };
266
285 template <class T, template <typename...> class Template>
286 concept is_specialization_of = requires(T const &t) {
287 []<typename... Args>(Template<Args...> const &)
288 { return true; }(t);
289 };
290
305 template <bool... Cs>
306 concept requires_all = (Cs && ...);
307
308}
constexpr bool is_basic_string_v
Variable template shortcut for is_basic_string.
Definition concepts.hpp:216
Concept to check if a type supports addition operations.
Definition concepts.hpp:94
Concept checking if a type has a get_allocator() method returning allocator_type.
Definition concepts.hpp:191
Concept checking if an object can be destroyed via an allocator.
Definition concepts.hpp:180
Concept to check if a type supports all basic arithmetic operations.
Definition concepts.hpp:146
Concept to check if a callable can be invoked with given argument types.
Definition concepts.hpp:45
Concept to check if a type supports common comparison operators.
Definition concepts.hpp:57
Concept that models an STL-like container.
Definition concepts.hpp:245
Concept checking if an object can be destroyed via std::destroy_at.
Definition concepts.hpp:166
Concept to check if a type supports division operations.
Definition concepts.hpp:133
Concept to check if a container supports erasing of elements.
Definition concepts.hpp:230
Concept to check if a type is hashable via std::hash.
Definition concepts.hpp:22
Concept to check if a type is an integral type.
Definition concepts.hpp:34
Concept to check if a type supports multiplication operations.
Definition concepts.hpp:120
Concept to check if a type is a signed integral type.
Definition concepts.hpp:84
Concept to check if a type can be streamed to an std::ostream.
Definition concepts.hpp:156
Concept to check if a type supports subtraction operations.
Definition concepts.hpp:107
Concept to check if a type is an unsigned integral type.
Definition concepts.hpp:74
Checks whether a given type T is a specialization of the class template Template.
Definition concepts.hpp:286
Concept satisfied only if all boolean conditions are true.
Definition concepts.hpp:306
Helper struct to detect if a type is std::basic_string.
Definition concepts.hpp:204