forked from boostorg/type_index
Add ability to do runtime searches in CTTI and fix pretty_name() on clang-3.4
This commit is contained in:
@ -301,6 +301,7 @@ i
|
||||
|
||||
TypeIndex has been tested and successfully work on many compilers.
|
||||
|
||||
[\ -DB_TYPE_INDEX_CTTI_USER_DEFINED_PARSING='BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(1, 1, false, "")' ]
|
||||
If `BOOST_TYPE_INDEX_FUNCTION_SIGNATURE` macro is not defined or
|
||||
`BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP`
|
||||
are defined to zero then you are using a compiler that was not tested with this library.
|
||||
|
@ -97,9 +97,7 @@ inline const detail::ctti_data& ctti_construct() BOOST_NOEXCEPT {
|
||||
class ctti_type_index: public type_index_facade<ctti_type_index, detail::ctti_data> {
|
||||
const detail::ctti_data* data_;
|
||||
|
||||
inline std::size_t get_raw_name_length() const BOOST_NOEXCEPT {
|
||||
return std::strlen(raw_name() + detail::ctti_skip_size_at_end);
|
||||
}
|
||||
inline std::size_t get_raw_name_length() const BOOST_NOEXCEPT;
|
||||
|
||||
public:
|
||||
typedef detail::ctti_data type_info_t;
|
||||
@ -158,6 +156,10 @@ inline const char* ctti_type_index::raw_name() const BOOST_NOEXCEPT {
|
||||
return reinterpret_cast<const char*>(data_);
|
||||
}
|
||||
|
||||
inline std::size_t ctti_type_index::get_raw_name_length() const BOOST_NOEXCEPT {
|
||||
return std::strlen(raw_name() + detail::ctti_skip_size_at_end);
|
||||
}
|
||||
|
||||
|
||||
inline std::string ctti_type_index::pretty_name() const {
|
||||
std::size_t len = get_raw_name_length();
|
||||
|
@ -17,12 +17,21 @@
|
||||
|
||||
/// \file compile_time_type_info.hpp
|
||||
/// \brief Contains implementation of boost::ctti class.
|
||||
///
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
#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 */ \
|
||||
/**/
|
||||
|
||||
namespace boost { namespace typeindex { namespace detail {
|
||||
|
||||
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
|
||||
|
||||
@ -36,59 +45,73 @@ namespace boost { namespace typeindex { namespace detail {
|
||||
/// that outputs the WHOLE function signature, including template parameters.
|
||||
///
|
||||
/// If your compiler is not recognised and BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is not defined,
|
||||
/// then a compile-time error will arise at any attempt to use boost::template_info or
|
||||
/// boost::template_index classes.
|
||||
/// then a compile-time error will arise at any attempt to use boost::typeindex::ctti_type_index classes.
|
||||
#define BOOST_TYPE_INDEX_FUNCTION_SIGNATURE BOOST_CURRENT_FUNCTION
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP
|
||||
/// \def BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING
|
||||
///
|
||||
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE, BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP
|
||||
/// and BOOST_TYPE_INDEX_CTTI_END_SKIP macroses are used for adding a
|
||||
/// support for compilers, that by default are not recognized by TypeIndex library.
|
||||
///
|
||||
/// See Compiler support for more info
|
||||
#define BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP 0
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_CTTI_END_SKIP
|
||||
///
|
||||
/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE, BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP
|
||||
/// and BOOST_TYPE_INDEX_CTTI_END_SKIP macroses are used for adding a
|
||||
/// support for compilers, that by default are not recognized by TypeIndex library.
|
||||
///
|
||||
/// See Compiler support for more info
|
||||
#define BOOST_TYPE_INDEX_CTTI_END_SKIP 0
|
||||
|
||||
#elif defined(BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP) && defined(BOOST_TYPE_INDEX_CTTI_END_SKIP)
|
||||
// skip user specified bytes count
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP);
|
||||
// skip user specified bytes count
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = BOOST_TYPE_INDEX_CTTI_END_SKIP);
|
||||
#elif defined _MSC_VER
|
||||
// sizeof("const char *__cdecl boost::detail::ctti<") - 1
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 40);
|
||||
|
||||
// sizeof(">::n(void)") - 1
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 10);
|
||||
|
||||
#elif defined __clang__
|
||||
// sizeof("static const char *boost::detail::ctti<") - 1
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 39);
|
||||
|
||||
// == sizeof(">::n()") - 1
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 6);
|
||||
#elif defined __GNUC__
|
||||
// sizeof("static const char* boost::detail::ctti<T>::n() [with T = ") - 1
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 57);
|
||||
|
||||
// == sizeof("]") - 1
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 1);
|
||||
#define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(0, 0, false, "");
|
||||
|
||||
#elif defined(BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING)
|
||||
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__) && (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 4))
|
||||
// sizeof("static const char *boost::detail::ctti<") - 1, sizeof(">::n()") - 1
|
||||
BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 6, false, "");
|
||||
#elif defined(__clang__) && __clang_major__ == 3 && __clang_minor__ >= 4
|
||||
// sizeof("static const char *boost::detail::ctti<") - 1, sizeof("]") - 1, true, "int>::n() [T = int"
|
||||
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
|
||||
// TODO: Code for other platforms
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 0); // skip nothing
|
||||
BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 0); // skip nothing
|
||||
// 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_BEGIN_SKIP and "
|
||||
"BOOST_TYPE_INDEX_CTTI_END_SKIP to correct values. See section "
|
||||
"'RTTI emulation limitations' of the documentation."
|
||||
);
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -98,38 +121,31 @@ namespace boost { namespace detail {
|
||||
/// This name must be as short as posible, to avoid code bloat
|
||||
template <class T>
|
||||
struct ctti {
|
||||
typedef T template_type;
|
||||
typedef ctti this_type;
|
||||
|
||||
/// 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_TYPE_INDEX_FUNCTION_SIGNATURE + boost::typeindex::detail::ctti_skip_size_at_begin;
|
||||
#elif defined(__FUNCSIG__)
|
||||
return __FUNCSIG__ + boost::typeindex::detail::ctti_skip_size_at_begin;
|
||||
#elif defined(__PRETTY_FUNCTION__) \
|
||||
|| defined(__GNUC__) \
|
||||
|| (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
|
||||
|| (defined(__ICC) && (__ICC >= 600)) \
|
||||
|| defined(__ghs__) \
|
||||
|| defined(__DMC__)
|
||||
#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 __PRETTY_FUNCTION__ + boost::typeindex::detail::ctti_skip_size_at_begin;
|
||||
#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. "
|
||||
"Do not forget to also define BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP and "
|
||||
"BOOST_TYPE_INDEX_CTTI_END_SKIP."
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Returns raw name
|
||||
static const char* name() BOOST_NOEXCEPT {
|
||||
return this_type::n();
|
||||
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. "
|
||||
"Do not forget to also define BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP and "
|
||||
"BOOST_TYPE_INDEX_CTTI_END_SKIP."
|
||||
);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user