25#ifndef JAU_CPP_LANG_EXT_HPP_
26#define JAU_CPP_LANG_EXT_HPP_
36#if __cplusplus > 201703L
40#if __cplusplus > 202002L
95#if __cplusplus > 201703L
96 #define consteval_cxx20 consteval
98 #define consteval_cxx20 constexpr
103 #if __cplusplus > 201402L
111 #if __cplusplus > 201703L
119 #if __cplusplus > 202002L
127 #if __cplusplus > 202302L
152#if __cplusplus > 201703L
153 #define constinit_cxx20 constinit
155 #define constinit_cxx20 constexpr
171#if __cplusplus > 201703L
172 #define constexpr_cxx20 constexpr
174 #define constexpr_cxx20 inline
177#if __cplusplus > 202002L
178 #define constexpr_cxx23 constexpr
180 #define constexpr_cxx23 inline
183#if __cplusplus > 202302L
184 #define constexpr_cxx26 constexpr
186 #define constexpr_cxx26 inline
207 #define constexpr_non_literal_var constexpr_cxx23
224 #define constexpr_atomic constexpr_cxx23
229 #if defined(__clang__)
230 #define __restrict_cxx__ __restrict__
231 #elif defined(__GNUC__) && !defined(__clang__)
232 #define __restrict_cxx__ __restrict__
233 #elif defined(_MSC_VER)
234 #define __restrict_cxx__ __restrict
236 #define __restrict_cxx__
239 #if defined(__clang__)
241 #define JAU_PRETTY_FUNCTION __PRETTY_FUNCTION__
242 #elif defined(__GNUC__) && !defined(__clang__)
244 #define JAU_PRETTY_FUNCTION __PRETTY_FUNCTION__
245 #elif defined(_MSC_VER)
247 #define JAU_PRETTY_FUNCTION __FUNCSIG__
249 #error "JAU_PRETTY_FUNCTION not available"
269 std::string
demangle_name(
const char* mangled_name)
noexcept;
271 #if defined(__clang__)
274 #elif defined(__GNUC__) && !defined(__clang__)
276 #define final_opt final
277 #elif defined(_MSC_VER)
279 #define final_opt final
282 #define final_opt final
298 template <
typename Dummy_type>
300 #if defined __has_builtin && __has_builtin(__builtin_bit_cast)
337 #if defined __has_builtin && __has_builtin(__builtin_bit_cast)
362 template <
class Dest,
class Source>
364 typename std::enable_if_t<
365 sizeof(Dest) ==
sizeof(Source) &&
366 std::is_pointer_v<Source> &&
367 std::is_pointer_v<Dest>,
372 return std::bit_cast<Dest, Source>(src);
374 return __builtin_bit_cast(Dest, src);
377 return reinterpret_cast<Dest
>(
const_cast< std::remove_const_t< std::remove_pointer_t<Source>
>* >( src ) );
394 template <
class Dest,
class Source>
396 typename std::enable_if_t<
397 sizeof(Dest) ==
sizeof(Source) &&
398 std::is_trivially_copyable_v<Dest> &&
399 std::is_trivially_copyable_v<Source>,
404 return std::bit_cast<Dest, Source>(src);
406 return __builtin_bit_cast(Dest, src);
413 #if defined(__SIZEOF_INT128__)
420 #if defined(__SIZEOF_INT128__)
422 #if defined(__GNUG__)
423 typedef int int128_t __attribute__((mode(TI)));
424 typedef unsigned int uint128_t __attribute__((mode(TI)));
426 typedef __int128 int128_t;
427 typedef unsigned __int128 uint128_t;
433 #if defined(NDEBUG) && !defined(DEBUG)
440 #if defined(__clang__)
441 #define __attrdecl_no_optimize__ __attribute__ ((optnone))
442 #define __attrdef_no_optimize__ __attribute__ ((optnone))
443 #elif defined(__GNUC__) && !defined(__clang__)
444 #define __attrdecl_no_optimize__ __attribute__((optimize("O0")))
446 #define __attrdef_no_optimize__
448 #define __attrdecl_no_optimize__
449 #define __attrdef_no_optimize__
455 template <
typename UnaryFunc>
458 asm volatile(
"" :
"+r,m"(
f) : :
"memory");
474 inline __attribute__((always_inline))
478 std::rethrow_exception(eptr);
479 }
catch (
const std::exception &e) {
480 ::fprintf(stderr,
"Exception caught @ %s:%d: %s\n", file, line, e.what());
488 template<
class UnaryPredicate>
490 std::exception_ptr eptr;
495 eptr = std::current_exception();
508 template<
class UnaryPredicate>
510 std::exception_ptr eptr;
514 eptr = std::current_exception();
517 return std::string();
542 return static_cast<bool>(rhs);
545 return static_cast<bool>(rhs);
551 return Bool(*lhs && *rhs);
554 return Bool(*lhs || *rhs);
557 return Bool(*lhs ^ *rhs);
560 return Bool(*lhs || *rhs);
563 return Bool(*lhs && *rhs);
580 constexpr std::string_view
name(
const Bool v)
noexcept {
641 inline bool runtime_eval(
bool v) {
return v; }
645 [[maybe_unused]]
bool r = v ? true : impl::runtime_eval(v);
657#define E_FILE_LINE __FILE__, __LINE__
669#define JAU_EXPAND(...) JAU_EXPAND4(JAU_EXPAND4(JAU_EXPAND4(JAU_EXPAND4(__VA_ARGS__))))
670#define JAU_EXPAND4(...) JAU_EXPAND3(JAU_EXPAND3(JAU_EXPAND3(JAU_EXPAND3(__VA_ARGS__))))
671#define JAU_EXPAND3(...) JAU_EXPAND2(JAU_EXPAND2(JAU_EXPAND2(JAU_EXPAND2(__VA_ARGS__))))
672#define JAU_EXPAND2(...) JAU_EXPAND1(JAU_EXPAND1(JAU_EXPAND1(JAU_EXPAND1(__VA_ARGS__))))
673#define JAU_EXPAND1(...) __VA_ARGS__
677#define JAU_FOR_EACH1_LIST(macro, ...) \
678 __VA_OPT__(JAU_EXPAND(JAU_FOR_EACH1_LIST_HELPER(macro, __VA_ARGS__)))
679#define JAU_FOR_EACH1_LIST_HELPER(macro, a1, ...) \
681 __VA_OPT__(, JAU_FOR_EACH1_LIST_AGAIN JAU_PARENS (macro, __VA_ARGS__))
682#define JAU_FOR_EACH1_LIST_AGAIN() JAU_FOR_EACH1_LIST_HELPER
684#define JAU_DECLTYPE_VALUE(type) decltype(type)
685#define JAU_NOREF_DECLTYPE_VALUE(type) std::remove_reference_t<decltype(type)>
689#define JAU_FOR_EACH2(macro, type, ...) \
690 __VA_OPT__(JAU_EXPAND(JAU_FOR_EACH2_HELPER(macro, type, __VA_ARGS__)))
691#define JAU_FOR_EACH2_HELPER(macro, type, a1, ...) \
693 __VA_OPT__(JAU_FOR_EACH2_AGAIN JAU_PARENS (macro, type, __VA_ARGS__))
694#define JAU_FOR_EACH2_AGAIN() JAU_FOR_EACH2_HELPER
696#define JAU_FOR_EACH2_LIST(macro, type, ...) \
697 __VA_OPT__(JAU_EXPAND(JAU_FOR_EACH2_LIST_HELPER(macro, type, __VA_ARGS__)))
698#define JAU_FOR_EACH2_LIST_HELPER(macro, type, a1, ...) \
700 __VA_OPT__(, JAU_FOR_EACH2_LIST_AGAIN JAU_PARENS (macro, type, __VA_ARGS__))
701#define JAU_FOR_EACH2_LIST_AGAIN() JAU_FOR_EACH2_LIST_HELPER
703#define JAU_FOR_EACH2_VALUE(macro, type, value, ...) \
704 __VA_OPT__(JAU_EXPAND(JAU_FOR_EACH2_VALUE_HELPER(macro, type, value, __VA_ARGS__)))
705#define JAU_FOR_EACH2_VALUE_HELPER(macro, type, value, a1, ...) \
706 macro(type, a1, value) \
707 __VA_OPT__(JAU_FOR_EACH2_VALUE_AGAIN JAU_PARENS (macro, type, value, __VA_ARGS__))
708#define JAU_FOR_EACH2_VALUE_AGAIN() JAU_FOR_EACH2_VALUE_HELPER
std::string_view 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 handle_exception(std::exception_ptr eptr, const char *file, int line) noexcept
Handle given optional exception (nullable std::exception_ptr) and send std::exception::what() message...
bool do_noexcept(UnaryPredicate p) noexcept
No throw wrap for given unary predicate p action. Returns true for success (no exception),...
std::string string_noexcept(UnaryPredicate p) noexcept
No throw wrap for given unary predicate p producing a std::string. Returns an empty string if p cause...
__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.
Simple pre-defined value pair [uint8_t*, size_t, bool] for structured bindings to multi-values.
uint8_t * p
a uint8_t* pointer value
bool b
a boolean 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)