25#ifndef JAU_CPP_LANG_EXT_HPP_
26#define JAU_CPP_LANG_EXT_HPP_
81#if __cplusplus > 201703L
82 #define consteval_cxx20 consteval
84 #define consteval_cxx20 constexpr
89 #if __cplusplus > 201402L
97 #if __cplusplus > 201703L
105 #if __cplusplus > 202002L
113 #if __cplusplus > 202302L
138#if __cplusplus > 201703L
139 #define constinit_cxx20 constinit
141 #define constinit_cxx20 constexpr
157#if __cplusplus > 201703L
158 #define constexpr_cxx20 constexpr
160 #define constexpr_cxx20 inline
163#if __cplusplus > 202002L
164 #define constexpr_cxx23 constexpr
166 #define constexpr_cxx23 inline
169#if __cplusplus > 202302L
170 #define constexpr_cxx26 constexpr
172 #define constexpr_cxx26 inline
193 #define constexpr_non_literal_var inline
210 #define constexpr_atomic inline
215#if defined(__clang__)
216 #define __restrict_cxx__ __restrict__
217#elif defined(__GNUC__) && !defined(__clang__)
218 #define __restrict_cxx__ __restrict__
219#elif defined(_MSC_VER)
220 #define __restrict_cxx__ __restrict
222 #define __restrict_cxx__
225 #if defined(__clang__)
226 #if __has_feature(cxx_rtti)
236 #define __cxx_rtti_available__ 1
239 #if defined(__GXX_RTTI) || defined(_CPPRTTI)
249 #define __cxx_rtti_available__ 1
253#if defined(__cxx_rtti_available__)
258 template<
typename _Dummy>
struct is_rtti_available_t : std::true_type {};
275 #if defined(__cxx_rtti_available__)
282 #if defined(__clang__)
284 #define JAU_PRETTY_FUNCTION __PRETTY_FUNCTION__
285 #elif defined(__GNUC__) && !defined(__clang__)
287 #define JAU_PRETTY_FUNCTION __PRETTY_FUNCTION__
288 #elif defined(_MSC_VER)
290 #define JAU_PRETTY_FUNCTION __FUNCSIG__
292 #error "JAU_PRETTY_FUNCTION not available"
308 return JAU_PRETTY_FUNCTION;
348 template<
typename R,
typename L,
typename...A>
350 return JAU_PRETTY_FUNCTION;
370 std::string
demangle_name(
const char* mangled_name)
noexcept;
437 const char* signature;
455 #if defined(__cxx_rtti_available__)
458 #if defined(__clang__)
460 #elif defined(__GNUC__) && !defined(__clang__)
468 static constexpr bool is_valid(
const char* signature)
noexcept {
469 return nullptr != signature && 0 < ::strlen(signature);
474 if(
nullptr == signature ) {
475 fprintf(stderr,
"ABORT @ %s:%d %s: CTTI signature nullptr\n", __FILE__, __LINE__, __func__);
477 }
else if( 0 == ::strlen(signature) ) {
478 fprintf(stderr,
"ABORT @ %s:%d %s: CTTI signature zero sized\n", __FILE__, __LINE__, __func__);
487 : signature(""), hash_value(
std::hash<
std::string_view>{}(std::string_view(signature)) )
501 : signature(info_.name()), hash_value( info_.hash_code() )
514 : signature( signature_ ), hash_value(
nullptr != signature ? std::hash<std::string_view>{}(std::string_view(signature)) : 0 )
528 return signature == rhs.signature ||
530 hash_value == rhs.hash_value &&
531 0 == ::strcmp(signature, rhs.signature)
551 size_t hash_code() const noexcept {
return hash_value; }
554 const char*
name() const noexcept
555 {
return signature; }
577#if defined(__cxx_rtti_available__)
599 template<
typename R,
typename L,
typename...A>
601#if defined(__cxx_rtti_available__)
619#if defined(__cxx_rtti_available__)
620 return typeid(T).name();
622 return ctti_name<T>();
637 template<
typename R,
typename L,
typename...A>
639#if defined(__cxx_rtti_available__)
640 return typeid(L).name();
652 #if defined __has_builtin
653 #if __has_builtin(__builtin_bit_cast)
654 #define __has_builtin_bit_cast 1
665 template <
typename Dummy_type>
667 #if defined __has_builtin_bit_cast
680 #if !defined __has_builtin_bit_cast
687 #define __builtin_bit_cast(Dest_type,Value_arg) 0
691 template<
class Dummy_type>
693 std::enable_if_t< has_builtin_bit_cast_v<Dummy_type>,
bool> =
true ) noexcept
698 template<
class Dummy_type>
700 std::enable_if_t< !has_builtin_bit_cast_v<Dummy_type>,
bool> =
true ) noexcept
729 return impl::has_builtin_bit_cast_impl<bool>();
745 template <
class Dest,
class Source>
747 typename std::enable_if_t<
748 sizeof(Dest) ==
sizeof(Source) &&
749 std::is_trivially_copyable_v<Dest> &&
750 std::is_trivially_copyable_v<Source>,
780 template <
class Dest,
class Source>
782 typename std::enable_if_t<
783 sizeof(Dest) ==
sizeof(Source) &&
784 std::is_pointer_v<Source> &&
785 std::is_pointer_v<Dest>,
793 return reinterpret_cast<Dest
>(
const_cast< std::remove_const_t< std::remove_pointer_t<Source>
>* >( src ) );
798 #if defined(__SIZEOF_INT128__)
805 #if defined(__SIZEOF_INT128__)
807 #if defined(__GNUG__)
808 typedef int int128_t __attribute__((mode(TI)));
809 typedef unsigned int uint128_t __attribute__((mode(TI)));
811 typedef __int128 int128_t;
812 typedef unsigned __int128 uint128_t;
818 #if defined(NDEBUG) && !defined(DEBUG)
Generic type information using either Runtime type information (RTTI) or Compile time type informatio...
static constexpr bool is_valid(const char *signature) noexcept
Returns true if given signature is not nullptr and has a string length > 0, otherwise false.
static void abort_invalid(const char *signature) noexcept
Aborts program execution if given signature is nullptr or has a string length == 0.
type_info() noexcept
Constructor for an empty type_info instance, i.e.
size_t hash_code() const noexcept
Returns an unspecified hash code of this instance.
type_info(const char *signature_) noexcept
Constructor using a const char* signature with a static storage duration.
static constexpr const bool limited_lambda_id
Static constexpr boolean indicating whether resulting type_info uniqueness is limited for lambda func...
const char * name() const noexcept
Returns the type name, compiler implementation specific.
std::string demangled_name() const noexcept
Return the demangle_name() of name().
constexpr bool operator==(const type_info &rhs) const noexcept
Return true if both instances are equal.
bool operator!=(const type_info &rhs) const noexcept
type_info(const std::type_info &info_) noexcept
Constructor using an RTTI std::type_info reference, i.e.
consteval_cxx20 bool is_rtti_available() noexcept
Returns true if compiled with RTTI available.
jau::type_info make_ctti() noexcept
Constructs a jau::type_info instance based on given type T using template Compile Time Type Informati...
consteval_cxx20 bool is_builtin_int128_available() noexcept
consteval_cxx20 bool is_cxx23() noexcept
Returns true if compiled with >= C++23.
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 .
consteval_cxx20 bool is_cxx17() noexcept
Returns true if compiled with >= C++17.
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 const char * ctti_name() noexcept
Returns the type name of given type T using template Compile Time Type Information (CTTI) only with s...
constexpr bool is_rtti_available_v
Template type trait helper evaluating true if RTTI is available, otherwise false.
std::string demangle_name(const char *mangled_name) noexcept
Returns the demangled given mangled_name if successful, otherwise the mangled_name.
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).
#define __builtin_bit_cast(Dest_type, Value_arg)
Dummy definition in the absence of this builtin function as required to have this compilation unit co...
#define consteval_cxx20
consteval qualifier replacement for C++20 consteval.
const char * type_name() noexcept
Returns the type name of given type T using template Compile Time Type Information (CTTI) only via RT...
consteval_cxx20 bool is_builtin_bit_cast_available() noexcept
Query whether __builtin_bit_cast(Dest_type, arg) is available, using jau::has_builtin_bit_cast.
consteval_cxx20 bool is_cxx26() noexcept
Returns true if compiled with >= C++26.
consteval_cxx20 bool has_builtin_bit_cast_impl(std::enable_if_t< has_builtin_bit_cast_v< Dummy_type >, bool >=true) noexcept
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Convenience type trait for __has_builtin(__builtin_bit_cast).
Template type trait evaluating std::true_type{} if RTTI is available, otherwise std::false_type{}.