HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
type_traits.hpp
Go to the documentation of this file.
1// Copyright Take Vos 2019-2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
8#pragma once
9
10#include "../macros.hpp"
11#include <cstdint>
12#include <type_traits>
13#include <string>
14#include <string_view>
15#include <memory>
16#include <variant>
17#include <atomic>
18
19hi_export_module(hikogui.utility.type_traits);
20
21hi_export namespace hi {
22inline namespace v1 {
30template<typename T>
32template<>
34template<>
36template<>
38template<>
40template<>
41struct is_numeric_signed_integral<signed long long> : std::true_type {};
42
45template<typename T>
47
55template<typename T>
57template<>
59template<>
61template<>
62struct is_numeric_unsigned_integral<unsigned short> : std::true_type {};
63template<>
65template<>
66struct is_numeric_unsigned_integral<unsigned long long> : std::true_type {};
67
70template<typename T>
72
81template<typename T>
83template<>
84struct is_numeric_integral<unsigned int> : std::true_type {};
85template<>
86struct is_numeric_integral<unsigned char> : std::true_type {};
87template<>
88struct is_numeric_integral<unsigned short> : std::true_type {};
89template<>
90struct is_numeric_integral<unsigned long> : std::true_type {};
91template<>
92struct is_numeric_integral<unsigned long long> : std::true_type {};
93template<>
94struct is_numeric_integral<signed char> : std::true_type {};
95template<>
96struct is_numeric_integral<signed short> : std::true_type {};
97template<>
98struct is_numeric_integral<signed int> : std::true_type {};
99template<>
100struct is_numeric_integral<signed long> : std::true_type {};
101template<>
102struct is_numeric_integral<signed long long> : std::true_type {};
103
106template<typename T>
108
118template<typename T>
120template<>
121struct is_numeric<unsigned char> : std::true_type {};
122template<>
123struct is_numeric<unsigned short> : std::true_type {};
124template<>
125struct is_numeric<unsigned int> : std::true_type {};
126template<>
127struct is_numeric<unsigned long> : std::true_type {};
128template<>
129struct is_numeric<unsigned long long> : std::true_type {};
130template<>
131struct is_numeric<signed char> : std::true_type {};
132template<>
133struct is_numeric<signed short> : std::true_type {};
134template<>
135struct is_numeric<signed int> : std::true_type {};
136template<>
137struct is_numeric<signed long> : std::true_type {};
138template<>
139struct is_numeric<signed long long> : std::true_type {};
140template<>
141struct is_numeric<float> : std::true_type {};
142template<>
143struct is_numeric<double> : std::true_type {};
144template<>
145struct is_numeric<long double> : std::true_type {};
146
149template<typename T>
150inline constexpr bool is_numeric_v = is_numeric<T>::value;
151
152template<typename T>
154template<>
155struct is_character<char> : std::true_type {};
156template<>
157struct is_character<wchar_t> : std::true_type {};
158template<>
159struct is_character<char8_t> : std::true_type {};
160template<>
161struct is_character<char16_t> : std::true_type {};
162template<>
163struct is_character<char32_t> : std::true_type {};
164template<>
165struct is_character<char const> : std::true_type {};
166template<>
167struct is_character<wchar_t const> : std::true_type {};
168template<>
169struct is_character<char8_t const> : std::true_type {};
170template<>
171struct is_character<char16_t const> : std::true_type {};
172template<>
173struct is_character<char32_t const> : std::true_type {};
174
178template<typename T>
180
185template<typename T>
187template<>
188struct is_byte_like<char> : std::true_type {};
189template<>
190struct is_byte_like<unsigned char> : std::true_type {};
191template<>
192struct is_byte_like<std::byte> : std::true_type {};
193template<>
194struct is_byte_like<char const> : std::true_type {};
195template<>
196struct is_byte_like<unsigned char const> : std::true_type {};
197template<>
198struct is_byte_like<std::byte const> : std::true_type {};
199
204template<typename T>
206
209template<typename T>
210struct make_string {};
211template<>
212struct make_string<char> {
213 using type = std::string;
214};
215template<>
216struct make_string<wchar_t> {
217 using type = std::wstring;
218};
219template<>
220struct make_string<char8_t> {
221 using type = std::u8string;
222};
223template<>
224struct make_string<char16_t> {
225 using type = std::u16string;
226};
227template<>
228struct make_string<char32_t> {
229 using type = std::u32string;
230};
231
234template<typename T>
236
239template<typename T>
241 using type = void;
242};
243template<>
244struct make_string_view<char> {
245 using type = std::string_view;
246};
247template<>
248struct make_string_view<wchar_t> {
249 using type = std::wstring_view;
250};
251template<>
252struct make_string_view<char8_t> {
253 using type = std::u8string_view;
254};
255template<>
256struct make_string_view<char16_t> {
257 using type = std::u16string_view;
258};
259template<>
260struct make_string_view<char32_t> {
261 using type = std::u32string_view;
262};
263
266template<typename T>
268
269template<typename T, typename U>
271 using type = decltype(static_cast<T>(0) + static_cast<U>(0));
272};
273
274template<typename T, typename U>
275using make_promote_t = typename make_promote<T, U>::type;
276
277template<typename T, typename Ei = void>
279 using type = uintmax_t;
280};
281
282template<std::unsigned_integral T>
283struct make_intmax<T> {
284 using type = uintmax_t;
285};
286
287template<std::signed_integral T>
288struct make_intmax<T> {
289 using type = intmax_t;
290};
291
292template<typename T>
293using make_intmax_t = typename make_intmax<T>::type;
294
298template<std::size_t N>
300
304template<std::size_t N>
306
310template<std::size_t N>
312
316template<std::size_t N>
318
322template<std::size_t N>
324
328template<std::size_t N>
330
334template<std::size_t N>
335struct make_intxx {};
336
340template<std::size_t N>
341struct make_uintxx {};
342
346template<std::size_t N>
347struct make_floatxx {};
348
349#ifdef HI_HAS_INT128
350template<>
351struct has_native_intxx<128> : std::true_type {};
352template<>
353struct has_native_uintxx<128> : std::true_type {};
354#endif
355template<>
357template<>
359template<>
361template<>
363template<>
365template<>
367template<>
369template<>
371template<>
373template<>
375
376#ifdef HI_HAS_INT128
377template<>
378struct make_intxx<128> {
379 using type = int128_t;
380};
381template<>
382struct make_uintxx<128> {
383 using type = uint128_t;
384};
385#endif
386template<>
387struct make_intxx<64> {
388 using type = int64_t;
389};
390template<>
391struct make_uintxx<64> {
392 using type = uint64_t;
393};
394template<>
395struct make_floatxx<64> {
396 using type = double;
397};
398template<>
399struct make_intxx<32> {
400 using type = int32_t;
401};
402template<>
403struct make_uintxx<32> {
404 using type = uint32_t;
405};
406template<>
407struct make_floatxx<32> {
408 using type = float;
409};
410template<>
411struct make_intxx<16> {
412 using type = int16_t;
413};
414template<>
415struct make_uintxx<16> {
416 using type = uint16_t;
417};
418template<>
419struct make_intxx<8> {
420 using type = int8_t;
421};
422template<>
423struct make_uintxx<8> {
424 using type = uint8_t;
425};
426
427template<std::size_t N>
428constexpr bool has_native_intxx_v = has_native_intxx<N>::value;
429template<std::size_t N>
430constexpr bool has_native_uintxx_v = has_native_uintxx<N>::value;
431template<std::size_t N>
432constexpr bool has_native_floatxx_v = has_native_floatxx<N>::value;
433template<std::size_t N>
434constexpr bool has_intxx_v = has_intxx<N>::value;
435template<std::size_t N>
436constexpr bool has_uintxx_v = has_uintxx<N>::value;
437template<std::size_t N>
438constexpr bool has_floatxx_v = has_floatxx<N>::value;
439template<std::size_t N>
440using make_intxx_t = typename make_intxx<N>::type;
441template<std::size_t N>
442using make_uintxx_t = typename make_uintxx<N>::type;
443template<std::size_t N>
444using make_floatxx_t = typename make_floatxx<N>::type;
445
446template<typename T>
448 using type = std::remove_cv_t<std::remove_pointer_t<T>>;
449};
450
451template<typename T>
452using remove_cvptr_t = remove_cvptr<T>::type;
453
456template<typename To, typename From, typename Ei = void>
457struct copy_cv {};
458
459template<typename To, typename From>
460requires(not std::is_const_v<From> and not std::is_volatile_v<From>)
462 using type = std::remove_cv_t<To>;
463};
464
465template<typename To, typename From>
466requires(not std::is_const_v<From> and std::is_volatile_v<From>)
467struct copy_cv<To, From> {
468 using type = std::remove_cv_t<To> volatile;
469};
470
471template<typename To, typename From>
472requires(std::is_const_v<From> and not std::is_volatile_v<From>)
473struct copy_cv<To, From> {
474 using type = std::remove_cv_t<To> const;
475};
476
477template<typename To, typename From>
478requires(std::is_const_v<From> and std::is_volatile_v<From>)
479struct copy_cv<To, From> {
480 using type = std::remove_cv_t<To> const volatile;
481};
482
485template<typename To, typename From>
487
488template<typename T>
490 template<typename C>
491 static std::true_type test(typename C::value_type*);
492 template<typename>
493 static std::false_type test(...);
494
495 static const bool value = std::is_same_v<decltype(test<T>(nullptr)), std::true_type>;
496};
497
498template<typename T>
499inline constexpr bool has_value_type_v = has_value_type<T>::value;
500
501template<typename T>
503 template<typename C>
504 static std::true_type test(decltype(&C::add_callback) func_ptr);
505 template<typename>
506 static std::false_type test(...);
507
508 static const bool value = std::is_same_v<decltype(test<T>(nullptr)), std::true_type>;
509};
510
511template<typename T>
512inline constexpr bool has_add_callback_v = has_add_callback<T>::value;
513
514template<typename BaseType, typename DerivedType>
515struct is_decayed_base_of : std::is_base_of<std::decay_t<BaseType>, std::decay_t<DerivedType>> {};
516
517template<typename BaseType, typename DerivedType>
518constexpr bool is_decayed_base_of_v = is_decayed_base_of<BaseType, DerivedType>::value;
519
520template<typename DerivedType, typename BaseType>
521struct is_derived_from : std::is_base_of<BaseType, DerivedType> {};
522
523template<typename DerivedType, typename BaseType>
524constexpr bool is_derived_from_v = is_derived_from<DerivedType, BaseType>::value;
525
526template<typename DerivedType, typename BaseType>
527struct is_decayed_derived_from : is_decayed_base_of<BaseType, DerivedType> {};
528
529template<typename DerivedType, typename BaseType>
530constexpr bool is_decayed_derived_from_v = is_decayed_derived_from<DerivedType, BaseType>::value;
531
532template<typename T>
534
535template<typename T>
536struct is_atomic<std::atomic<T>> : std::true_type {};
537
538template<typename T>
539constexpr bool is_atomic_v = is_atomic<T>::value;
540
541template<typename First, typename Second>
542struct use_first {
543 using type = First;
544};
545
546template<typename First, typename Second>
548
551template<typename Out, typename In>
554
592template<typename Context, typename Expected, typename... OtherExpected>
594
595template<typename Context, typename Expected, typename FirstOtherExpected, typename... OtherExpected>
596struct is_forward_of<Context, Expected, FirstOtherExpected, OtherExpected...> :
597 std::conditional_t<
598 is_forward_of<Context, Expected>::value or
599 (is_forward_of<Context, FirstOtherExpected>::value or ... or is_forward_of<Context, OtherExpected>::value),
600 std::true_type,
601 std::false_type> {};
602
603template<typename Context, typename Expected>
604struct is_forward_of<Context, Expected> :
605 std::conditional_t<
606 std::is_same_v<std::decay_t<Context>, Expected> or std::is_base_of_v<Expected, std::decay_t<Context>>,
607 std::true_type,
608 std::false_type> {
609 static_assert(not std::is_reference_v<Expected>, "Template argument Expected must be a non-reference type.");
610};
611
612template<typename Context, typename Expected>
613struct is_forward_of<Context, std::shared_ptr<Expected>> :
614 std::conditional_t<std::is_convertible_v<Context, std::shared_ptr<Expected>>, std::true_type, std::false_type> {};
615
616template<typename Context, typename Expected>
617struct is_forward_of<Context, std::weak_ptr<Expected>> :
618 std::conditional_t<std::is_convertible_v<Context, std::weak_ptr<Expected>>, std::true_type, std::false_type> {};
619
620template<typename Context, typename Expected>
621struct is_forward_of<Context, std::unique_ptr<Expected>> :
622 std::conditional_t<std::is_convertible_v<Context, std::unique_ptr<Expected>>, std::true_type, std::false_type> {};
623
624template<typename Context, typename Expected>
625struct is_forward_of<Context, Expected*> :
626 std::conditional_t<std::is_convertible_v<Context, Expected*>, std::true_type, std::false_type> {};
627
628template<typename Context, typename Result, typename... Args>
629struct is_forward_of<Context, Result(Args...)> :
630 std::conditional_t<std::is_invocable_r_v<Result, Context, Args...>, std::true_type, std::false_type> {};
631
632template<typename Context, typename Expected, typename... OtherExpected>
633constexpr bool is_forward_of_v = is_forward_of<Context, Expected, OtherExpected...>::value;
634
635template<typename Context>
637 using type = std::conditional_t<std::is_rvalue_reference_v<Context>, std::decay_t<Context>, std::decay_t<Context> const&>;
638};
639
640template<typename Context>
641using forward_copy_or_ref_t = forward_copy_or_ref<Context>::type;
642
647template<typename T>
649 using type = std::decay_t<T>;
650};
651
652template<>
653struct variant_decay<void> {
654 using type = std::monostate;
655};
656
659template<typename T>
661
690template<typename T>
691struct selector;
692
709template<typename T>
711
716template<class... Ts>
717struct overloaded : Ts... {
718 // Makes the call operator of each lambda available directly to the `overloaded` type.
719 using Ts::operator()...;
720
721 // The implicit constructor is all that is needed to initialize each lambda.
722};
723
728template<typename T>
730
731template<std::integral T>
733 constexpr static T off = T{};
734 constexpr static T on = T{1};
735};
736
737template<typename T>
738requires(std::is_enum_v<T>)
739struct default_values<T> : std::true_type {
740 constexpr static T off = static_cast<T>(0);
741 constexpr static T on = static_cast<T>(1);
742};
743
744template<typename T>
745constexpr bool default_values_v = default_values<T>::value;
746
747} // namespace v1
748} // namespace hi::inline v1
STL namespace.
The HikoGUI namespace.
Definition array_generic.hpp:20
constexpr bool is_numeric_v
Definition type_traits.hpp:150
constexpr bool is_character_v
Definition type_traits.hpp:179
constexpr bool is_numeric_signed_integral_v
Definition type_traits.hpp:46
typename copy_cv< To, From >::type copy_cv_t
Type-trait to copy const volatile qualifiers from one type to another.
Definition type_traits.hpp:486
constexpr bool is_byte_like_v
An array of this type will implicitly create objects within that array.
Definition type_traits.hpp:205
@ on
The border is drawn on the edge of a quad.
variant_decay< T >::type variant_decay_t
Definition type_traits.hpp:660
constexpr bool is_numeric_integral_v
Definition type_traits.hpp:107
typename make_string_view< T >::type make_string_view_t
type-trait to convert a character to a string_view type.
Definition type_traits.hpp:267
constexpr bool is_numeric_unsigned_integral_v
Definition type_traits.hpp:71
constexpr bool type_in_range_v
All values of numeric type In can be represented without loss of range by numeric type Out.
Definition type_traits.hpp:552
typename make_string< T >::type make_string_t
type-trait to convert a character to a string type.
Definition type_traits.hpp:235
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
Is a numeric signed integer.
Definition type_traits.hpp:31
Is a numeric unsigned integer.
Definition type_traits.hpp:56
Is a numeric integer.
Definition type_traits.hpp:82
Is a numeric.
Definition type_traits.hpp:119
Definition type_traits.hpp:153
An array of this type will implicitly create objects within that array.
Definition type_traits.hpp:186
type-trait to convert a character to a string type.
Definition type_traits.hpp:210
type-trait to convert a character to a string_view type.
Definition type_traits.hpp:240
Definition type_traits.hpp:270
Definition type_traits.hpp:278
Has an signed integer of a specific size, natively supported by the compiler.
Definition type_traits.hpp:299
Has an unsigned integer of a specific size, natively supported by the compiler.
Definition type_traits.hpp:305
Has an float of a specific size, natively supported by the compiler.
Definition type_traits.hpp:311
Has an signed integer of a specific size.
Definition type_traits.hpp:317
Has an unsigned integer of a specific size.
Definition type_traits.hpp:323
Has an float of a specific size.
Definition type_traits.hpp:329
Make an signed integer.
Definition type_traits.hpp:335
Make an unsigned integer.
Definition type_traits.hpp:341
Make an floating point.
Definition type_traits.hpp:347
Definition type_traits.hpp:447
Type-trait to copy const volatile qualifiers from one type to another.
Definition type_traits.hpp:457
Definition type_traits.hpp:489
Definition type_traits.hpp:502
Definition type_traits.hpp:515
Definition type_traits.hpp:521
Definition type_traits.hpp:527
Definition type_traits.hpp:533
Definition type_traits.hpp:542
Is context a form of the expected type.
Definition type_traits.hpp:593
Definition type_traits.hpp:636
Decays types for use as elements in std::variant.
Definition type_traits.hpp:648
This selector allows access to member variable by name.
Definition type_traits.hpp:691
Documentation of a type.
Definition type_traits.hpp:710
Helper type to turn a set of lambdas into a single overloaded type to pass to std::visit().
Definition type_traits.hpp:717
A type traits for generating default values of a type.
Definition type_traits.hpp:729