StormByte C++ Library 0.0.9999
StormByte is a comprehensive, cross-platform C++ library aimed at easing system programming, configuration management, logging, and database handling tasks. This library provides a unified API that abstracts away the complexities and inconsistencies of different platforms (Windows, Linux).
Loading...
Searching...
No Matches
type_traits.hxx
1#pragma once
2
3#include <concepts>
4#include <optional>
5#include <string>
6#include <type_traits>
7#include <utility>
8#include <variant>
9
17namespace StormByte {
18 // Implementation detail: type traits for internal use only
19 namespace {
20 template<typename T>
21 struct is_string : std::bool_constant<std::is_same_v<T, std::string> || std::is_same_v<T, std::wstring>> {};
22
23 template<typename T, typename _ = void>
24 struct is_container : std::false_type {};
25
26 template<typename T>
27 struct is_container<T, std::void_t<decltype(std::declval<T>().begin()), decltype(std::declval<T>().end()), typename T::value_type>>
28 : std::bool_constant<!is_string<std::decay_t<T>>::value> {};
29
30 template<typename T, typename _ = void>
31 struct is_optional : std::false_type {};
32
33 template<typename T>
34 struct is_optional<T, std::void_t<typename T::value_type>>
35 : std::is_same<T, std::optional<typename T::value_type>> {};
36
37 template<typename T, typename _ = void>
38 struct is_pair : std::false_type {};
39
40 template<typename T>
41 struct is_pair<T, std::void_t<
42 decltype(std::declval<T>().first),
43 decltype(std::declval<T>().second)
44 >> : std::true_type {};
45
46 template<typename T>
47 struct is_variant : std::false_type {};
48
49 template<typename... Ts>
50 struct is_variant<std::variant<Ts...>> : std::true_type {};
51
52 template<typename VariantT, typename U, std::size_t... I>
53 constexpr bool variant_has_type_impl(std::index_sequence<I...>) noexcept {
54 return ((std::is_same_v<std::remove_cvref_t<U>, std::remove_cvref_t<std::variant_alternative_t<I, VariantT>>>) || ...);
55 }
56
57 template<typename VariantT, typename U>
58 struct variant_has_type : std::bool_constant<
59 variant_has_type_impl<VariantT, U>(std::make_index_sequence<std::variant_size_v<VariantT>>())
60 > {};
61
68 template<typename U>
69 constexpr U swap_endian(U val) noexcept {
70 union {
71 U value;
72 unsigned char bytes[sizeof(U)];
73 } src, dest;
74
75 src.value = val;
76 for (std::size_t i = 0; i < sizeof(U); ++i) {
77 dest.bytes[i] = src.bytes[sizeof(U) - 1 - i];
78 }
79 return dest.value;
80 }
81 }
82
90 namespace Type {
101 template<typename T>
102 concept String = is_string<T>::value;
103
115 template<typename T>
116 concept Container = is_container<T>::value;
117
124 template<typename C>
125 concept HasPushBack = Container<C> && requires(C& c, typename C::value_type const& v) {
126 c.push_back(v);
127 };
128
132 template<typename C>
133 concept HasPushFront = Container<C> && requires(C& c, typename C::value_type const& v) {
134 c.push_front(v);
135 };
136
140 template<typename C>
141 concept HasInsert = Container<C> && requires(C& c, typename C::value_type const& v) {
142 c.insert(v);
143 };
144
151 template<typename C, typename U>
152 concept HasSubscript = Container<C> && requires(C& c, U const& u) {
153 { c[u] };
154 };
155
166 template<typename C>
167 concept HasKeyType = Container<C> && requires { typename C::key_type; };
168
175 template<typename C>
176 concept HasMappedType = Container<C> && requires { typename C::mapped_type; };
177
188 template<typename T>
189 concept Optional = is_optional<T>::value;
190
201 template<typename T>
202 concept Pair = is_pair<T>::value;
203
214 template<typename T>
215 concept Reference = std::is_reference_v<T>;
216
227 template<typename E>
228 concept Enum = std::is_enum_v<std::remove_cv_t<E>>;
229
240 template<typename E>
241 concept UnsignedEnum =
242 Enum<E> &&
243 std::is_unsigned_v<std::underlying_type_t<std::remove_cv_t<E>>>;
244
255 template<typename E>
256 concept ScopedEnum = std::is_scoped_enum_v<E>;
257
265 template<typename E>
266 requires Enum<E>
267 using UnderlyingType = std::underlying_type_t<std::remove_cv_t<E>>;
268
272 template<typename E>
273 requires Enum<E>
274 constexpr UnderlyingType<E> ToUnderlying(E e) noexcept {
275 return static_cast<UnderlyingType<E>>(e);
276 }
277
288 template<typename T>
289 concept Pointer = std::is_pointer_v<T>;
290
301 template<typename T>
302 concept Integral = std::is_integral_v<T>;
303
314 template<typename T>
315 concept FloatingPoint = std::is_floating_point_v<T>;
316
327 template<typename T>
328 concept Arithmetic = std::is_arithmetic_v<T>;
329
340 template<typename T>
341 concept Signed = std::is_signed_v<T>;
342
353 template<typename T>
354 concept Unsigned = std::is_unsigned_v<T>;
355
366 template<typename T>
367 concept Const = std::is_const_v<T>;
368
379 template<typename T>
380 concept Class = std::is_class_v<T>;
381
392 template<typename T>
393 concept Variant = is_variant<std::remove_cvref_t<T>>::value;
394
406 template<typename T, typename U>
407 concept VariantHasType = Variant<T> && variant_has_type<std::remove_cvref_t<T>, U>::value;
408
419 template<typename T>
420 concept TriviallyCopyable = std::is_trivially_copyable_v<T>;
421
432 template<typename T>
433 concept TriviallyDestructible = std::is_trivially_destructible_v<T>;
434
445 template<typename T>
446 concept DefaultConstructible = std::is_default_constructible_v<T>;
447
458 template<typename T>
459 concept CopyConstructible = std::is_copy_constructible_v<T>;
460
471 template<typename T>
472 concept MoveConstructible = std::is_move_constructible_v<T>;
473
486 template<typename F, typename... Args>
487 concept Callable = std::is_invocable_v<F, Args...>;
488
501 template<typename T, typename U>
502 concept SameAs = std::is_same_v<std::remove_cvref_t<T>, std::remove_cvref_t<U>>;
503
516 template<typename From, typename To>
517 concept ConvertibleTo = std::is_convertible_v<From, To>;
518 }
519}
Concept to check if a type is arithmetic.
Definition type_traits.hxx:328
Concept to check if a type is callable.
Definition type_traits.hxx:487
Concept to check if a type is a class or struct.
Definition type_traits.hxx:380
Concept to check if a type is const-qualified.
Definition type_traits.hxx:367
Concept to check if a type is a container (excluding strings).
Definition type_traits.hxx:116
Concept to check if one type is convertible to another.
Definition type_traits.hxx:517
Concept to check if a type is copy constructible.
Definition type_traits.hxx:459
Concept to check if a type is default constructible.
Definition type_traits.hxx:446
Concept to check if a type is an enumeration.
Definition type_traits.hxx:228
Concept to check if a type is a floating-point type.
Definition type_traits.hxx:315
Concept that checks whether a container supports insert with a value.
Definition type_traits.hxx:141
Concept to check if a container has a key_type member type.
Definition type_traits.hxx:167
Concept to check if a container has a mapped_type member type.
Definition type_traits.hxx:176
Concept that checks whether a container supports push_back.
Definition type_traits.hxx:125
Concept that checks whether a container supports push_front.
Definition type_traits.hxx:133
Concept that checks whether a container supports operator[] for a given key/index type U.
Definition type_traits.hxx:152
Concept to check if a type is an integral type.
Definition type_traits.hxx:302
Concept to check if a type is move constructible.
Definition type_traits.hxx:472
Concept to check if a type is an optional.
Definition type_traits.hxx:189
Concept to check if a type is a pair.
Definition type_traits.hxx:202
Concept to check if a type is a pointer.
Definition type_traits.hxx:289
Concept to check if a type is a reference.
Definition type_traits.hxx:215
Concept to check if two types are the same.
Definition type_traits.hxx:502
Concept to check if a type is a scoped enumeration (enum class).
Definition type_traits.hxx:256
Concept to check if a type is signed.
Definition type_traits.hxx:341
Concept to check if a type is std::string or std::wstring.
Definition type_traits.hxx:102
Concept to check if a type is trivially copyable.
Definition type_traits.hxx:420
Concept to check if a type has a trivial destructor.
Definition type_traits.hxx:433
Concept to check if a type is an unsigned enumeration.
Definition type_traits.hxx:241
Concept to check if a type is unsigned.
Definition type_traits.hxx:354
Concept to check if a variant type contains a specific type.
Definition type_traits.hxx:407
Concept to check if a type is a variant.
Definition type_traits.hxx:393
Main namespace for the StormByte library.
Modern C++20 concepts for type checking.