25#ifndef JAU_CPP_LANG_EXT_HPP_
26#define JAU_CPP_LANG_EXT_HPP_
35#if __cplusplus > 201703L
39#if __cplusplus > 202002L
94#if __cplusplus > 201703L
95 #define consteval_cxx20 consteval
97 #define consteval_cxx20 constexpr
102 #if __cplusplus > 201402L
110 #if __cplusplus > 201703L
118 #if __cplusplus > 202002L
126 #if __cplusplus > 202302L
151#if __cplusplus > 201703L
152 #define constinit_cxx20 constinit
154 #define constinit_cxx20 constexpr
170#if __cplusplus > 201703L
171 #define constexpr_cxx20 constexpr
173 #define constexpr_cxx20 inline
176#if __cplusplus > 202002L
177 #define constexpr_cxx23 constexpr
179 #define constexpr_cxx23 inline
182#if __cplusplus > 202302L
183 #define constexpr_cxx26 constexpr
185 #define constexpr_cxx26 inline
206 #define constexpr_non_literal_var constexpr_cxx23
223 #define constexpr_atomic constexpr_cxx23
228 #if defined(__clang__)
229 #define __restrict_cxx__ __restrict__
230 #elif defined(__GNUC__) && !defined(__clang__)
231 #define __restrict_cxx__ __restrict__
232 #elif defined(_MSC_VER)
233 #define __restrict_cxx__ __restrict
235 #define __restrict_cxx__
238 #if defined(__clang__)
240 #define JAU_PRETTY_FUNCTION __PRETTY_FUNCTION__
241 #elif defined(__GNUC__) && !defined(__clang__)
243 #define JAU_PRETTY_FUNCTION __PRETTY_FUNCTION__
244 #elif defined(_MSC_VER)
246 #define JAU_PRETTY_FUNCTION __FUNCSIG__
248 #error "JAU_PRETTY_FUNCTION not available"
268 std::string
demangle_name(
const char* mangled_name)
noexcept;
270 #if defined(__clang__)
273 #elif defined(__GNUC__) && !defined(__clang__)
275 #define final_opt final
276 #elif defined(_MSC_VER)
278 #define final_opt final
281 #define final_opt final
297 template <
typename Dummy_type>
299 #if defined __has_builtin && __has_builtin(__builtin_bit_cast)
336 #if defined __has_builtin && __has_builtin(__builtin_bit_cast)
361 template <
class Dest,
class Source>
363 typename std::enable_if_t<
364 sizeof(Dest) ==
sizeof(Source) &&
365 std::is_pointer_v<Source> &&
366 std::is_pointer_v<Dest>,
371 return std::bit_cast<Dest, Source>(src);
373 return __builtin_bit_cast(Dest, src);
376 return reinterpret_cast<Dest
>(
const_cast< std::remove_const_t< std::remove_pointer_t<Source>
>* >( src ) );
393 template <
class Dest,
class Source>
395 typename std::enable_if_t<
396 sizeof(Dest) ==
sizeof(Source) &&
397 std::is_trivially_copyable_v<Dest> &&
398 std::is_trivially_copyable_v<Source>,
403 return std::bit_cast<Dest, Source>(src);
405 return __builtin_bit_cast(Dest, src);
412 #if defined(__SIZEOF_INT128__)
419 #if defined(__SIZEOF_INT128__)
421 #if defined(__GNUG__)
422 typedef int int128_t __attribute__((mode(TI)));
423 typedef unsigned int uint128_t __attribute__((mode(TI)));
425 typedef __int128 int128_t;
426 typedef unsigned __int128 uint128_t;
432 #if defined(NDEBUG) && !defined(DEBUG)
439 #if defined(__clang__)
440 #define __attrdecl_no_optimize__ __attribute__ ((optnone))
441 #define __attrdef_no_optimize__ __attribute__ ((optnone))
442 #elif defined(__GNUC__) && !defined(__clang__)
443 #define __attrdecl_no_optimize__ __attribute__((optimize("O0")))
445 #define __attrdef_no_optimize__
447 #define __attrdecl_no_optimize__
448 #define __attrdef_no_optimize__
454 template <
typename UnaryFunc>
457 asm volatile(
"" :
"+r,m"(
f) : :
"memory");
471 return static_cast<bool>(rhs);
474 return static_cast<bool>(rhs);
480 return Bool(*lhs && *rhs);
483 return Bool(*lhs || *rhs);
486 return Bool(*lhs ^ *rhs);
489 return Bool(*lhs || *rhs);
492 return Bool(*lhs && *rhs);
509 constexpr std::string_view
name(
const Bool v)
noexcept {
575#define E_FILE_LINE __FILE__, __LINE__
587#define JAU_EXPAND(...) JAU_EXPAND4(JAU_EXPAND4(JAU_EXPAND4(JAU_EXPAND4(__VA_ARGS__))))
588#define JAU_EXPAND4(...) JAU_EXPAND3(JAU_EXPAND3(JAU_EXPAND3(JAU_EXPAND3(__VA_ARGS__))))
589#define JAU_EXPAND3(...) JAU_EXPAND2(JAU_EXPAND2(JAU_EXPAND2(JAU_EXPAND2(__VA_ARGS__))))
590#define JAU_EXPAND2(...) JAU_EXPAND1(JAU_EXPAND1(JAU_EXPAND1(JAU_EXPAND1(__VA_ARGS__))))
591#define JAU_EXPAND1(...) __VA_ARGS__
595#define JAU_FOR_EACH1_LIST(macro, ...) \
596 __VA_OPT__(JAU_EXPAND(JAU_FOR_EACH1_LIST_HELPER(macro, __VA_ARGS__)))
597#define JAU_FOR_EACH1_LIST_HELPER(macro, a1, ...) \
599 __VA_OPT__(, JAU_FOR_EACH1_LIST_AGAIN JAU_PARENS (macro, __VA_ARGS__))
600#define JAU_FOR_EACH1_LIST_AGAIN() JAU_FOR_EACH1_LIST_HELPER
602#define JAU_DECLTYPE_VALUE(type) decltype(type)
606#define JAU_FOR_EACH2(macro, type, ...) \
607 __VA_OPT__(JAU_EXPAND(JAU_FOR_EACH2_HELPER(macro, type, __VA_ARGS__)))
608#define JAU_FOR_EACH2_HELPER(macro, type, a1, ...) \
610 __VA_OPT__(JAU_FOR_EACH2_AGAIN JAU_PARENS (macro, type, __VA_ARGS__))
611#define JAU_FOR_EACH2_AGAIN() JAU_FOR_EACH2_HELPER
613#define JAU_FOR_EACH2_LIST(macro, type, ...) \
614 __VA_OPT__(JAU_EXPAND(JAU_FOR_EACH2_LIST_HELPER(macro, type, __VA_ARGS__)))
615#define JAU_FOR_EACH2_LIST_HELPER(macro, type, a1, ...) \
617 __VA_OPT__(, JAU_FOR_EACH2_LIST_AGAIN JAU_PARENS (macro, type, __VA_ARGS__))
618#define JAU_FOR_EACH2_LIST_AGAIN() JAU_FOR_EACH2_LIST_HELPER
620#define JAU_FOR_EACH2_VALUE(macro, type, value, ...) \
621 __VA_OPT__(JAU_EXPAND(JAU_FOR_EACH2_VALUE_HELPER(macro, type, value, __VA_ARGS__)))
622#define JAU_FOR_EACH2_VALUE_HELPER(macro, type, value, a1, ...) \
623 macro(type, a1, value) \
624 __VA_OPT__(JAU_FOR_EACH2_VALUE_AGAIN JAU_PARENS (macro, type, value, __VA_ARGS__))
625#define JAU_FOR_EACH2_VALUE_AGAIN() JAU_FOR_EACH2_VALUE_HELPER
std::string to_string(const endian_t v) noexcept
Return std::string representation of the given endian.
std::ostream & operator<<(std::ostream &out, const bitfield_t< StorageType, BitSize > &v)
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.
#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.
bool operator==(const callocator< T1 > &lhs, const callocator< T2 > &rhs) noexcept
Simple pre-defined value tuple [int64_t, size_t, bool] for structured bindings to multi-values.
size_t s
a size_t value, e.g.
bool b
a boolean value, e.g.
int64_t v
a int64_t value, e.g.
Simple pre-defined value pair [size_t, bool] for structured bindings to multi-values.
size_t s
a size_t value, e.g.
bool b
a boolean value, e.g.
Simple pre-defined value tuple [uint64_t, size_t, bool] for structured bindings to multi-values.
bool b
a boolean value, e.g.
uint64_t v
a uint64_t value, e.g.
size_t s
a size_t value, e.g.
Convenience type trait for __has_builtin(__builtin_bit_cast).
static std::string f(uint32_t v)