Fixed almost all the notes by Andrey Semashev except link-time assertions and ctti type name assertions

This commit is contained in:
Antony Polukhin
2014-05-06 18:23:26 +04:00
parent f7388d59b5
commit a184f3969f
4 changed files with 85 additions and 44 deletions

View File

@ -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]

View File

@ -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);

View File

@ -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.
///

View File

@ -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