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