mirror of
https://github.com/boostorg/type_index.git
synced 2025-07-29 20:07:18 +02:00
Fixed almost all the notes by Andrey Semashev except link-time assertions and ctti type name assertions
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
[library Boost.TypeIndex
|
||||
[quickbook 1.6]
|
||||
[version 3.0]
|
||||
[version 4.0]
|
||||
[copyright 2012-2014 Antony Polukhin]
|
||||
[category Language Features Emulation]
|
||||
[license
|
||||
@ -25,8 +25,6 @@ Boost.TypeIndex library was designed to work around all those issues.
|
||||
|
||||
[note `T` means type here. Think of it as of `T` in `template <class T>` ]
|
||||
|
||||
[warning Version 3.0 of this library is waitning for Boost mini-review. ]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Getting started]
|
||||
|
@ -45,13 +45,15 @@
|
||||
|
||||
#if !defined(BOOST_MSVC)
|
||||
# include <boost/assert.hpp>
|
||||
# include <boost/detail/no_exceptions_support.hpp>
|
||||
# include <cstdlib> // std::free
|
||||
# include <cstdlib> // std::free
|
||||
# include <algorithm> // std::find, std::search
|
||||
#endif
|
||||
|
||||
#if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
|
||||
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
|
||||
# include <boost/type_traits/is_arithmetic.hpp>
|
||||
# include <boost/type_traits/is_signed.hpp>
|
||||
# include <boost/type_traits/make_signed.hpp>
|
||||
# include <boost/mpl/identity.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
@ -131,41 +133,69 @@ inline const char* stl_type_index::name() const BOOST_NOEXCEPT {
|
||||
return data_->name();
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
class free_at_scope_exit {
|
||||
char* to_free_;
|
||||
|
||||
public:
|
||||
explicit free_at_scope_exit(char* to_free) BOOST_NOEXCEPT
|
||||
: to_free_(to_free)
|
||||
{}
|
||||
|
||||
~free_at_scope_exit() BOOST_NOEXCEPT {
|
||||
std::free(to_free_);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
inline std::string stl_type_index::pretty_name() const {
|
||||
static const char cvr_saver_name[] = "boost::typeindex::detail::cvr_saver<";
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
std::string ret = data_->name();
|
||||
#else
|
||||
std::string ret;
|
||||
int status = 0;
|
||||
char* demang = abi::__cxa_demangle(raw_name(), NULL, 0, &status);
|
||||
BOOST_ASSERT(!status);
|
||||
|
||||
BOOST_TRY {
|
||||
ret = demang; // may throw out of memory exception
|
||||
} BOOST_CATCH (...) {
|
||||
std::free(demang);
|
||||
BOOST_RETHROW;
|
||||
} BOOST_CATCH_END
|
||||
|
||||
std::free(demang);
|
||||
#endif
|
||||
|
||||
std::string::size_type pos = ret.find("boost::typeindex::detail::cvr_saver<");
|
||||
if (pos == std::string::npos) {
|
||||
std::string::size_type pos_beg = ret.find(cvr_saver_name);
|
||||
if (pos_beg == std::string::npos) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
pos += sizeof("boost::typeindex::detail::cvr_saver<") - 1;
|
||||
while (ret[pos] == ' ') {
|
||||
++ pos;
|
||||
const char* begin = ret.c_str() + pos_beg + sizeof(cvr_saver_name) - 1;
|
||||
const char* end = ret.c_str() + ret.size() - 1;
|
||||
#else
|
||||
int status = 0;
|
||||
char* demang = abi::__cxa_demangle(raw_name(), NULL, 0, &status);
|
||||
detail::free_at_scope_exit scope(demang);
|
||||
BOOST_ASSERT(!status);
|
||||
const std::size_t length = std::strlen(demang);
|
||||
const char* begin = std::search(
|
||||
demang, demang + length,
|
||||
cvr_saver_name, cvr_saver_name + sizeof(cvr_saver_name) - 1
|
||||
);
|
||||
|
||||
if (begin == demang + length) {
|
||||
return std::string(demang, demang + length);
|
||||
}
|
||||
begin += sizeof(cvr_saver_name) - 1;
|
||||
const char* end = demang + length - 1;
|
||||
#endif
|
||||
while (*begin == ' ') { // begin is zero terminated
|
||||
++ begin;
|
||||
}
|
||||
|
||||
std::string::size_type end = ret.rfind(">");
|
||||
while (ret[end - 1] == ' ') {
|
||||
while (end != begin && *end != '>') {
|
||||
-- end;
|
||||
}
|
||||
|
||||
return ret.substr(pos, end - pos);
|
||||
// we have cvr_saver_name somewhere at the start of the end
|
||||
while (end != begin && *(end - 1) == ' ') {
|
||||
-- end;
|
||||
}
|
||||
|
||||
if (begin >= end) {
|
||||
// Some strange error in demangled name parsing
|
||||
return begin;
|
||||
}
|
||||
|
||||
return std::string(begin, end);
|
||||
}
|
||||
|
||||
|
||||
@ -217,12 +247,22 @@ inline bool stl_type_index::before(const stl_type_index& rhs) const BOOST_NOEXCE
|
||||
template <class T>
|
||||
inline stl_type_index stl_type_index::type_id() BOOST_NOEXCEPT {
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type no_ref_t;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<no_ref_t>::type no_cvr_t;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<no_ref_t>::type no_cvr_prefinal_t;
|
||||
|
||||
# if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
|
||||
|| (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
|
||||
BOOST_STATIC_ASSERT_MSG( !boost::is_arithmetic<no_cvr_t>::type::value
|
||||
, "Your EDG-based compiler seems to mistakenly distinguish 'int' from 'signed int', in typeid() expressions.");
|
||||
|
||||
// Old EDG-based compilers seem to mistakenly distinguish 'integral' from 'signed integral'
|
||||
// in typeid() expressions. Full temaplte specialization for 'integral' fixes that issue:
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
|
||||
boost::is_signed<no_cvr_prefinal_t>,
|
||||
boost::make_signed<no_cvr_prefinal_t>,
|
||||
boost::mpl::identity<no_cvr_prefinal_t>
|
||||
>::type no_cvr_prefinal_lazy_t;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME no_cvr_prefinal_t::type no_cvr_t;
|
||||
#else
|
||||
typedef no_cvr_prefinal_t no_cvr_t;
|
||||
#endif
|
||||
|
||||
return typeid(no_cvr_t);
|
||||
|
@ -53,6 +53,11 @@ namespace boost { namespace typeindex {
|
||||
///
|
||||
/// \tparam Derived Class derived from type_index_facade.
|
||||
/// \tparam TypeInfo Class that will be used as a base type_info class.
|
||||
/// \note Take a look at the protected methods. They are \b not \b defined in type_index_facade.
|
||||
/// Protected member functions raw_name() \b must be defined in Derived class. All the other
|
||||
/// methods are mandatory.
|
||||
/// \see 'Making a custom type_index' section for more information about
|
||||
/// creating your own type_index using type_index_facade.
|
||||
template <class Derived, class TypeInfo>
|
||||
class type_index_facade {
|
||||
private:
|
||||
@ -64,16 +69,6 @@ private:
|
||||
public:
|
||||
typedef TypeInfo type_info_t;
|
||||
|
||||
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
|
||||
/// \b Override: This function \b must be redefined in Derived class. Overrides \b must not throw.
|
||||
/// \return Const reference to underlying low level type_info_t.
|
||||
inline const type_info_t& type_info() const BOOST_NOEXCEPT;
|
||||
|
||||
/// \b Override: This function \b must be redefined in Derived class. Overrides \b must not throw.
|
||||
/// \return Pointer to unredable/raw type name.
|
||||
inline const char* raw_name() const BOOST_NOEXCEPT;
|
||||
#endif
|
||||
|
||||
/// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
|
||||
/// \return Name of a type. By default retuns Derived::raw_name().
|
||||
inline const char* name() const BOOST_NOEXCEPT {
|
||||
@ -112,6 +107,14 @@ public:
|
||||
|
||||
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
|
||||
protected:
|
||||
/// \b Override: This function \b must be redefined in Derived class. Overrides \b must not throw.
|
||||
/// \return Pointer to unredable/raw type name.
|
||||
inline const char* raw_name() const BOOST_NOEXCEPT;
|
||||
|
||||
/// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
|
||||
/// \return Const reference to underlying low level type_info_t.
|
||||
inline const type_info_t& type_info() const BOOST_NOEXCEPT;
|
||||
|
||||
/// This is a factory method that is used to create instances of Derived classes.
|
||||
/// boost::typeindex::type_id() will call this method, if Derived has same type as boost::typeindex::type_index.
|
||||
///
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright Antony Polukhin, 2012-2013.
|
||||
// Copyright Antony Polukhin, 2012-2014.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
|
Reference in New Issue
Block a user