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-2021.
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 "architecture.hpp"
11#include <cstdint>
12#include <type_traits>
13#include <string>
14#include <string_view>
15#include <memory>
16#include <variant>
17
18namespace hi::inline v1 {
19
20// clang-format off
21
29template<typename T> struct is_numeric_signed_integral : std::false_type {};
30template<> struct is_numeric_signed_integral<signed char> : std::true_type {};
31template<> struct is_numeric_signed_integral<signed short> : std::true_type {};
32template<> struct is_numeric_signed_integral<signed int> : std::true_type {};
33template<> struct is_numeric_signed_integral<signed long> : std::true_type {};
34template<> struct is_numeric_signed_integral<signed long long> : std::true_type {};
35
38template<typename T>
40
48template<typename T> struct is_numeric_unsigned_integral : std::false_type {};
49template<> struct is_numeric_unsigned_integral<unsigned int> : std::true_type {};
50template<> struct is_numeric_unsigned_integral<unsigned char> : std::true_type {};
51template<> struct is_numeric_unsigned_integral<unsigned short> : std::true_type {};
52template<> struct is_numeric_unsigned_integral<unsigned long> : std::true_type {};
53template<> struct is_numeric_unsigned_integral<unsigned long long> : std::true_type {};
54
57template<typename T>
59
68template<typename T> struct is_numeric_integral : std::false_type {};
69template<> struct is_numeric_integral<unsigned int> : std::true_type {};
70template<> struct is_numeric_integral<unsigned char> : std::true_type {};
71template<> struct is_numeric_integral<unsigned short> : std::true_type {};
72template<> struct is_numeric_integral<unsigned long> : std::true_type {};
73template<> struct is_numeric_integral<unsigned long long> : std::true_type {};
74template<> struct is_numeric_integral<signed char> : std::true_type {};
75template<> struct is_numeric_integral<signed short> : std::true_type {};
76template<> struct is_numeric_integral<signed int> : std::true_type {};
77template<> struct is_numeric_integral<signed long> : std::true_type {};
78template<> struct is_numeric_integral<signed long long> : std::true_type {};
79
82template<typename T> inline constexpr bool is_numeric_integral_v = is_numeric_integral<T>::value;
83
93template<typename T> struct is_numeric : std::false_type {};
94template<> struct is_numeric<unsigned char> : std::true_type {};
95template<> struct is_numeric<unsigned short> : std::true_type {};
96template<> struct is_numeric<unsigned int> : std::true_type {};
97template<> struct is_numeric<unsigned long> : std::true_type {};
98template<> struct is_numeric<unsigned long long> : std::true_type {};
99template<> struct is_numeric<signed char> : std::true_type {};
100template<> struct is_numeric<signed short> : std::true_type {};
101template<> struct is_numeric<signed int> : std::true_type {};
102template<> struct is_numeric<signed long> : std::true_type {};
103template<> struct is_numeric<signed long long> : std::true_type {};
104template<> struct is_numeric<float> : std::true_type {};
105template<> struct is_numeric<double> : std::true_type {};
106template<> struct is_numeric<long double> : std::true_type {};
107
110template<typename T> inline constexpr bool is_numeric_v = is_numeric<T>::value;
111
112template<typename T> struct is_character : std::false_type {};
113template<> struct is_character<char> : std::true_type {};
114template<> struct is_character<wchar_t> : std::true_type {};
115template<> struct is_character<char8_t> : std::true_type {};
116template<> struct is_character<char16_t> : std::true_type {};
117template<> struct is_character<char32_t> : std::true_type {};
118
122template<typename T> inline constexpr bool is_character_v = is_character<T>::value;
123
126template<typename T> struct make_string { };
127template<> struct make_string<char> { using type = std::string; };
128template<> struct make_string<wchar_t> { using type = std::wstring; };
129template<> struct make_string<char8_t> { using type = std::u8string; };
130template<> struct make_string<char16_t> { using type = std::u16string; };
131template<> struct make_string<char32_t> { using type = std::u32string; };
132
135template<typename T> using make_string_t = typename make_string<T>::type;
136
139template<typename T> struct make_string_view { using type = void; };
140template<> struct make_string_view<char> { using type = std::string_view; };
141template<> struct make_string_view<wchar_t> { using type = std::wstring_view; };
142template<> struct make_string_view<char8_t> { using type = std::u8string_view; };
143template<> struct make_string_view<char16_t> { using type = std::u16string_view; };
144template<> struct make_string_view<char32_t> { using type = std::u32string_view; };
145
148template<typename T>
149using make_string_view_t = typename make_string_view<T>::type;
150
151template<typename T, typename U>
153 using type = decltype(static_cast<T>(0) + static_cast<U>(0));
154};
155
156template<typename T, typename U>
157using make_promote_t = typename make_promote<T,U>::type;
158
159template<typename T, typename Ei=void>
161 using type = uintmax_t;
162};
163
164template<std::unsigned_integral T>
165struct make_intmax<T> {
166 using type = uintmax_t;
167};
168
169template<std::signed_integral T>
170struct make_intmax<T> {
171 using type = intmax_t;
172};
173
174template<typename T>
175using make_intmax_t = typename make_intmax<T>::type;
176
180template<std::size_t N> struct has_intxx : public std::false_type {};
181
185template<std::size_t N> struct has_uintxx : public std::false_type {};
186
190template<std::size_t N> struct has_floatxx : public std::false_type {};
191
195template<std::size_t N> struct make_intxx {};
196
200template<std::size_t N> struct make_uintxx {};
201
205template<std::size_t N> struct make_floatxx {};
206
207#if (HI_COMPILER == HI_CC_CLANG || HI_COMPILER == HI_CC_GCC) && (HI_PROCESSOR == HI_CPU_X64)
208template<> struct has_intxx<128> : public std::true_type {};
209template<> struct has_uintxx<128> : public std::true_type {};
210template<> struct make_intxx<128> { using type = __int128; };
211template<> struct make_uintxx<128> { using type = unsigned __int128; };
212#endif
213template<> struct has_intxx<64> : public std::true_type {};
214template<> struct has_uintxx<64> : public std::true_type {};
215template<> struct has_floatxx<64> : public std::true_type {};
216template<> struct make_intxx<64> { using type = int64_t; };
217template<> struct make_uintxx<64> { using type = uint64_t; };
218template<> struct make_floatxx<64> { using type = double; };
219template<> struct has_intxx<32> : public std::true_type {};
220template<> struct has_uintxx<32> : public std::true_type {};
221template<> struct has_floatxx<32> : public std::true_type {};
222template<> struct make_intxx<32> { using type = int32_t; };
223template<> struct make_uintxx<32> { using type = uint32_t; };
224template<> struct make_floatxx<32> { using type = float; };
225template<> struct has_intxx<16> : public std::true_type {};
226template<> struct has_uintxx<16> : public std::true_type {};
227template<> struct make_intxx<16> { using type = int16_t; };
228template<> struct make_uintxx<16> { using type = uint16_t; };
229template<> struct has_intxx<8> : public std::true_type {};
230template<> struct has_uintxx<8> : public std::true_type {};
231template<> struct make_intxx<8> { using type = int8_t; };
232template<> struct make_uintxx<8> { using type = uint8_t; };
233
234template<std::size_t N> constexpr bool has_intxx_v = has_intxx<N>::value;
235template<std::size_t N> constexpr bool has_uintxx_v = has_uintxx<N>::value;
236template<std::size_t N> constexpr bool has_floatxx_v = has_floatxx<N>::value;
237template<std::size_t N> using make_intxx_t = typename make_intxx<N>::type;
238template<std::size_t N> using make_uintxx_t = typename make_uintxx<N>::type;
239template<std::size_t N> using make_floatxx_t = typename make_floatxx<N>::type;
240
241
244template<typename To, typename From, typename Ei=void>
245struct copy_cv {};
246
247template<typename To, typename From> requires(not std::is_const_v<From> and not std::is_volatile_v<From>)
249 using type = std::remove_cv_t<To>;
250};
251
252template<typename To, typename From> requires(not std::is_const_v<From> and std::is_volatile_v<From>)
253struct copy_cv<To,From> {
254 using type = std::remove_cv_t<To> volatile;
255};
256
257template<typename To, typename From> requires(std::is_const_v<From> and not std::is_volatile_v<From>)
258struct copy_cv<To,From> {
259 using type = std::remove_cv_t<To> const;
260};
261
262template<typename To, typename From> requires(std::is_const_v<From> and std::is_volatile_v<From>)
263struct copy_cv<To,From> {
264 using type = std::remove_cv_t<To> const volatile;
265};
266
269template<typename To, typename From>
271
272template <typename T> struct has_value_type
273{
274 template <typename C> static std::true_type test(typename C::value_type *);
275 template <typename> static std::false_type test(...);
276
277 static const bool value = std::is_same_v<decltype(test<T>(nullptr)), std::true_type>;
278};
279
280template<typename T>
281inline constexpr bool has_value_type_v = has_value_type<T>::value;
282
283template <typename T> struct has_add_callback
284{
285 template <typename C> static std::true_type test(decltype(&C::add_callback) func_ptr);
286 template <typename> static std::false_type test(...);
287
288 static const bool value = std::is_same_v<decltype(test<T>(nullptr)), std::true_type>;
289};
290
291template<typename T>
292inline constexpr bool has_add_callback_v = has_add_callback<T>::value;
293
294template<typename BaseType, typename DerivedType>
295struct is_decayed_base_of : public std::is_base_of<std::decay_t<BaseType>,std::decay_t<DerivedType>> {};
296
297template<typename BaseType, typename DerivedType>
298constexpr bool is_decayed_base_of_v = is_decayed_base_of<BaseType,DerivedType>::value;
299
300template<typename DerivedType, typename BaseType>
301struct is_derived_from : public std::is_base_of<BaseType,DerivedType> {};
302
303template<typename DerivedType, typename BaseType>
304constexpr bool is_derived_from_v = is_derived_from<DerivedType,BaseType>::value;
305
306template<typename DerivedType, typename BaseType>
307struct is_decayed_derived_from : public is_decayed_base_of<BaseType,DerivedType> {};
308
309template<typename DerivedType, typename BaseType>
310constexpr bool is_decayed_derived_from_v = is_decayed_derived_from<DerivedType,BaseType>::value;
311
315template<typename T1, typename T2>
316constexpr bool is_different_v = not std::is_same_v<std::remove_cvref_t<T1>,std::remove_cvref_t<T2>>;
317
318template<typename T>
319struct is_atomic : public std::false_type {};
320
321template<typename T>
322struct is_atomic<std::atomic<T>> : public std::true_type {};
323
324template<typename T>
325constexpr bool is_atomic_v = is_atomic<T>::value;
326
327template<typename First, typename Second>
328struct use_first {
329 using type = First;
330};
331
332template<typename First, typename Second>
334
335template<typename T>
337
338template<typename T> struct acts_as_pointer<std::shared_ptr<T>> : public std::true_type {};
339template<typename T> struct acts_as_pointer<std::shared_ptr<T> &&> : public std::true_type {};
340template<typename T> struct acts_as_pointer<std::shared_ptr<T> &> : public std::true_type {};
341template<typename T> struct acts_as_pointer<std::shared_ptr<T> const &> : public std::true_type {};
342template<typename T> struct acts_as_pointer<std::weak_ptr<T>> : public std::true_type {};
343template<typename T> struct acts_as_pointer<std::weak_ptr<T> &&> : public std::true_type {};
344template<typename T> struct acts_as_pointer<std::weak_ptr<T> &> : public std::true_type {};
345template<typename T> struct acts_as_pointer<std::weak_ptr<T> const &> : public std::true_type {};
346template<typename T> struct acts_as_pointer<std::unique_ptr<T>> : public std::true_type {};
347template<typename T> struct acts_as_pointer<std::unique_ptr<T> &&> : public std::true_type {};
348template<typename T> struct acts_as_pointer<std::unique_ptr<T> &> : public std::true_type {};
349template<typename T> struct acts_as_pointer<std::unique_ptr<T> const &> : public std::true_type {};
350template<typename T> struct acts_as_pointer<T *> : public std::true_type {};
351
352template<typename T>
353constexpr bool acts_as_pointer_v = acts_as_pointer<T>::value;
354
355#define hi_call_method(object, method, ...) \
356 [&]() { \
357 if constexpr (acts_as_pointer_v<decltype(object)>) { \
358 return object->method(__VA_ARGS__); \
359 } else { \
360 return object.method(__VA_ARGS__); \
361 } \
362 }()
363
364// clang-format on
365
368template<typename Out, typename In>
371
381template<typename T, typename Forward>
383};
384
385template<typename T>
386struct is_forward_of<T, T> : public std::true_type {
387};
388
389template<typename T>
390struct is_forward_of<T, T const&> : public std::true_type {
391};
392
393template<typename T>
394struct is_forward_of<T, T&> : public std::true_type {
395};
396
397template<typename T, typename Forward>
398constexpr bool is_forward_of_v = is_forward_of<T, Forward>::value;
399
404template<typename T>
406 using type = std::decay_t<T>;
407};
408
409template<>
410struct variant_decay<void> {
411 using type = std::monostate;
412};
413
416template<typename T>
417using variant_decay_t = variant_decay<T>::type;
418
419} // namespace hi::inline v1
constexpr bool is_numeric_v
Definition type_traits.hpp:110
constexpr bool is_different_v
If the types are different.
Definition type_traits.hpp:316
typename make_string< T >::type make_string_t
type-trait to convert a character to a string type.
Definition type_traits.hpp:135
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:149
constexpr bool is_numeric_unsigned_integral_v
Definition type_traits.hpp:58
variant_decay< T >::type variant_decay_t
Definition type_traits.hpp:417
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:270
constexpr bool is_numeric_integral_v
Definition type_traits.hpp:82
constexpr bool type_in_range_v
All values of numeric type In can be represented without loss of precision by numeric type Out.
Definition type_traits.hpp:369
constexpr bool is_character_v
Definition type_traits.hpp:122
constexpr bool is_numeric_signed_integral_v
Definition type_traits.hpp:39
Functions and macros for handling architectural difference between compilers, CPUs and operating syst...
STL namespace.
Is a numeric signed integer.
Definition type_traits.hpp:29
Is a numeric unsigned integer.
Definition type_traits.hpp:48
Is a numeric integer.
Definition type_traits.hpp:68
Is a numeric.
Definition type_traits.hpp:93
Definition type_traits.hpp:112
type-trait to convert a character to a string type.
Definition type_traits.hpp:126
type-trait to convert a character to a string_view type.
Definition type_traits.hpp:139
Definition type_traits.hpp:152
Definition type_traits.hpp:160
Has an signed integer of a specific size.
Definition type_traits.hpp:180
Has an unsigned integer of a specific size.
Definition type_traits.hpp:185
Has an float of a specific size.
Definition type_traits.hpp:190
Make an signed integer.
Definition type_traits.hpp:195
Make an unsigned integer.
Definition type_traits.hpp:200
Make an floating point.
Definition type_traits.hpp:205
Type-trait to copy const volitile qualifiers from one type to another.
Definition type_traits.hpp:245
Definition type_traits.hpp:273
Definition type_traits.hpp:284
Definition type_traits.hpp:295
Definition type_traits.hpp:301
Definition type_traits.hpp:307
Definition type_traits.hpp:319
Definition type_traits.hpp:328
Definition type_traits.hpp:336
True if T is a forwarded type of OfType.
Definition type_traits.hpp:382
Decays types for use as elements in std::variant.
Definition type_traits.hpp:405