jaulib v1.4.1
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
cpp_lang_util.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Gothel Software e.K.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 */
24
25#ifndef JAU_CPP_LANG_EXT_HPP_
26#define JAU_CPP_LANG_EXT_HPP_
27
28#include <climits>
29#include <string_view>
30#include <type_traits>
31#include <string>
32#include <cstring>
33#include <ostream>
34#if __cplusplus > 201703L
35 // C++20
36 #include <bit>
37#endif
38#if __cplusplus > 202002L
39 // C++23
40 #include <stdbit>
41#endif
42
44
45namespace jau {
46
47 /** @defgroup CppLang C++ Language Utilities
48 * C++ language utilities, language feature alignment, type trails, data alignment and intrinsics.
49 *
50 * Used predefined `__cplusplus` macro identifier for C++ language specs:
51 * - `199711L`: pre C++11
52 * - `201103L`: C++11
53 * - `201402L`: C++14
54 * - `201703L`: C++17
55 * - `202002L`: C++20
56 * - `202302L`: C++23
57 * - `??????L`: C++26 ??
58 *
59 * Used predefined macros denoting the compiler:
60 * - `__clang__` : LLVM's clang, clang++
61 * - `__GNUC__` : GNU Compiler Collection (GCC)'s gcc, g++
62 * - `_MSC_VER` : Microsoft Compiler
63 * - `__MINGW32__` : MinGW 32
64 * - `__MINGW64__` : MinGW 64
65 * - `__EMSCRIPTEN__`: emscripten for asm.js and WebAssembly
66 *
67 * Further infos:
68 * - [Unix standards](https://sourceforge.net/p/predef/wiki/Standards/)
69 * - [GNU glibc](https://sourceforge.net/p/predef/wiki/Libraries/)
70 * - [glibc 1.3.4 Feature Test Macros](https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html)
71 * - [Architectures](https://sourceforge.net/p/predef/wiki/Architectures/)
72 *
73 * @{
74 */
75
76 /**
77 * `consteval` qualifier replacement for C++20 `consteval`.
78 *
79 * > A `consteval` specifier implies `inline`.
80 * > At most one of the `constexpr`, `consteval`, and `constinit` specifiers is allowed to appear within the same sequence of declaration specifiers.
81 * > ...
82 * > An immediate function is a `constexpr` function,
83 * > and must satisfy the requirements applicable to `constexpr` functions or `constexpr` constructors, as the case may be.
84 *
85 * <p>
86 * Evaluated using the alternative qualifier `constexpr` for C++ < 20,
87 * as it is almost contained within `consteval` but lacks the `immediate function` constraint.
88 * </p>
89 * <p>
90 * Evaluated as `consteval` for C++20.
91 * </p>
92 */
93#if __cplusplus > 201703L
94 #define consteval_cxx20 consteval
95#else
96 #define consteval_cxx20 constexpr
97#endif
98
99 /** Returns true if compiled with >= C++17 */
100 consteval_cxx20 bool is_cxx17() noexcept {
101 #if __cplusplus > 201402L
102 return true;
103 #else
104 return false;
105 #endif
106 }
107 /** Returns true if compiled with >= C++20 */
108 consteval_cxx20 bool is_cxx20() noexcept {
109 #if __cplusplus > 201703L
110 return true;
111 #else
112 return false;
113 #endif
114 }
115 /** Returns true if compiled with >= C++23 */
116 consteval_cxx20 bool is_cxx23() noexcept {
117 #if __cplusplus > 202002L
118 return true;
119 #else
120 return false;
121 #endif
122 }
123 /** Returns true if compiled with >= C++26 */
124 consteval_cxx20 bool is_cxx26() noexcept {
125 #if __cplusplus > 202302L
126 return true;
127 #else
128 return false;
129 #endif
130 }
131
132 /**
133 * `constinit` qualifier replacement for C++20 `constinit`.
134 *
135 * > `constinit` cannot be used together with `constexpr` or `consteval`.
136 * > When the declared variable is a reference, `constinit` is equivalent to `constexpr`.
137 * > When the declared variable is an object,
138 * > `constexpr` mandates that the object must have static initialization and constant destruction
139 * > and makes the object const-qualified, however, `constinit` does not mandate constant destruction and const-qualification.
140 *
141 * <p>
142 * Evaluated using the alternative qualifier `constexpr` for C++ < 20,
143 * as it is almost contained within `constinit` but lacks the loosening of not mandating constant destruction and const-qualification.<br>
144 * FIXME: Due to the above, this replacement might not be suitable: TBD!
145 * </p>
146 * <p>
147 * Evaluated as `constinit` for C++20.
148 * </p>
149 */
150#if __cplusplus > 201703L
151 #define constinit_cxx20 constinit
152#else
153 #define constinit_cxx20 constexpr
154#endif
155
156 /**
157 * `constexpr` qualifier replacement for C++20 `constexpr`.
158 *
159 * > A `constexpr` specifier used in a function or static member variable (since C++17) declaration implies `inline`.
160 *
161 * <p>
162 * Evaluated using the alternative qualifier `inline` for C++ < 20,
163 * as it is implied for `constexpr` functions or static member variables, see above.
164 * </p>
165 * <p>
166 * Evaluated as `constexpr` for C++20, i.e. std::string literals, virtual functions, etc.
167 * </p>
168 */
169#if __cplusplus > 201703L
170 #define constexpr_cxx20 constexpr
171#else
172 #define constexpr_cxx20 inline
173#endif
174
175#if __cplusplus > 202002L
176 #define constexpr_cxx23 constexpr
177#else
178 #define constexpr_cxx23 inline
179#endif
180
181#if __cplusplus > 202302L
182 #define constexpr_cxx26 constexpr
183#else
184 #define constexpr_cxx26 inline
185#endif
186
187
188 /**
189 * Used when designed to declare a function `constexpr`,
190 * but prohibited by its specific implementation.
191 * <p>
192 * Evaluated using the alternative qualifier `inline` for C++ < 23,
193 * as it is implied for `constexpr` functions or static member variables, see constexpr_cxx23.
194 * </p>
195 * <p>
196 * Here it but uses non-literal variables, such as std::lock_guard etc.
197 * As these can't be evaluated at compile time, the standard does
198 * not allow using `constexpr` here.
199 * </p>
200 * <p>
201 * Empty until standard defines otherwise.
202 * </p>
203 * @see constexpr_cxx23
204 */
205 #define constexpr_non_literal_var constexpr_cxx23
206
207 /**
208 * Used when designed to declare a function `constexpr`,
209 * but prohibited by its specific implementation.
210 * <p>
211 * Evaluated using the alternative qualifier `inline` for C++ < 23,
212 * as it is implied for `constexpr` functions or static member variables, see constexpr_cxx23.
213 * </p>
214 * <p>
215 * Here it uses thread-safety related measures like atomic storage
216 * or mutex locks, which are non-literal variables and hence
217 * prohibit the use of `constexpr`.
218 * </p>
219 * @see constexpr_cxx23
220 * @see constexpr_non_literal_var
221 */
222 #define constexpr_atomic constexpr_cxx23
223
224 /**
225 * Wrap C++ extension `__restrict__` covering C99's `restrict` feature keyword.
226 */
227 #if defined(__clang__)
228 #define __restrict_cxx__ __restrict__
229 #elif defined(__GNUC__) && !defined(__clang__)
230 #define __restrict_cxx__ __restrict__
231 #elif defined(_MSC_VER)
232 #define __restrict_cxx__ __restrict
233 #else
234 #define __restrict_cxx__
235 #endif
236
237 #if defined(__clang__)
238 /** Consider using [jau::ctti_name<R, L, A...>()](@ref ctti_name_lambda). */
239 #define JAU_PRETTY_FUNCTION __PRETTY_FUNCTION__
240 #elif defined(__GNUC__) && !defined(__clang__)
241 /** Consider using [jau::ctti_name<R, L, A...>()](@ref ctti_name_lambda). */
242 #define JAU_PRETTY_FUNCTION __PRETTY_FUNCTION__
243 #elif defined(_MSC_VER)
244 /** Consider using [jau::ctti_name<R, L, A...>()](@ref ctti_name_lambda). */
245 #define JAU_PRETTY_FUNCTION __FUNCSIG__
246 #else
247 #error "JAU_PRETTY_FUNCTION not available"
248 #endif
249
250 /**
251 * Returns the demangled given mangled_name if successful,
252 * otherwise the mangled_name.
253 *
254 * Implementation utilizes the [cross-vendor C++ ABI abi::__cxa_demangle()](https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html)
255 * as supported at least on on `gcc` and `clang`.
256 *
257 * May be used to demangle the result of jau::type_name() or jau::type_info::name() if jau::type_info::rtti_available == true,
258 * i.e. RTTI typeif(T) symbols are being used.
259 *
260 * See also [gcc libstdc++ FAQ, Chapter 28](https://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html).
261 *
262 * Further, implementation also checks whether the mangled_name results from [jau::ctti_name<T>()](@ref ctti_name_type)
263 * and cleans up the known `gcc` and `clang` variant of JAU_PRETTY_FUNCTION.
264 *
265 * @param mangled_name mangled name
266 */
267 std::string demangle_name(const char* mangled_name) noexcept;
268
269 #if defined(__clang__)
270 /** Optional generic usage of final keyword w/o negative performance impact. (Disabled) */
271 #define final_opt
272 #elif defined(__GNUC__) && !defined(__clang__)
273 /** Optional generic usage of final keyword w/o negative performance impact. (Enabled) */
274 #define final_opt final
275 #elif defined(_MSC_VER)
276 /** Optional generic usage of final keyword w/o negative performance impact. (Enabled, OK?) */
277 #define final_opt final
278 #else
279 /** Optional generic usage of final keyword w/o negative performance impact. (Enabled, OK?) */
280 #define final_opt final
281 #endif
282
283 /**
284 // *************************************************
285 // *************************************************
286 // *************************************************
287 */
288
289 /**
290 * Convenience type trait for `__has_builtin(__builtin_bit_cast)`.
291 * @tparam Dummy_type just to make template `SFINAE` happy
292 * @see jau::has_builtin_bit_cast()
293 * @see jau::bit_cast()
294 * @see jau::pointer_cast()
295 */
296 template <typename Dummy_type>
298 #if defined __has_builtin && __has_builtin(__builtin_bit_cast)
299 : std::true_type
300 #else
301 : std::false_type
302 #endif
303 {};
304 /**
305 * Value access of has_builtin_bit_cast type trait for convenience ..
306 * @tparam Dummy_type just to make template `SFINAE` happy
307 * @see has_builtin_bit_cast
308 */
309 template <typename Dummy_type> constexpr bool has_builtin_bit_cast_v = has_builtin_bit_cast_t<Dummy_type>::value;
310
311 /**
312 * Query whether `__builtin_bit_cast(Dest_type, arg)` is available
313 * via `__has_builtin(__builtin_bit_cast)`.
314 *
315 * - - - - - - - - - - - - - - -
316 *
317 * Availability of `__builtin_bit_cast(Dest_type, arg)`
318 *
319 * Reflecting my manual platform tests using `test_basictypeconv.cpp`
320 *
321 * Compiler | Version | Architecture | Available |
322 * :--------- | -------: | :------------------ | :-------- |
323 * GCC | 8.3.0 | amd64, arm64, arm32 | no |
324 * GCC | 10.2.1 | amd64 | no |
325 * GCC | 12.2.0 | amd64 | yes |
326 * clang | 9.0.1 | amd64, arm64 | yes |
327 * clang | 11.0.1 | amd64 | yes |
328 *
329 * @return `true` if query subject is available, otherwise not.
330 * @see has_builtin_bit_cast_t
331 * @see bit_cast()
332 * @see pointer_cast()
333 */
335 #if defined __has_builtin && __has_builtin(__builtin_bit_cast)
336 return true;
337 #else
338 return false;
339 #endif
340 }
341
342 /**
343 * A `constexpr` pointer cast implementation for C++17,
344 * inspired by C++20 `bit_cast<>(arg)`.
345 * <p>
346 * If is_builtin_bit_cast_available() evaluates `true`,
347 * implementation uses `__builtin_bit_cast(Dest, src)`.<br>
348 *
349 * Otherwise a simple `reinterpret_cast<Dest>(src)` is utilized,
350 * which officially is questionable to deliver a `constexpr`.
351 * </p>
352 * @tparam Dest the target pointer type
353 * @tparam Source the source pointer argument type
354 * @param src the pointer to convert to Dest pointer type
355 * @return the converted Dest pointer type value
356 * @see jau::has_builtin_bit_cast
357 * @see is_builtin_bit_cast_available()
358 * @see bit_cast()
359 */
360 template <class Dest, class Source>
361 constexpr
362 typename std::enable_if_t<
363 sizeof(Dest) == sizeof(Source) && // NOLINT(bugprone-sizeof-expression): Intended, same pointer size
364 std::is_pointer_v<Source> &&
365 std::is_pointer_v<Dest>,
366 Dest>
367 pointer_cast(const Source& src) noexcept
368 {
369 if constexpr ( is_cxx20() ) {
370 return std::bit_cast<Dest, Source>(src);
371 } else if constexpr ( has_builtin_bit_cast() ) {
372 return __builtin_bit_cast(Dest, src);
373 } else {
374 // not 'really' constexpr .. oops, working though
375 return reinterpret_cast<Dest>( const_cast< std::remove_const_t< std::remove_pointer_t<Source> >* >( src ) );
376 }
377 }
378
379 /**
380 * C++20 `bit_cast<>(arg)` implementation for C++17.
381 * <p>
382 * Utilizing native bit_cast if is_builtin_bit_cast_available(), otherwise `pointer_cast<const packed_t<Dest>*>( &src )->store`.
383 * </p>
384 * @tparam Dest the target type
385 * @tparam Source the source argument type
386 * @param src the value to convert to Dest type
387 * @return the converted Dest type value
388 * @see jau::has_builtin_bit_cast
389 * @see is_builtin_bit_cast_available()
390 * @see pointer_cast()
391 */
392 template <class Dest, class Source>
393 constexpr
394 typename std::enable_if_t<
395 sizeof(Dest) == sizeof(Source) &&
396 std::is_trivially_copyable_v<Dest> &&
397 std::is_trivially_copyable_v<Source>,
398 Dest>
399 bit_cast(const Source& src) noexcept
400 {
401 if constexpr ( is_cxx20() ) {
402 return std::bit_cast<Dest, Source>(src);
403 } else if constexpr ( has_builtin_bit_cast() ) {
404 return __builtin_bit_cast(Dest, src);
405 } else {
406 return pointer_cast<const packed_t<Dest>*>( &src )->store;
407 }
408 }
409
411 #if defined(__SIZEOF_INT128__)
412 return true;
413 #else
414 return false;
415 #endif
416 }
417
418 #if defined(__SIZEOF_INT128__)
419 // Prefer TI mode over __int128 as GCC rejects the latter in pendantic mode
420 #if defined(__GNUG__)
421 typedef int int128_t __attribute__((mode(TI)));
422 typedef unsigned int uint128_t __attribute__((mode(TI)));
423 #else
424 typedef __int128 int128_t;
425 typedef unsigned __int128 uint128_t;
426 #endif
427 #endif
428
429 /** Returns true if compiled with debug information and w/o optimization, i.e. not `defined(NDEBUG) && !defined(DEBUG)`. */
431 #if defined(NDEBUG) && !defined(DEBUG)
432 return false;
433 #else
434 return true;
435 #endif
436 }
437
438 #if defined(__clang__)
439 #define __attrdecl_no_optimize__ __attribute__ ((optnone))
440 #define __attrdef_no_optimize__ __attribute__ ((optnone))
441 #elif defined(__GNUC__) && !defined(__clang__)
442 #define __attrdecl_no_optimize__ __attribute__((optimize("O0")))
443 // #define __attrdecl_no_optimize__ [[gnu::optimize("O0")]]
444 #define __attrdef_no_optimize__
445 #else
446 #define __attrdecl_no_optimize__
447 #define __attrdef_no_optimize__
448 #endif
449
450 /**
451 * Simple unary function wrapper which ensures function call to happen in order and not optimized away.
452 */
453 template <typename UnaryFunc>
455 // asm asm-qualifiers ( AssemblerTemplate : OutputOperands [ : InputOperands [ : Clobbers ] ] )
456 asm volatile("" : "+r,m"(f) : : "memory"); // a nop asm, usually guaranteeing synchronized order and non-optimization
457 f();
458 }
459
460 /// Boolean type without implicit conversion, safe for function parameter
461 enum class Bool : bool {
462 False = false,
463 True = true
464 };
465 constexpr Bool True() noexcept { return Bool::True; }
466 constexpr Bool False() noexcept { return Bool::False; }
467 constexpr Bool makeBool(bool v) noexcept { return v ? Bool::True : Bool::False; }
468
469 constexpr bool value(const Bool rhs) noexcept {
470 return static_cast<bool>(rhs);
471 }
472 constexpr bool operator*(const Bool rhs) noexcept {
473 return static_cast<bool>(rhs);
474 }
475 constexpr Bool operator!(const Bool rhs) noexcept {
476 return Bool(!*rhs);
477 }
478 constexpr Bool operator&&(const Bool lhs, const Bool rhs) noexcept {
479 return Bool(*lhs && *rhs);
480 }
481 constexpr Bool operator||(const Bool lhs, const Bool rhs) noexcept {
482 return Bool(*lhs || *rhs);
483 }
484 constexpr Bool operator^(const Bool lhs, const Bool rhs) noexcept {
485 return Bool(*lhs ^ *rhs);
486 }
487 constexpr Bool operator|(const Bool lhs, const Bool rhs) noexcept {
488 return Bool(*lhs || *rhs);
489 }
490 constexpr Bool operator&(const Bool lhs, const Bool rhs) noexcept {
491 return Bool(*lhs && *rhs);
492 }
493 constexpr Bool& operator|=(Bool& lhs, const Bool rhs) noexcept {
494 lhs = lhs | rhs;
495 return lhs;
496 }
497 constexpr Bool& operator&=(Bool& lhs, const Bool rhs) noexcept {
498 lhs = lhs & rhs;
499 return lhs;
500 }
501 constexpr Bool& operator^=(Bool& lhs, const Bool rhs) noexcept {
502 lhs = lhs ^ rhs;
503 return lhs;
504 }
505 constexpr bool operator==(const Bool lhs, const Bool rhs) noexcept {
506 return *lhs == *rhs;
507 }
508 constexpr std::string_view name(const Bool v) noexcept {
509 if( *v ) {
510 return "true";
511 } else {
512 return "false";
513 }
514 }
515 constexpr std::string to_string(const Bool v) noexcept { return std::string(name(v)); }
516 inline std::ostream & operator << (std::ostream &out, const Bool c) {
517 out << to_string(c);
518 return out;
519 }
520
521 /**
522 * Static compile-time string literal storage.
523 * @tparam N string length including EOS
524 */
525 template<size_t N>
527 {
528 // private:
529 public:
530 char buf[N];
531
532 public:
533 consteval_cxx20 StringLiteral(const char (&str)[N]) noexcept {
534 for (size_t i = 0; i < N; ++i) { buf[i] = str[i]; }
535 }
536 consteval_cxx20 StringLiteral(const StringLiteral& o) noexcept = delete; // violating pattern
537 consteval_cxx20 StringLiteral& operator=(const StringLiteral& o) noexcept = delete; // violating pattern
538
541
542 /// Returns string literal size w/o EOS.
543 consteval_cxx20 size_t size() const noexcept { return N-1; }
544 /// Returns c-string w/ EOS.
545 consteval_cxx20 char const* c_str() const noexcept { return buf; }
546 /// Returns string_view
547 consteval_cxx20 std::string_view view() const noexcept { return std::string_view(buf, N-1); }
548 };
549
550 namespace impl {
551 inline bool runtime_eval(bool v) { return v; }
552 }
553
555 [[maybe_unused]] bool r = v ? true : impl::runtime_eval(v);
556 }
557
558 /**@}*/
559
560} // namespace jau
561
562#endif /* JAU_CPP_LANG_EXT_HPP_ */
consteval_cxx20 StringLiteral(StringLiteral &&o) noexcept=default
consteval_cxx20 StringLiteral(const char(&str)[N]) noexcept
consteval_cxx20 size_t size() const noexcept
Returns string literal size w/o EOS.
consteval_cxx20 StringLiteral & operator=(StringLiteral &&o) noexcept=default
consteval_cxx20 StringLiteral & operator=(const StringLiteral &o) noexcept=delete
consteval_cxx20 char const * c_str() const noexcept
Returns c-string w/ EOS.
consteval_cxx20 StringLiteral(const StringLiteral &o) noexcept=delete
consteval_cxx20 std::string_view view() const noexcept
Returns string_view.
std::ostream & operator<<(std::ostream &out, const bitfield_t< StorageType, BitSize > &v)
Definition bitfield.hpp:486
consteval_cxx20 bool is_builtin_int128_available() noexcept
constexpr bool value(const Bool rhs) noexcept
constexpr bool operator*(const Bool rhs) noexcept
constexpr Bool & operator&=(Bool &lhs, const Bool rhs) noexcept
constexpr Bool makeBool(bool v) noexcept
constexpr Bool & operator^=(Bool &lhs, const Bool rhs) noexcept
consteval_cxx20 bool is_cxx23() noexcept
Returns true if compiled with >= C++23.
void callNotOptimize(UnaryFunc f) __attrdef_no_optimize__
Simple unary function wrapper which ensures function call to happen in order and not optimized away.
consteval_cxx20 bool is_cxx20() noexcept
Returns true if compiled with >= C++20.
constexpr bool has_builtin_bit_cast_v
Value access of has_builtin_bit_cast type trait for convenience .
constexpr Bool False() noexcept
constexpr Bool operator^(const Bool lhs, const Bool rhs) noexcept
consteval_cxx20 bool is_cxx17() noexcept
Returns true if compiled with >= C++17.
constexpr Bool operator|(const Bool lhs, const Bool rhs) noexcept
constexpr Bool True() noexcept
constexpr std::enable_if_t< sizeof(Dest)==sizeof(Source) &&std::is_trivially_copyable_v< Dest > &&std::is_trivially_copyable_v< Source >, Dest > bit_cast(const Source &src) noexcept
C++20 bit_cast<>(arg) implementation for C++17.
consteval_cxx20 bool is_debug_enabled() noexcept
Returns true if compiled with debug information and w/o optimization, i.e.
constexpr Bool operator&(const Bool lhs, const Bool rhs) noexcept
constexpr Bool operator&&(const Bool lhs, const Bool rhs) noexcept
constexpr Bool & operator|=(Bool &lhs, const Bool rhs) noexcept
consteval_cxx20 bool has_builtin_bit_cast() noexcept
Query whether __builtin_bit_cast(Dest_type, arg) is available via __has_builtin(__builtin_bit_cast).
constexpr std::enable_if_t< sizeof(Dest)==sizeof(Source) &&std::is_pointer_v< Source > &&std::is_pointer_v< Dest >, Dest > pointer_cast(const Source &src) noexcept
A constexpr pointer cast implementation for C++17, inspired by C++20 bit_cast<>(arg).
consteval_cxx20 void consteval_assert(bool v)
constexpr Bool operator||(const Bool lhs, const Bool rhs) noexcept
std::string demangle_name(const char *mangled_name) noexcept
Returns the demangled given mangled_name if successful, otherwise the mangled_name.
Definition debug.cpp:57
#define __attrdef_no_optimize__
constexpr std::string_view name(const Bool v) noexcept
constexpr Bool operator!(const Bool rhs) noexcept
#define consteval_cxx20
consteval qualifier replacement for C++20 consteval.
consteval_cxx20 bool is_cxx26() noexcept
Returns true if compiled with >= C++26.
Bool
Boolean type without implicit conversion, safe for function parameter.
bool runtime_eval(bool v)
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition backtrace.hpp:32
bool operator==(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
std::string to_string(const bit_order_t v) noexcept
Return std::string representation of the given bit_order_t.
STL namespace.
Convenience type trait for __has_builtin(__builtin_bit_cast).
static std::string f(uint32_t v)