File indexing completed on 2025-09-13 08:38:30
0001 #ifndef BOOST_LEAF_DETAIL_DEMANGLE_HPP_INCLUDED
0002 #define BOOST_LEAF_DETAIL_DEMANGLE_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <boost/leaf/config.hpp>
0018 #include <iosfwd>
0019 #include <cstdlib>
0020
0021 #if BOOST_LEAF_CFG_DIAGNOSTICS
0022
0023
0024
0025
0026 #if defined(__has_include) && (!defined(__GNUC__) || defined(__clang__) || (__GNUC__ + 0) >= 5)
0027 # if __has_include(<cxxabi.h>)
0028 # define BOOST_LEAF_HAS_CXXABI_H
0029 # endif
0030 #elif defined(__GLIBCXX__) || defined(__GLIBCPP__)
0031 # define BOOST_LEAF_HAS_CXXABI_H
0032 #endif
0033
0034 #if defined(BOOST_LEAF_HAS_CXXABI_H)
0035 # include <cxxabi.h>
0036
0037
0038
0039 # if defined(__GABIXX_CXXABI_H__)
0040 # undef BOOST_LEAF_HAS_CXXABI_H
0041 # endif
0042 #endif
0043
0044 #endif
0045
0046 namespace boost { namespace leaf {
0047
0048 namespace detail
0049 {
0050
0051
0052
0053 template <int S1, int S2, int I, bool = S1 >= S2>
0054 struct cpp11_prefix
0055 {
0056 BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&)[S1], char const (&)[S2]) noexcept
0057 {
0058 return false;
0059 }
0060 };
0061 template <int S1, int S2, int I>
0062 struct cpp11_prefix<S1, S2, I, true>
0063 {
0064 BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&str)[S1], char const (&prefix)[S2]) noexcept
0065 {
0066 return str[I] == prefix[I] && cpp11_prefix<S1, S2, I - 1>::check(str, prefix);
0067 }
0068 };
0069 template <int S1, int S2>
0070 struct cpp11_prefix<S1, S2, 0, true>
0071 {
0072 BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&str)[S1], char const (&prefix)[S2]) noexcept
0073 {
0074 return str[0] == prefix[0];
0075 }
0076 };
0077 template <int S1, int S2>
0078 BOOST_LEAF_ALWAYS_INLINE constexpr int check_prefix(char const (&str)[S1], char const (&prefix)[S2]) noexcept
0079 {
0080 return cpp11_prefix<S1, S2, S2 - 2>::check(str, prefix) ? S2 - 1 : 0;
0081 }
0082
0083
0084
0085 template <int S1, int S2, int I1, int I2, bool = S1 >= S2>
0086 struct cpp11_suffix
0087 {
0088 BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&)[S1], char const (&)[S2]) noexcept
0089 {
0090 return false;
0091 }
0092 };
0093 template <int S1, int S2, int I1, int I2>
0094 struct cpp11_suffix<S1, S2, I1, I2, true>
0095 {
0096 BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&str)[S1], char const (&suffix)[S2]) noexcept
0097 {
0098 return str[I1] == suffix[I2] && cpp11_suffix<S1, S2, I1 - 1, I2 - 1>::check(str, suffix);
0099 }
0100 };
0101 template <int S1, int S2, int I1>
0102 struct cpp11_suffix<S1, S2, I1, 0, true>
0103 {
0104 BOOST_LEAF_ALWAYS_INLINE constexpr static bool check(char const (&str)[S1], char const (&suffix)[S2]) noexcept
0105 {
0106 return str[I1] == suffix[0];
0107 }
0108 };
0109 template <int S1, int S2>
0110 BOOST_LEAF_ALWAYS_INLINE constexpr int check_suffix(char const (&str)[S1], char const (&suffix)[S2]) noexcept
0111 {
0112 return cpp11_suffix<S1, S2, S1 - 2, S2 - 2>::check(str, suffix) ? S1 - S2 : 0;
0113 }
0114 }
0115
0116 namespace n
0117 {
0118 struct r
0119 {
0120 char const * name;
0121 int len;
0122 r(char const * name, int len) noexcept:
0123 name(name),
0124 len(len)
0125 {
0126 }
0127 template <class CharT, class Traits>
0128 friend std::ostream & operator<<(std::basic_ostream<CharT, Traits> & os, r const & pn)
0129 {
0130 return os.write(pn.name, pn.len);
0131 }
0132 };
0133
0134 template <class T>
0135 BOOST_LEAF_ALWAYS_INLINE r p()
0136 {
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147 #define BOOST_LEAF_P(P) (sizeof(char[1 + detail::check_prefix(BOOST_LEAF_PRETTY_FUNCTION, P)]) - 1)
0148
0149 int const p01 = BOOST_LEAF_P("r boost::leaf::n::p() [T = ");
0150 int const p02 = BOOST_LEAF_P("r __cdecl boost::leaf::n::p(void) [T = ");
0151 int const p03 = BOOST_LEAF_P("r __stdcall boost::leaf::n::p(void) [T = ");
0152 int const p04 = BOOST_LEAF_P("r __fastcall boost::leaf::n::p(void) [T = ");
0153
0154 int const p05 = BOOST_LEAF_P("boost::leaf::n::r boost::leaf::n::p() [T = ");
0155 int const p06 = BOOST_LEAF_P("boost::leaf::n::r __cdecl boost::leaf::n::p(void) [T = ");
0156 int const p07 = BOOST_LEAF_P("boost::leaf::n::r __stdcall boost::leaf::n::p(void) [T = ");
0157 int const p08 = BOOST_LEAF_P("boost::leaf::n::r __fastcall boost::leaf::n::p(void) [T = ");
0158
0159 int const p09 = BOOST_LEAF_P("boost::leaf::n::r boost::leaf::n::p() [with T = ");
0160 int const p10 = BOOST_LEAF_P("boost::leaf::n::r __cdecl boost::leaf::n::p() [with T = ");
0161 int const p11 = BOOST_LEAF_P("boost::leaf::n::r __stdcall boost::leaf::n::p() [with T = ");
0162 int const p12 = BOOST_LEAF_P("boost::leaf::n::r __fastcall boost::leaf::n::p() [with T = ");
0163
0164 int const p13 = BOOST_LEAF_P("struct boost::leaf::n::r __cdecl boost::leaf::n::p<struct ");
0165 int const p14 = BOOST_LEAF_P("struct boost::leaf::n::r __stdcall boost::leaf::n::p<struct ");
0166 int const p15 = BOOST_LEAF_P("struct boost::leaf::n::r __fastcall boost::leaf::n::p<struct ");
0167
0168 int const p16 = BOOST_LEAF_P("struct boost::leaf::n::r __cdecl boost::leaf::n::p<class ");
0169 int const p17 = BOOST_LEAF_P("struct boost::leaf::n::r __stdcall boost::leaf::n::p<class ");
0170 int const p18 = BOOST_LEAF_P("struct boost::leaf::n::r __fastcall boost::leaf::n::p<class ");
0171
0172 int const p19 = BOOST_LEAF_P("struct boost::leaf::n::r __cdecl boost::leaf::n::p<enum ");
0173 int const p20 = BOOST_LEAF_P("struct boost::leaf::n::r __stdcall boost::leaf::n::p<enum ");
0174 int const p21 = BOOST_LEAF_P("struct boost::leaf::n::r __fastcall boost::leaf::n::p<enum ");
0175
0176 int const p22 = BOOST_LEAF_P("struct boost::leaf::n::r __cdecl boost::leaf::n::p<");
0177 int const p23 = BOOST_LEAF_P("struct boost::leaf::n::r __stdcall boost::leaf::n::p<");
0178 int const p24 = BOOST_LEAF_P("struct boost::leaf::n::r __fastcall boost::leaf::n::p<");
0179 #undef BOOST_LEAF_P
0180
0181 #define BOOST_LEAF_S(S) (sizeof(char[1 + detail::check_suffix(BOOST_LEAF_PRETTY_FUNCTION, S)]) - 1)
0182
0183 int const s01 = BOOST_LEAF_S("]");
0184
0185 int const s02 = BOOST_LEAF_S(">(void)");
0186 #undef BOOST_LEAF_S
0187
0188 char static_assert_unrecognized_pretty_function_format_please_file_github_issue[sizeof(
0189 char[
0190 (s01 && (1 == (!!p01 + !!p02 + !!p03 + !!p04 + !!p05 + !!p06 + !!p07 + !!p08 + !!p09 + !!p10 + !!p11 + !!p12)))
0191 ||
0192 (s02 && (1 == (!!p13 + !!p14 + !!p15 + !!p16 + !!p17 + !!p18 + !!p19 + !!p20 + !!p21)))
0193 ||
0194 (s02 && (1 == (!!p22 + !!p23 + !!p24)))
0195 ]
0196 ) * 2 - 1];
0197 (void) static_assert_unrecognized_pretty_function_format_please_file_github_issue;
0198
0199 if( int const p = sizeof(char[1 + !!s01 * (p01 + p02 + p03 + p04 + p05 + p06 + p07 + p08 + p09 + p10 + p11 + p12)]) - 1 )
0200 return { BOOST_LEAF_PRETTY_FUNCTION + p, s01 - p };
0201
0202 if( int const p = sizeof(char[1 + !!s02 * (p13 + p14 + p15 + p16 + p17 + p18 + p19 + p20 + p21)]) - 1 )
0203 return { BOOST_LEAF_PRETTY_FUNCTION + p, s02 - p };
0204
0205 int const p = sizeof(char[1 + !!s02 * (p22 + p23 + p24)]) - 1;
0206 return { BOOST_LEAF_PRETTY_FUNCTION + p, s02 - p };
0207 }
0208 }
0209
0210 using parsed = n::r;
0211
0212 template <class T>
0213 parsed parse()
0214 {
0215 return n::p<T>();
0216 }
0217
0218 } }
0219
0220
0221
0222 namespace boost { namespace leaf {
0223
0224 namespace detail
0225 {
0226 template <class CharT, class Traits>
0227 std::ostream & demangle_and_print(std::basic_ostream<CharT, Traits> & os, char const * mangled_name)
0228 {
0229 BOOST_LEAF_ASSERT(mangled_name);
0230 #if defined(BOOST_LEAF_CFG_DIAGNOSTICS) && defined(BOOST_LEAF_HAS_CXXABI_H)
0231 struct raii
0232 {
0233 char * demangled_name;
0234 raii(char const * mangled_name) noexcept
0235 {
0236 int status = 0;
0237 demangled_name = abi::__cxa_demangle(mangled_name, nullptr, nullptr, &status);
0238 }
0239 ~raii() noexcept
0240 {
0241 std::free(demangled_name);
0242 }
0243 } d(mangled_name);
0244 if( d.demangled_name )
0245 return os << d.demangled_name;
0246 #endif
0247 return os << mangled_name;
0248 }
0249 }
0250
0251 } }
0252
0253 #endif