HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
utility.hpp
Go to the documentation of this file.
1// Copyright Take Vos 2021-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
10#pragma once
11
12#include <cstddef>
13#include <string>
14#include <chrono>
15
16#ifndef hilet
23#define hilet auto const
24#endif
25
26#ifndef hi_forward
29#define hi_forward(x) std::forward<decltype(x)>(x)
30#endif
31
38#define hi_return_if_valid(expression) \
39 do { \
40 if constexpr (requires { expression; }) { \
41 return expression; \
42 } \
43 } while (false)
44
45// One clang-format off is not enough to stop clang-format to format.
46// clang-format off
47// clang-format off
48#define hi_num_va_args_impl( \
49 _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
50 _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
51 _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
52 _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
53 _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
54 _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
55 _61,_62,_63,N,...) N
56#define hi_num_va_args_(...) hi_num_va_args_impl(__VA_ARGS__)
57
63#define hi_num_va_args(...) hi_num_va_args_(__VA_ARGS__ __VA_OPT__(,) \
64 63,62,61,60, \
65 59,58,57,56,55,54,53,52,51,50, \
66 49,48,47,46,45,44,43,42,41,40, \
67 39,38,37,36,35,34,33,32,31,30, \
68 29,28,27,26,25,24,23,22,21,20, \
69 19,18,17,16,15,14,13,12,11,10, \
70 9,8,7,6,5,4,3,2,1,0)
71// clang-format on
72
73#define hi_parans ()
74
75#define hi_expand1(...) __VA_ARGS__
76#define hi_expand2(...) hi_expand1(hi_expand1(hi_expand1(hi_expand1(__VA_ARGS__))))
77#define hi_expand3(...) hi_expand2(hi_expand2(hi_expand2(hi_expand2(__VA_ARGS__))))
78#define hi_expand4(...) hi_expand3(hi_expand3(hi_expand3(hi_expand3(__VA_ARGS__))))
79
84#define hi_expand(...) hi_expand4(hi_expand4(hi_expand4(hi_expand4(__VA_ARGS__))))
85
86#define hi_for_each_again() hi_for_each_helper
87#define hi_for_each_helper(macro, first_arg, ...) macro(first_arg) __VA_OPT__(hi_for_each_again hi_parans(macro, __VA_ARGS__))
88
94#define hi_for_each(macro, ...) __VA_OPT__(hi_expand(hi_for_each_helper(macro, __VA_ARGS__)))
95
96#define hi_stringify_(x) #x
97#define hi_stringify(x) hi_stringify_(x)
98
99#define hi_cat_(a, b) a##b
100#define hi_cat(a, b) hi_cat_(a, b)
101
102#define hi_return_on_self_assignment(other) \
103 if (&(other) == this) [[unlikely]] \
104 return *this;
105
115#define hi_get_overloaded_macro2(_1, _2, name, ...) name
116
117#if defined(__clang__)
118#define hi_unreachable() __builtin_unreachable()
119#define hi_assume(condition) __builtin_assume(to_bool(condition))
120#define hi_force_inline inline __attribute__((always_inline))
121#define hi_no_inline __attribute__((noinline))
122#define hi_restrict __restrict__
123#define hi_warning_push() _Pragma("warning(push)")
124#define hi_warning_pop() _Pragma("warning(push)")
125#define hi_warning_ignore_msvc(code)
126#define hi_warning_ignore_clang(a) _Pragma(hi_stringify(clang diagnostic ignored a))
127#define hi_export
128#define hi_typename typename
129#define hi_constexpr
130
131#elif defined(_MSC_BUILD)
132#define hi_unreachable() __assume(0)
133#define hi_assume(condition) __assume(condition)
134#define hi_force_inline __forceinline
135#define hi_no_inline __declspec(noinline)
136#define hi_restrict __restrict
137#define hi_warning_push() _Pragma("warning( push )")
138#define hi_warning_pop() _Pragma("warning( pop )")
139#define hi_msvc_pragma(a) _Pragma(a)
140#define hi_warning_ignore_msvc(code) _Pragma(hi_stringify(warning(disable : code)))
141#define hi_warning_ignore_clang(a)
142#define hi_export __declspec(dllexport)
143#define hi_typename
144#define hi_constexpr constexpr
145
146#elif defined(__GNUC__)
147#define hi_unreachable() __builtin_unreachable()
148#define hi_assume(condition) \
149 do { \
150 if (!(condition)) \
151 hi_unreachable(); \
152 } while (false)
153#define hi_force_inline inline __attribute__((always_inline))
154#define hi_no_inline __attribute__((noinline))
155#define hi_restrict __restrict__
156#define hi_warning_push() _Pragma("warning(push)")
157#define hi_warning_pop() _Pragma("warning(pop)")
158#define hi_msvc_pragma(a)
159#define hi_warning_ignore_clang(a)
160#define msvc_pragma(a)
161#define hi_typename
162
163#else
164#define hi_unreachable() std::terminate()
165#define hi_assume(condition) static_assert(sizeof(condition) == 1)
166#define hi_force_inline inline
167#define hi_no_inline
168#define hi_restrict
169#define hi_warning_push()
170#define hi_warning_pop()
171#define hi_msvc_pragma(a)
172#define hi_warning_ignore_clang(a)
173#define msvc_pragma(a)
174#define hi_typename
175#endif
176
177hi_warning_push();
178// C26472: Don't use static_cast for arithmetic conversions, Use brace initialization, gsl::narrow_cast or gsl::narrow (type.1).
179// We do not have access to narrow_cast in this file.
181// C26473: Don't cast between pointer types where the source type and the target type are the same (type.1).
182// hi_forward need to specifically cast a value to a reference using static_cast.
184
185namespace hi { inline namespace v1 {
186
190
191#define ssizeof(x) (static_cast<ssize_t>(sizeof(x)))
192
193constexpr std::size_t operator"" _uz(unsigned long long lhs) noexcept
194{
195 return static_cast<std::size_t>(lhs);
196}
197
198constexpr std::size_t operator"" _zu(unsigned long long lhs) noexcept
199{
200 return static_cast<std::size_t>(lhs);
201}
202
203constexpr std::ptrdiff_t operator"" _z(unsigned long long lhs) noexcept
204{
205 return static_cast<std::ptrdiff_t>(lhs);
206}
207
211template<typename T, typename U>
212[[nodiscard]] bool compare_store(T& lhs, U&& rhs) noexcept
213{
214 if (lhs != rhs) {
215 lhs = std::forward<U>(rhs);
216 return true;
217 } else {
218 return false;
219 }
220}
221
227template<typename T, typename U>
228[[nodiscard]] bool compare_store(std::atomic<T>& lhs, U&& rhs) noexcept
229{
230 return lhs.exchange(rhs, std::memory_order::relaxed) != rhs;
231}
232
235struct override_t {};
236
240 unusable_t() = delete;
241 ~unusable_t() = delete;
242 unusable_t(unusable_t const&) = delete;
243 unusable_t(unusable_t&&) = delete;
244 unusable_t &operator=(unusable_t const&) = delete;
245 unusable_t &operator=(unusable_t&&) = delete;
246};
247
248
249template<class T, class U>
250[[nodiscard]] constexpr auto&& forward_like(U&& x) noexcept
251{
252 constexpr bool is_adding_const = std::is_const_v<std::remove_reference_t<T>>;
253 if constexpr (std::is_lvalue_reference_v<T&&>) {
254 if constexpr (is_adding_const) {
255 return std::as_const(x);
256 } else {
257 return static_cast<U&>(x);
258 }
259 } else {
260 if constexpr (is_adding_const) {
261 return std::move(std::as_const(x));
262 } else {
263 return std::move(x);
264 }
265 }
266}
267
268}} // namespace hi::v1
269
270hi_warning_pop();
hi_warning_ignore_msvc(26472)
Definition int_carry.hpp:27
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
bool compare_store(T &lhs, U &&rhs) noexcept
Compare then store if there was a change.
Definition utility.hpp:212
Tag used for special functions or constructions to do a override compared to another function of the ...
Definition utility.hpp:235
A type that can not be constructed, copied, moved or destructed.
Definition utility.hpp:239
T move(T... args)