]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/type_index/detail/compile_time_type_info.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / type_index / detail / compile_time_type_info.hpp
CommitLineData
7c673cae 1//
1e59de90 2// Copyright 2012-2022 Antony Polukhin.
7c673cae
FG
3//
4//
5// Distributed under the Boost Software License, Version 1.0. (See accompanying
6// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7//
8
9#ifndef BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
10#define BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
11
12/// \file compile_time_type_info.hpp
13/// \brief Contains helper macros and implementation details of boost::typeindex::ctti_type_index.
b32b8144 14/// Not intended for inclusion from user's code.
7c673cae 15
92f5a8d4 16#include <cstring>
7c673cae
FG
17#include <boost/config.hpp>
18#include <boost/static_assert.hpp>
92f5a8d4 19#include <boost/type_traits/integral_constant.hpp>
7c673cae
FG
20
21#ifdef BOOST_HAS_PRAGMA_ONCE
22# pragma once
23#endif
24
25/// @cond
92f5a8d4
TL
26#if defined(__has_builtin)
27#if __has_builtin(__builtin_constant_p)
28#define BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x)
29#endif
30#if __has_builtin(__builtin_strcmp)
31#define BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP(str1, str2) __builtin_strcmp(str1, str2)
32#endif
33#elif defined(__GNUC__)
34#define BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x)
35#define BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP(str1, str2) __builtin_strcmp(str1, str2)
36#endif
37
7c673cae
FG
38#define BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(begin_skip, end_skip, runtime_skip, runtime_skip_until) \
39 namespace boost { namespace typeindex { namespace detail { \
40 BOOST_STATIC_CONSTEXPR std::size_t ctti_skip_size_at_begin = begin_skip; \
41 BOOST_STATIC_CONSTEXPR std::size_t ctti_skip_size_at_end = end_skip; \
42 BOOST_STATIC_CONSTEXPR bool ctti_skip_more_at_runtime = runtime_skip; \
43 BOOST_STATIC_CONSTEXPR char ctti_skip_until_runtime[] = runtime_skip_until; \
44 }}} /* namespace boost::typeindex::detail */ \
45 /**/
46/// @endcond
47
48
49#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
50 /* Nothing to document. All the macro docs are moved to <boost/type_index.hpp> */
51#elif defined(BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING)
52# include <boost/preprocessor/facilities/expand.hpp>
53 BOOST_PP_EXPAND( BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING )
92f5a8d4 54#elif defined(_MSC_VER) && !defined(__clang__) && defined (BOOST_NO_CXX11_NOEXCEPT)
7c673cae
FG
55 // sizeof("const char *__cdecl boost::detail::ctti<") - 1, sizeof(">::n(void)") - 1
56 BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 10, false, "")
92f5a8d4 57#elif defined(_MSC_VER) && !defined(__clang__) && !defined (BOOST_NO_CXX11_NOEXCEPT)
7c673cae
FG
58 // sizeof("const char *__cdecl boost::detail::ctti<") - 1, sizeof(">::n(void) noexcept") - 1
59 BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 19, false, "")
60#elif defined(__clang__) && defined(__APPLE__)
61 // Someone made __clang_major__ equal to LLVM version rather than compiler version
62 // on APPLE platform.
63 //
64 // Using less efficient solution because there is no good way to detect real version of Clang.
65 // sizeof("static const char *boost::detail::ctti<") - 1, sizeof("]") - 1, true, "???????????>::n() [T = int"
66 BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ")
67#elif defined(__clang__) && (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ == 0))
68 // sizeof("static const char *boost::detail::ctti<") - 1, sizeof(">::n()") - 1
69 // note: checked on 3.0
70 BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 6, false, "")
71#elif defined(__clang__) && (__clang_major__ >= 4 || (__clang_major__ == 3 && __clang_minor__ > 0))
72 // sizeof("static const char *boost::detail::ctti<") - 1, sizeof("]") - 1, true, "int>::n() [T = int"
73 // note: checked on 3.1, 3.4
74 BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ")
92f5a8d4
TL
75#elif defined(__EDG__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
76 // sizeof("static cha boost::detail::ctti<T>::s() [with I = 40U, T = ") - 1, sizeof("]") - 1
77 // note: checked on 4.14
78 BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(58, 1, false, "")
79#elif defined(__EDG__) && defined(BOOST_NO_CXX14_CONSTEXPR)
80 // sizeof("static const char *boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
81 // note: checked on 4.14
82 BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "")
b32b8144
FG
83#elif defined(__GNUC__) && (__GNUC__ < 7) && !defined(BOOST_NO_CXX14_CONSTEXPR)
84 // sizeof("static constexpr char boost::detail::ctti<T>::s() [with unsigned int I = 0u; T = ") - 1, sizeof("]") - 1
7c673cae 85 BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(81, 1, false, "")
b32b8144
FG
86#elif defined(__GNUC__) && (__GNUC__ >= 7) && !defined(BOOST_NO_CXX14_CONSTEXPR)
87 // sizeof("static constexpr char boost::detail::ctti<T>::s() [with unsigned int I = 0; T = ") - 1, sizeof("]") - 1
88 BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(80, 1, false, "")
7c673cae
FG
89#elif defined(__GNUC__) && defined(BOOST_NO_CXX14_CONSTEXPR)
90 // sizeof("static const char* boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
91 BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "")
92f5a8d4
TL
92#elif defined(__ghs__)
93 // sizeof("static const char *boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
94 BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "")
7c673cae
FG
95#else
96 // Deafult code for other platforms... Just skip nothing!
97 BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(0, 0, false, "")
98#endif
99
100#undef BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS
101
b32b8144 102namespace boost { namespace typeindex { namespace detail {
7c673cae
FG
103 template <bool Condition>
104 BOOST_CXX14_CONSTEXPR inline void assert_compile_time_legths() BOOST_NOEXCEPT {
105 BOOST_STATIC_ASSERT_MSG(
106 Condition,
107 "TypeIndex library is misconfigured for your compiler. "
108 "Please define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct values. See section "
109 "'RTTI emulation limitations' of the documentation for more information."
110 );
111 }
112
113 template <class T>
114 BOOST_CXX14_CONSTEXPR inline void failed_to_get_function_name() BOOST_NOEXCEPT {
115 BOOST_STATIC_ASSERT_MSG(
116 sizeof(T) && false,
117 "TypeIndex library could not detect your compiler. "
118 "Please make the BOOST_TYPE_INDEX_FUNCTION_SIGNATURE macro use "
119 "correct compiler macro for getting the whole function name. "
120 "Define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct value after that."
121 );
122 }
123
92f5a8d4
TL
124#if defined(BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT)
125 BOOST_CXX14_CONSTEXPR BOOST_FORCEINLINE bool is_constant_string(const char* str) BOOST_NOEXCEPT {
126 while (BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT(*str)) {
127 if (*str == '\0')
128 return true;
129 ++str;
130 }
131 return false;
132 }
133#endif // defined(BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT)
134
7c673cae 135 template <unsigned int ArrayLength>
92f5a8d4 136 BOOST_CXX14_CONSTEXPR inline const char* skip_begining_runtime(const char* begin, boost::false_type) BOOST_NOEXCEPT {
7c673cae
FG
137 return begin;
138 }
139
140 template<class ForwardIterator1, class ForwardIterator2>
141 BOOST_CXX14_CONSTEXPR inline ForwardIterator1 constexpr_search(
142 ForwardIterator1 first1,
143 ForwardIterator1 last1,
144 ForwardIterator2 first2,
145 ForwardIterator2 last2) BOOST_NOEXCEPT
146 {
147 if (first2 == last2) {
148 return first1; // specified in C++11
149 }
150
151 while (first1 != last1) {
152 ForwardIterator1 it1 = first1;
153 ForwardIterator2 it2 = first2;
154
155 while (*it1 == *it2) {
156 ++it1;
157 ++it2;
158 if (it2 == last2) return first1;
159 if (it1 == last1) return last1;
160 }
161
162 ++first1;
163 }
164
165 return last1;
166 }
167
92f5a8d4 168 BOOST_CXX14_CONSTEXPR inline int constexpr_strcmp_loop(const char *v1, const char *v2) BOOST_NOEXCEPT {
7c673cae
FG
169 while (*v1 != '\0' && *v1 == *v2) {
170 ++v1;
171 ++v2;
92f5a8d4 172 }
7c673cae
FG
173
174 return static_cast<int>(*v1) - *v2;
175 }
176
92f5a8d4
TL
177 BOOST_CXX14_CONSTEXPR inline int constexpr_strcmp(const char *v1, const char *v2) BOOST_NOEXCEPT {
178#if !defined(BOOST_NO_CXX14_CONSTEXPR) && defined(BOOST_TYPE_INDEX_DETAIL_IS_CONSTANT) && defined(BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP)
179 if (boost::typeindex::detail::is_constant_string(v1) && boost::typeindex::detail::is_constant_string(v2))
180 return boost::typeindex::detail::constexpr_strcmp_loop(v1, v2);
181 return BOOST_TYPE_INDEX_DETAIL_BUILTIN_STRCMP(v1, v2);
182#elif !defined(BOOST_NO_CXX14_CONSTEXPR)
183 return boost::typeindex::detail::constexpr_strcmp_loop(v1, v2);
184#else
185 return std::strcmp(v1, v2);
186#endif
187 }
188
7c673cae 189 template <unsigned int ArrayLength>
92f5a8d4 190 BOOST_CXX14_CONSTEXPR inline const char* skip_begining_runtime(const char* begin, boost::true_type) BOOST_NOEXCEPT {
7c673cae
FG
191 const char* const it = constexpr_search(
192 begin, begin + ArrayLength,
193 ctti_skip_until_runtime, ctti_skip_until_runtime + sizeof(ctti_skip_until_runtime) - 1
194 );
195 return (it == begin + ArrayLength ? begin : it + sizeof(ctti_skip_until_runtime) - 1);
196 }
197
198 template <unsigned int ArrayLength>
199 BOOST_CXX14_CONSTEXPR inline const char* skip_begining(const char* begin) BOOST_NOEXCEPT {
200 assert_compile_time_legths<(ArrayLength > ctti_skip_size_at_begin + ctti_skip_size_at_end)>();
201 return skip_begining_runtime<ArrayLength - ctti_skip_size_at_begin>(
b32b8144 202 begin + ctti_skip_size_at_begin,
92f5a8d4 203 boost::integral_constant<bool, ctti_skip_more_at_runtime>()
7c673cae
FG
204 );
205 }
206
207#if !defined(__clang__) && defined(__GNUC__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
208 template <unsigned int... I>
209 struct index_seq {};
210
211 template <typename Left, typename Right>
212 struct make_index_sequence_join;
213
214 template <unsigned int... Left, unsigned int... Right>
215 struct make_index_sequence_join<index_seq<Left...>, index_seq<Right...> > {
216 typedef index_seq<Left..., Right...> type;
217 };
218
219 template <unsigned int C, unsigned int D>
220 struct make_index_seq_impl {
221 typedef typename make_index_sequence_join<
222 typename make_index_seq_impl<C, D / 2>::type,
223 typename make_index_seq_impl<C + D / 2, (D + 1) / 2>::type
224 >::type type;
225 };
226
227 template <unsigned int C>
228 struct make_index_seq_impl<C, 0> {
229 typedef index_seq<> type;
230 };
231
232 template <unsigned int C>
233 struct make_index_seq_impl<C, 1> {
234 typedef index_seq<C> type;
235 };
236
237 template <char... C>
238 struct cstring {
239 static constexpr unsigned int size_ = sizeof...(C);
240 static constexpr char data_[size_] = { C... };
241 };
242
243 template <char... C>
244 constexpr char cstring<C...>::data_[];
245#endif
246
247}}} // namespace boost::typeindex::detail
248
249namespace boost { namespace detail {
250
251/// Noncopyable type_info that does not require RTTI.
252/// CTTI == Compile Time Type Info.
253/// This name must be as short as possible, to avoid code bloat
254template <class T>
255struct ctti {
b32b8144 256
7c673cae
FG
257#if !defined(__clang__) && defined(__GNUC__) && !defined(BOOST_NO_CXX14_CONSTEXPR)
258 //helper functions
259 template <unsigned int I>
260 constexpr static char s() BOOST_NOEXCEPT { // step
261 constexpr unsigned int offset =
262 (I >= 10u ? 1u : 0u)
263 + (I >= 100u ? 1u : 0u)
264 + (I >= 1000u ? 1u : 0u)
265 + (I >= 10000u ? 1u : 0u)
266 + (I >= 100000u ? 1u : 0u)
267 + (I >= 1000000u ? 1u : 0u)
268 ;
269
270 #if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
271 return BOOST_TYPE_INDEX_FUNCTION_SIGNATURE[I + offset];
272 #elif defined(__FUNCSIG__)
273 return __FUNCSIG__[I + offset];
274 #else
275 return __PRETTY_FUNCTION__[I + offset];
276 #endif
277 }
278
279 template <unsigned int ...Indexes>
280 constexpr static const char* impl(::boost::typeindex::detail::index_seq<Indexes...> ) BOOST_NOEXCEPT {
281 return ::boost::typeindex::detail::cstring<s<Indexes>()...>::data_;
282 }
283
284 template <unsigned int D = 0> // `D` means `Dummy`
285 constexpr static const char* n() BOOST_NOEXCEPT {
286 #if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
287 constexpr unsigned int size = sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE);
288 #elif defined(__FUNCSIG__)
289 constexpr unsigned int size = sizeof(__FUNCSIG__);
290 #elif defined(__PRETTY_FUNCTION__) \
291 || defined(__GNUC__) \
292 || (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) \
293 || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
294 || (defined(__ICC) && (__ICC >= 600)) \
295 || defined(__ghs__) \
296 || defined(__DMC__)
297 constexpr unsigned int size = sizeof(__PRETTY_FUNCTION__);
298 #else
92f5a8d4 299 boost::typeindex::detail::failed_to_get_function_name<T>();
7c673cae
FG
300 #endif
301
302 boost::typeindex::detail::assert_compile_time_legths<
303 (size > boost::typeindex::detail::ctti_skip_size_at_begin + boost::typeindex::detail::ctti_skip_size_at_end + sizeof("const *") - 1)
304 >();
305 static_assert(!boost::typeindex::detail::ctti_skip_more_at_runtime, "Skipping for GCC in C++14 mode is unsupported");
306
307 typedef typename boost::typeindex::detail::make_index_seq_impl<
308 boost::typeindex::detail::ctti_skip_size_at_begin,
309 size - sizeof("const *") + 1 - boost::typeindex::detail::ctti_skip_size_at_begin
310 >::type idx_seq;
311 return impl(idx_seq());
312 }
313#else
314 /// Returns raw name. Must be as short, as possible, to avoid code bloat
315 BOOST_CXX14_CONSTEXPR static const char* n() BOOST_NOEXCEPT {
316 #if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
317 return boost::typeindex::detail::skip_begining< sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE) >(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE);
318 #elif defined(__FUNCSIG__)
319 return boost::typeindex::detail::skip_begining< sizeof(__FUNCSIG__) >(__FUNCSIG__);
320 #elif defined(__PRETTY_FUNCTION__) \
321 || defined(__GNUC__) \
322 || (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) \
323 || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
324 || (defined(__ICC) && (__ICC >= 600)) \
325 || defined(__ghs__) \
92f5a8d4
TL
326 || defined(__DMC__) \
327 || defined(__clang__)
7c673cae
FG
328 return boost::typeindex::detail::skip_begining< sizeof(__PRETTY_FUNCTION__) >(__PRETTY_FUNCTION__);
329 #else
92f5a8d4 330 boost::typeindex::detail::failed_to_get_function_name<T>();
7c673cae
FG
331 return "";
332 #endif
333 }
334#endif
335};
336
337}} // namespace boost::detail
338
339#endif // BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP