summaryrefslogtreecommitdiff
path: root/boost/type_index/detail/compile_time_type_info.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/type_index/detail/compile_time_type_info.hpp')
-rw-r--r--boost/type_index/detail/compile_time_type_info.hpp143
1 files changed, 143 insertions, 0 deletions
diff --git a/boost/type_index/detail/compile_time_type_info.hpp b/boost/type_index/detail/compile_time_type_info.hpp
new file mode 100644
index 0000000000..8ee4c66e39
--- /dev/null
+++ b/boost/type_index/detail/compile_time_type_info.hpp
@@ -0,0 +1,143 @@
+//
+// Copyright (c) Antony Polukhin, 2012-2014.
+//
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
+#define BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
+
+/// \file compile_time_type_info.hpp
+/// \brief Contains helper macros and implementation details of boost::typeindex::ctti_type_index.
+/// Not intended for inclusion from user's code.
+
+#include <boost/config.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/mpl/bool.hpp>
+#include <algorithm>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+# pragma once
+#endif
+
+/// @cond
+#define BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(begin_skip, end_skip, runtime_skip, runtime_skip_until) \
+ namespace boost { namespace typeindex { namespace detail { \
+ BOOST_STATIC_CONSTEXPR std::size_t ctti_skip_size_at_begin = begin_skip; \
+ BOOST_STATIC_CONSTEXPR std::size_t ctti_skip_size_at_end = end_skip; \
+ BOOST_STATIC_CONSTEXPR bool ctti_skip_more_at_runtime = runtime_skip; \
+ BOOST_STATIC_CONSTEXPR char ctti_skip_until_runtime[] = runtime_skip_until; \
+ }}} /* namespace boost::typeindex::detail */ \
+ /**/
+/// @endcond
+
+#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
+ /* Nothing to document. All the macro docs are moved to <boost/type_index.hpp> */
+#elif defined(BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING)
+
+# include <boost/preprocessor/facilities/expand.hpp>
+ BOOST_PP_EXPAND( BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING )
+
+#elif defined(_MSC_VER)
+ // sizeof("const char *__cdecl boost::detail::ctti<") - 1, sizeof(">::n(void)") - 1
+ BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 10, false, "");
+#elif defined(__clang__) && defined(__APPLE__)
+ // Someone made __clang_major__ equal to LLVM version rather than compiler version
+ // on APPLE platform.
+ //
+ // Using less efficient solution because there is no good way to detect real version of Clang.
+ // sizeof("static const char *boost::detail::ctti<") - 1, sizeof("]") - 1, true, "???????????>::n() [T = int"
+ BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ");
+#elif defined(__clang__) && (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ == 0))
+ // sizeof("static const char *boost::detail::ctti<") - 1, sizeof(">::n()") - 1
+ // note: checked on 3.0
+ BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 6, false, "");
+#elif defined(__clang__) && __clang_major__ == 3 && __clang_minor__ > 0
+ // sizeof("static const char *boost::detail::ctti<") - 1, sizeof("]") - 1, true, "int>::n() [T = int"
+ // note: checked on 3.1, 3.4
+ BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ");
+#elif defined(__GNUC__)
+ // sizeof("static const char* boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
+ BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "");
+#else
+ // Deafult code for other platforms... Just skip nothing!
+ BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(0, 0, false, "");
+#endif
+
+#undef BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS
+
+namespace boost { namespace typeindex { namespace detail {
+ template <bool Condition>
+ inline void assert_compile_time_legths() BOOST_NOEXCEPT {
+ BOOST_STATIC_ASSERT_MSG(
+ Condition,
+ "TypeIndex library is misconfigured for your compiler. "
+ "Please define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct values. See section "
+ "'RTTI emulation limitations' of the documentation for more information."
+ );
+ }
+
+ template <std::size_t ArrayLength>
+ inline const char* skip_begining_runtime(const char* begin, boost::mpl::false_) BOOST_NOEXCEPT {
+ return begin;
+ }
+
+ template <std::size_t ArrayLength>
+ inline const char* skip_begining_runtime(const char* begin, boost::mpl::true_) BOOST_NOEXCEPT {
+ const char* const it = std::search(
+ begin, begin + ArrayLength,
+ ctti_skip_until_runtime, ctti_skip_until_runtime + sizeof(ctti_skip_until_runtime) - 1
+ );
+ return (it == begin + ArrayLength ? begin : it + sizeof(ctti_skip_until_runtime) - 1);
+ }
+
+ template <std::size_t ArrayLength>
+ inline const char* skip_begining(const char* begin) BOOST_NOEXCEPT {
+ assert_compile_time_legths<(ArrayLength > ctti_skip_size_at_begin + ctti_skip_size_at_end)>();
+ return skip_begining_runtime<ArrayLength - ctti_skip_size_at_begin>(
+ begin + ctti_skip_size_at_begin,
+ boost::mpl::bool_<ctti_skip_more_at_runtime>()
+ );
+ }
+}}} // namespace boost::typeindex::detail
+
+namespace boost { namespace detail {
+
+/// Noncopyable type_info that does not require RTTI.
+/// CTTI == Compile Time Type Info.
+/// This name must be as short as possible, to avoid code bloat
+template <class T>
+struct ctti {
+
+ /// Returns raw name. Must be as short, as possible, to avoid code bloat
+ static const char* n() BOOST_NOEXCEPT {
+ #if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
+ return boost::typeindex::detail::skip_begining< sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE >(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE);
+ #elif defined(__FUNCSIG__)
+ return boost::typeindex::detail::skip_begining< sizeof(__FUNCSIG__) >(__FUNCSIG__);
+ #elif defined(__PRETTY_FUNCTION__) \
+ || defined(__GNUC__) \
+ || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
+ || (defined(__ICC) && (__ICC >= 600)) \
+ || defined(__ghs__) \
+ || defined(__DMC__)
+
+ return boost::typeindex::detail::skip_begining< sizeof(__PRETTY_FUNCTION__) >(__PRETTY_FUNCTION__);
+ #else
+ BOOST_STATIC_ASSERT_MSG(
+ sizeof(T) && false,
+ "TypeIndex library could not detect your compiler. "
+ "Please make the BOOST_TYPE_INDEX_FUNCTION_SIGNATURE macro use "
+ "correct compiler macro for getting the whole function name. "
+ "Define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct value after that."
+ );
+ #endif
+ }
+};
+
+}} // namespace boost::detail
+
+#endif // BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
+