FlatImage
A configurable Linux containerization system
Loading...
Searching...
No Matches
concept.hpp
Go to the documentation of this file.
1
12
13#pragma once
14
15#include <string>
16#include <type_traits>
17#include <variant>
18#include <vector>
19#include <optional>
20#include <ranges>
21#include <deque>
22#include <list>
23#include <set>
24#include <map>
25#include <unordered_set>
26#include <unordered_map>
27#include <memory>
28
37namespace ns_concept
38{
39
40// ============================================================================
41// Template Metaprogramming Utilities
42// ============================================================================
43
49template<typename T, template<typename...> typename U>
50inline constexpr bool is_instance_of_v = std::false_type {};
51
57template<template<typename...> typename U, typename... Args>
58inline constexpr bool is_instance_of_v<U<Args...>,U> = std::true_type {};
59
71template<typename T, template<typename...> typename U>
73
74static_assert(!IsInstanceOf<std::vector<int>*, std::vector>);
75static_assert( IsInstanceOf<std::vector<int>&, std::vector>);
76static_assert( IsInstanceOf<std::vector<int> const&, std::vector>);
77static_assert( IsInstanceOf<std::vector<int>, std::vector>);
78static_assert( IsInstanceOf<std::vector<std::string>, std::vector>);
80static_assert( IsInstanceOf<std::optional<int>, std::optional>);
81
82// ============================================================================
83// Boolean and Logical Concepts
84// ============================================================================
85
102template<typename T>
103concept Boolean = std::convertible_to<std::remove_cvref_t<T>, bool>
104&& requires(T t)
105{
106 { !t } -> std::convertible_to<bool>;
107};
108
109static_assert( Boolean<bool const&>);
110static_assert( Boolean<bool &>);
111static_assert( Boolean<int const&>);
112static_assert( Boolean<int &>);
113static_assert( Boolean<void*>);
114static_assert(!Boolean<std::string>);
115static_assert(!Boolean<std::vector<int>>);
116
117// ============================================================================
118// Enum Concepts
119// ============================================================================
120
133template<typename T>
134concept Enum = std::is_enum_v<T>;
135
136enum TestEnum { VALUE1, VALUE2 };
137enum class TestEnumClass { VALUE1, VALUE2 };
138static_assert( Enum<TestEnum>);
139static_assert( Enum<TestEnumClass>);
140static_assert(!Enum<int>);
141static_assert(!Enum<std::string>);
142
149template<typename T>
150concept ScopedEnum = Enum<T> && !std::is_convertible_v<T, std::underlying_type_t<T>>;
151
152static_assert(!ScopedEnum<TestEnum>);
153static_assert( ScopedEnum<TestEnumClass>);
154
155// ============================================================================
156// Variant Concepts
157// ============================================================================
158
171template <typename T, typename... Args>
173
175static_assert( Variant<std::variant<int>>);
176static_assert(!Variant<int>);
177static_assert(!Variant<std::optional<int>>);
178
179// ============================================================================
180// Type Equality Concepts
181// ============================================================================
182
197template<typename T, typename... U>
198concept Uniform = ( std::same_as<std::remove_cvref_t<T>, std::remove_cvref_t<U>> and ... );
199
200static_assert( Uniform<int, int>);
201static_assert(!Uniform<int, long>);
202static_assert(!Uniform<int, int, long, short>);
203static_assert( Uniform<const int&, int>);
204static_assert(!Uniform<int, std::string>);
206
207// ============================================================================
208// Iterator and Range Concepts
209// ============================================================================
210
226template<typename T>
227concept Iterable = std::ranges::range<T>;
228
229static_assert( Iterable<std::vector<int>>);
230static_assert( Iterable<std::string>);
231static_assert( Iterable<int[5]>);
232static_assert(!Iterable<int>);
233static_assert(!Iterable<void*>);
234
235// ============================================================================
236// Container Concepts
237// ============================================================================
238
256template <typename T, typename U>
257concept IsContainerOf = requires
258{
259 typename T::value_type;
260 requires std::same_as<typename T::value_type, U>;
261 requires Iterable<T>;
262};
263
264static_assert( IsContainerOf<std::vector<int>, int>);
265static_assert( IsContainerOf<std::vector<std::string>, std::string>);
266static_assert(!IsContainerOf<std::vector<int>, double>);
267static_assert(!IsContainerOf<int, int>);
268
275template <typename T>
277
278static_assert( IsVector<std::vector<int>>);
279static_assert( IsVector<std::vector<std::string>>);
280static_assert(!IsVector<std::string>);
281static_assert(!IsVector<int>);
282
287template <typename T>
289
290static_assert( IsOptional<std::optional<int>>);
292static_assert(!IsOptional<int>);
293static_assert(!IsOptional<std::vector<int>>);
294
318template <typename T>
326
327static_assert( Container<std::vector<int>>);
329static_assert( Container<std::deque<double>>);
330static_assert( Container<std::list<int>>);
331static_assert( Container<std::set<int>>);
333static_assert( Container<std::unordered_set<int>>);
335static_assert(!Container<int>);
336static_assert(!Container<int[10]>);
337static_assert(!Container<std::optional<int>>);
338static_assert(!Container<std::string>);
339
340// ============================================================================
341// String Concepts
342// ============================================================================
343
350template<typename T>
351concept StringConvertible = std::is_convertible_v<std::remove_cvref_t<T>, std::string>;
352
353static_assert( StringConvertible<std::string>);
354static_assert( StringConvertible<const char*>);
355static_assert(!StringConvertible<int>);
357
364template<typename T>
365concept StringConstructible = std::constructible_from<std::string, std::remove_cvref_t<T>>;
366
369static_assert(!StringConstructible<int>);
370static_assert(!StringConstructible<void*>);
371
372// ============================================================================
373// Numeric Concepts
374// ============================================================================
375
388template<typename T>
389concept Numeric = std::integral<std::remove_cvref_t<T>> or std::floating_point<std::remove_cvref_t<T>>;
390
391// Static assertions for Numeric
392static_assert( Numeric<int>);
393static_assert( Numeric<double>);
394static_assert( Numeric<float>);
395static_assert( Numeric<long long>);
396static_assert( Numeric<unsigned int>);
397static_assert(!Numeric<std::string>);
398static_assert(!Numeric<void*>);
399
400// ============================================================================
401// Stream and Formatting Concepts
402// ============================================================================
403
416template<typename T>
417concept StreamInsertable = requires(T t, std::ostream& os)
418{
419 { os << t } -> std::same_as<std::ostream&>;
420};
421
422// Static assertions for StreamInsertable
423static_assert( StreamInsertable<int>);
424static_assert( StreamInsertable<std::string>);
425static_assert( StreamInsertable<double>);
426static_assert(!StreamInsertable<std::vector<int>>);
427
441template<typename T>
444 or Numeric<T>
446
447static_assert( StringRepresentable<int>);
450static_assert( StringRepresentable<double>);
452
453} // namespace ns_concept
454
455/* vim: set expandtab fdm=marker ts=2 sw=2 tw=100 et :*/
Concept for types that can be contextually converted to bool.
Definition concept.hpp:103
Concept for standard library container types.
Definition concept.hpp:319
Concept for enumeration types.
Definition concept.hpp:134
Concept for containers holding a specific value type.
Definition concept.hpp:257
Concept to check if a type is an instance of a specific template.
Definition concept.hpp:72
Concept for std::optional types.
Definition concept.hpp:288
Concept for std::vector types.
Definition concept.hpp:276
Concept for iterable containers (has begin() and end())
Definition concept.hpp:227
Concept for numeric types (integral or floating-point)
Definition concept.hpp:389
Concept for scoped enumeration types (enum class)
Definition concept.hpp:150
Concept for types that support stream insertion (operator<<)
Definition concept.hpp:417
Concept for types that can construct a std::string.
Definition concept.hpp:365
Concept for types implicitly convertible to std::string.
Definition concept.hpp:351
Concept for types that can be represented as a string.
Definition concept.hpp:442
Concept to check if all types are the same.
Definition concept.hpp:198
Concept for std::variant types.
Definition concept.hpp:172
C++ concepts for type constraints and compile-time validation.
constexpr bool is_instance_of_v
Type trait to check if a type is an instance of a template.
Definition concept.hpp:50