Reimplement and simplify design using type_index_facade class

This commit is contained in:
Antony Polukhin
2014-02-07 13:32:24 +04:00
parent 496ab93589
commit 683dab93a2
5 changed files with 382 additions and 305 deletions

View File

@ -27,18 +27,22 @@
#include <boost/config.hpp>
#if (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
# include <boost/type_index/stl_type_index.ipp>
#if defined(BOOST_TYPE_INDEX_USER_TYPEINFO) && defined(BOOST_TYPE_INDEX_USER_TYPEINFO_NAME)
# include BOOST_TYPE_INDEX_USER_TYPEINFO
#elif (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
# include <boost/type_index/stl_type_index.hpp>
#else
# include <boost/type_index/ctti_type_index.ipp>
# include <boost/type_index/ctti_type_index.hpp>
#endif
namespace boost { namespace typeind {
#if (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
typedef boost::typeind::detail::type_index_base<std::type_info> type_index;
#if defined(BOOST_TYPE_INDEX_USER_TYPEINFO) && defined(BOOST_TYPE_INDEX_USER_TYPEINFO_NAME)
typedef boost::typeind::detail::type_index_base<BOOST_TYPE_INDEX_USER_TYPEINFO_NAME> type_index;
#elif (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
typedef boost::typeind::detail::stl_type_index type_index;
#else
typedef boost::typeind::detail::type_index_base<boost::typeind::detail::ctti_data> type_index;
typedef boost::typeind::detail::ctti_type_index type_index;
#endif
typedef type_index::type_info_t type_info;
@ -66,13 +70,13 @@ inline type_index type_id_with_cvr() BOOST_NOEXCEPT {
/// Function that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index.
template <class T>
inline type_index type_id_runtime(T& runtime_val) BOOST_NOEXCEPT {
inline type_index type_id_runtime(const T& runtime_val) BOOST_NOEXCEPT {
return type_index::construct_runtime(runtime_val);
}
/// Function that works exactly like C++ typeid(rtti_val) call, but returns boost::type_info.
template <class T>
inline type_index type_id_runtime(T* runtime_val) {
inline type_index type_id_runtime(const T* runtime_val) {
return type_index::construct_runtime(runtime_val);
}

View File

@ -6,8 +6,8 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_IPP
#define BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_IPP
#ifndef BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
#define BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
@ -25,7 +25,7 @@
/// is usually used instead of it (some compilers allow calling typeid(T)
/// even if RTTI is disabled, those copilers will continue to use boost::type_info class).
#include <boost/type_index/type_index_base.hpp>
#include <boost/type_index/type_index_facade.hpp>
#include <boost/type_index/detail/compile_time_type_info.hpp>
#include <cstring>
@ -37,7 +37,7 @@
namespace boost { namespace typeind { namespace detail {
struct ctti_data {
const char* const typename_;
const char* typename_;
};
template <class T>
@ -47,75 +47,99 @@ inline const ctti_data& ctti_construct() BOOST_NOEXCEPT {
}
template <>
class ctti_type_index: public type_index_facade<ctti_type_index, ctti_data> {
const ctti_data* data_;
public:
typedef ctti_data type_info_t;
inline ctti_type_index(const type_info_t& data) BOOST_NOEXCEPT
: data_(&data)
{}
inline const type_info_t& type_info() const BOOST_NOEXCEPT;
inline const char* raw_name() const BOOST_NOEXCEPT;
inline const char* name() const BOOST_NOEXCEPT;
inline std::string pretty_name() const;
inline std::size_t hash_code() const BOOST_NOEXCEPT;
inline bool equal(const ctti_type_index& rhs) const BOOST_NOEXCEPT;
inline bool before(const ctti_type_index& rhs) const BOOST_NOEXCEPT;
template <class T>
inline static ctti_type_index construct() BOOST_NOEXCEPT;
template <class T>
inline static ctti_type_index construct_with_cvr() BOOST_NOEXCEPT;
template <class T>
inline static ctti_type_index construct_runtime(const T* variable) BOOST_NOEXCEPT;
template <class T>
inline static ctti_type_index construct_runtime(const T& variable) BOOST_NOEXCEPT;
};
template <class T>
inline type_index_base<ctti_data> type_index_base<ctti_data>::construct() BOOST_NOEXCEPT {
inline ctti_type_index ctti_type_index::construct() 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;
return ctti_construct<no_cvr_t>();
}
template <>
template <class T>
inline type_index_base<ctti_data> type_index_base<ctti_data>::construct_with_cvr() BOOST_NOEXCEPT {
inline ctti_type_index ctti_type_index::construct_with_cvr() BOOST_NOEXCEPT {
return ctti_construct<T>();
}
template <>
template <class T>
inline type_index_base<ctti_data> type_index_base<ctti_data>::construct_runtime(T& rtti_val) BOOST_NOEXCEPT {
inline ctti_type_index ctti_type_index::construct_runtime(const T* rtti_val) BOOST_NOEXCEPT {
BOOST_STATIC_ASSERT_MSG(sizeof(T) && false,
"type_id_runtime(T&) and type_index::construct_runtime(T&) require RTTI");
"type_id_runtime(const T*) and type_index::construct_runtime(const T*) require RTTI");
return ctti_construct<T>();
}
template <>
template <class T>
inline type_index_base<ctti_data> type_index_base<ctti_data>::construct_runtime(T* rtti_val) {
inline ctti_type_index ctti_type_index::construct_runtime(const T& rtti_val) BOOST_NOEXCEPT {
BOOST_STATIC_ASSERT_MSG(sizeof(T) && false,
"type_id_runtime(T*) and type_index::construct_runtime(T*) require RTTI");
"type_id_runtime(const T&) and type_index::construct_runtime(const T&) require RTTI");
return ctti_construct<T>();
}
template <>
inline const char* type_index_base<ctti_data>::raw_name() const BOOST_NOEXCEPT {
inline const char* ctti_type_index::raw_name() const BOOST_NOEXCEPT {
return data_->typename_;
}
template <>
inline const char* type_index_base<ctti_data>::name() const BOOST_NOEXCEPT {
inline const char* ctti_type_index::name() const BOOST_NOEXCEPT {
return data_->typename_;
}
template <>
inline std::string type_index_base<ctti_data>::pretty_name() const {
inline std::string ctti_type_index::pretty_name() const {
std::size_t len = std::strlen(raw_name() + ctti_skip_size_at_end);
while (raw_name()[len - 1] == ' ') --len; // MSVC sometimes adds whitespaces
return std::string(raw_name(), len);
}
template <>
inline bool type_index_base<ctti_data>::equal(const type_index_base<ctti_data>& rhs) const BOOST_NOEXCEPT {
inline bool ctti_type_index::equal(const ctti_type_index& rhs) const BOOST_NOEXCEPT {
return raw_name() == rhs.raw_name() || !std::strcmp(raw_name(), rhs.raw_name());
}
template <>
inline bool type_index_base<ctti_data>::before(const type_index_base<ctti_data>& rhs) const BOOST_NOEXCEPT {
inline bool ctti_type_index::before(const ctti_type_index& rhs) const BOOST_NOEXCEPT {
return raw_name() != rhs.raw_name() && std::strcmp(raw_name(), rhs.raw_name()) < 0;
}
template <>
inline std::size_t type_index_base<ctti_data>::hash_code() const BOOST_NOEXCEPT {
inline std::size_t ctti_type_index::hash_code() const BOOST_NOEXCEPT {
return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name() + detail::ctti_skip_size_at_end));
}

View File

@ -6,8 +6,8 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BOOST_TYPE_INDEX_STL_TYPE_INDEX_IPP
#define BOOST_TYPE_INDEX_STL_TYPE_INDEX_IPP
#ifndef BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
#define BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
@ -25,7 +25,7 @@
/// is usually used instead of it (some compilers allow calling typeid(T)
/// even if RTTI is disabled, those copilers will continue to use boost::type_info class).
#include <boost/type_index/type_index_base.hpp>
#include <boost/type_index/type_index_facade.hpp>
// MSVC is capable of calling typeid(T) even when RTTI is off
@ -46,7 +46,7 @@
#ifdef __GNUC__
#include <cxxabi.h>
# include <cxxabi.h> // abi::__cxa_demangle
#endif
#if !defined(BOOST_MSVC)
@ -61,62 +61,60 @@
namespace boost { namespace typeind { namespace detail {
template <>
template <class T>
inline type_index_base<std::type_info> type_index_base<std::type_info>::construct() 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;
# 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.");
#endif
return typeid(no_cvr_t);
}
template <>
template <class T>
inline type_index_base<std::type_info> type_index_base<std::type_info>::construct_with_cvr() BOOST_NOEXCEPT {
typedef typename boost::mpl::if_c<
boost::is_reference<T>::value
|| boost::is_const<T>::value
|| boost::is_volatile<T>::value,
detail::cvr_saver<T>,
T
>::type type;
return typeid(type);
}
template <>
template <class T>
inline type_index_base<std::type_info> type_index_base<std::type_info>::construct_runtime(T& rtti_val) BOOST_NOEXCEPT {
#ifdef BOOST_NO_RTTI
BOOST_STATIC_ASSERT_MSG(sizeof(T) && false,
"type_id_runtime(T&) and type_index::construct_runtime(T&) require RTTI");
class stl_type_index
: public type_index_facade<
stl_type_index,
#ifdef BOOST_NO_STD_TYPEINFO
type_info
#else
std::type_info
#endif
>
{
public:
#ifdef BOOST_NO_STD_TYPEINFO
typedef type_info type_info_t;
#else
typedef std::type_info type_info_t;
#endif
return typeid(rtti_val);
private:
const type_info_t* data_;
public:
inline stl_type_index(const type_info_t& data) BOOST_NOEXCEPT
: data_(&data)
{}
inline const type_info_t& type_info() const BOOST_NOEXCEPT;
inline const char* raw_name() const BOOST_NOEXCEPT;
inline const char* name() const BOOST_NOEXCEPT;
inline std::string pretty_name() const;
inline std::size_t hash_code() const BOOST_NOEXCEPT;
inline bool equal(const stl_type_index& rhs) const BOOST_NOEXCEPT;
inline bool before(const stl_type_index& rhs) const BOOST_NOEXCEPT;
template <class T>
inline static stl_type_index construct() BOOST_NOEXCEPT;
template <class T>
inline static stl_type_index construct_with_cvr() BOOST_NOEXCEPT;
template <class T>
inline static stl_type_index construct_runtime(const T* variable);
template <class T>
inline static stl_type_index construct_runtime(const T& value) BOOST_NOEXCEPT;
};
inline const stl_type_index::type_info_t& stl_type_index::type_info() const BOOST_NOEXCEPT {
return *data_;
}
template <>
template <class T>
inline type_index_base<std::type_info> type_index_base<std::type_info>::construct_runtime(T* rtti_val) {
#ifdef BOOST_NO_RTTI
BOOST_STATIC_ASSERT_MSG(sizeof(T) && false,
"type_id_runtime(T*) and type_index::construct_runtime(T*) require RTTI");
#endif
return typeid(rtti_val);
}
template <>
inline const char* type_index_base<std::type_info>::raw_name() const BOOST_NOEXCEPT {
inline const char* stl_type_index::raw_name() const BOOST_NOEXCEPT {
#ifdef _MSC_VER
return data_->raw_name();
#else
@ -124,14 +122,11 @@ inline const char* type_index_base<std::type_info>::raw_name() const BOOST_NOEXC
#endif
}
template <>
inline const char* type_index_base<std::type_info>::name() const BOOST_NOEXCEPT {
inline const char* stl_type_index::name() const BOOST_NOEXCEPT {
return data_->name();
}
template <>
inline std::string type_index_base<std::type_info>::pretty_name() const {
inline std::string stl_type_index::pretty_name() const {
#if defined(_MSC_VER)
std::string ret = data_->name();
#else
@ -169,6 +164,15 @@ inline std::string type_index_base<std::type_info>::pretty_name() const {
}
inline std::size_t stl_type_index::hash_code() const BOOST_NOEXCEPT {
#if _MSC_VER > 1600 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__))
return data_->hash_code();
#else
return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name()));
#endif
}
/// @cond
// for this compiler at least, cross-shared-library type_info
@ -183,9 +187,7 @@ inline std::string type_index_base<std::type_info>::pretty_name() const {
/// @endcond
template <>
inline bool type_index_base<std::type_info>::equal(const type_index_base<std::type_info>& rhs) const BOOST_NOEXCEPT {
inline bool stl_type_index::equal(const stl_type_index& rhs) const BOOST_NOEXCEPT {
#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
return raw_name() == rhs.raw_name() || !std::strcmp(raw_name(), rhs.raw_name());
#else
@ -193,9 +195,7 @@ inline bool type_index_base<std::type_info>::equal(const type_index_base<std::ty
#endif
}
template <>
inline bool type_index_base<std::type_info>::before(const type_index_base<std::type_info>& rhs) const BOOST_NOEXCEPT {
inline bool stl_type_index::before(const stl_type_index& rhs) const BOOST_NOEXCEPT {
#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
return raw_name() != rhs.raw_name() && std::strcmp(raw_name(), rhs.raw_name()) < 0;
#else
@ -203,24 +203,62 @@ inline bool type_index_base<std::type_info>::before(const type_index_base<std::t
#endif
}
#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
#undef BOOST_CLASSINFO_COMPARE_BY_NAMES
#endif
template <>
inline std::size_t type_index_base<std::type_info>::hash_code() const BOOST_NOEXCEPT {
#if _MSC_VER > 1600 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__))
return data_->hash_code();
#else
return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name()));
#endif
template <class T>
inline stl_type_index stl_type_index::construct() 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;
# 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.");
#endif
return typeid(no_cvr_t);
}
template <class T> class cvr_saver{};
template <class T>
inline stl_type_index stl_type_index::construct_with_cvr() BOOST_NOEXCEPT {
typedef typename boost::mpl::if_c<
boost::is_reference<T>::value
|| boost::is_const<T>::value
|| boost::is_volatile<T>::value,
cvr_saver<T>,
T
>::type type;
return typeid(type);
}
template <class T>
inline stl_type_index stl_type_index::construct_runtime(const T* rtti_val) {
#ifdef BOOST_NO_RTTI
BOOST_STATIC_ASSERT_MSG(sizeof(T) && false,
"type_id_runtime(const T*) and type_index::construct_runtime(const T*) require RTTI");
#endif
return typeid(rtti_val);
}
template <class T>
inline stl_type_index stl_type_index::construct_runtime(const T& value) BOOST_NOEXCEPT {
#ifdef BOOST_NO_RTTI
BOOST_STATIC_ASSERT_MSG(sizeof(T) && false,
"type_id_runtime(const T&) and type_index::construct_runtime(const T&) require RTTI");
#endif
return typeid(value);
}
}}} // namespace boost::typeind::detail
#endif // BOOST_TYPE_INDEX_STL_TYPE_INDEX_IPP
#endif // BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP

View File

@ -1,193 +0,0 @@
//
// Copyright (c) Antony Polukhin, 2013-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_TYPE_INDEX_BASE_HPP
#define BOOST_TYPE_INDEX_TYPE_INDEX_BASE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/config.hpp>
#include <string>
#if !defined(BOOST_NO_IOSTREAM)
#if !defined(BOOST_NO_IOSFWD)
#include <iosfwd> // for std::basic_ostream
#else
#include <ostream>
#endif
#endif
namespace boost { namespace typeind { namespace detail {
template <class T> class cvr_saver{};
template <class TypeInfo>
class type_index_base {
const TypeInfo* data_;
public:
typedef TypeInfo type_info_t;
typedef type_index_base<TypeInfo> this_type;
type_index_base(const TypeInfo& info) BOOST_NOEXCEPT
: data_(&info)
{}
const type_info_t& type_info() const BOOST_NOEXCEPT {
return *data_;
}
// All of the following methods must be explicitly specialized for each type_index_base.
const char* raw_name() const BOOST_NOEXCEPT;
const char* name() const BOOST_NOEXCEPT;
std::string pretty_name() const;
std::size_t hash_code() const BOOST_NOEXCEPT;
bool equal(const this_type& rhs) const BOOST_NOEXCEPT;
bool before(const this_type& rhs) const BOOST_NOEXCEPT;
template <class T>
static this_type construct() BOOST_NOEXCEPT;
template <class T>
static this_type construct_with_cvr() BOOST_NOEXCEPT;
template <class T>
static this_type construct_runtime(T&) BOOST_NOEXCEPT;
template <class T>
static this_type construct_runtime(T* rtti_val);
};
template <class TypeInfo>
inline bool operator == (const type_index_base<TypeInfo>& lhs, const type_index_base<TypeInfo>& rhs) BOOST_NOEXCEPT {
return lhs.equal(rhs);
}
template <class TypeInfo>
inline bool operator < (const type_index_base<TypeInfo>& lhs, const type_index_base<TypeInfo>& rhs) BOOST_NOEXCEPT {
return lhs.before(rhs);
}
template <class TypeInfo>
inline bool operator > (const type_index_base<TypeInfo>& lhs, const type_index_base<TypeInfo>& rhs) BOOST_NOEXCEPT {
return rhs < lhs;
}
template <class TypeInfo>
inline bool operator <= (const type_index_base<TypeInfo>& lhs, const type_index_base<TypeInfo>& rhs) BOOST_NOEXCEPT {
return !(lhs > rhs);
}
template <class TypeInfo>
inline bool operator >= (const type_index_base<TypeInfo>& lhs, const type_index_base<TypeInfo>& rhs) BOOST_NOEXCEPT {
return !(lhs < rhs);
}
template <class TypeInfo>
inline bool operator != (const type_index_base<TypeInfo>& lhs, const type_index_base<TypeInfo>& rhs) BOOST_NOEXCEPT {
return !(lhs == rhs);
}
// ######################### COMPARISONS with TypeInfo ############################ //
template <class TypeInfo>
inline bool operator == (const TypeInfo& lhs, const type_index_base<TypeInfo>& rhs) BOOST_NOEXCEPT {
return type_index_base<TypeInfo>(lhs) == rhs;
}
template <class TypeInfo>
inline bool operator < (const TypeInfo& lhs, const type_index_base<TypeInfo>& rhs) BOOST_NOEXCEPT {
return type_index_base<TypeInfo>(lhs) < rhs;
}
template <class TypeInfo>
inline bool operator > (const TypeInfo& lhs, const type_index_base<TypeInfo>& rhs) BOOST_NOEXCEPT {
return rhs < type_index_base<TypeInfo>(lhs);
}
template <class TypeInfo>
inline bool operator <= (const TypeInfo& lhs, const type_index_base<TypeInfo>& rhs) BOOST_NOEXCEPT {
return !(type_index_base<TypeInfo>(lhs) > rhs);
}
template <class TypeInfo>
inline bool operator >= (const TypeInfo& lhs, const type_index_base<TypeInfo>& rhs) BOOST_NOEXCEPT {
return !(type_index_base<TypeInfo>(lhs) < rhs);
}
template <class TypeInfo>
inline bool operator != (const TypeInfo& lhs, const type_index_base<TypeInfo>& rhs) BOOST_NOEXCEPT {
return !(type_index_base<TypeInfo>(lhs) == rhs);
}
template <class TypeInfo>
inline bool operator == (const type_index_base<TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
return lhs == type_index_base<TypeInfo>(rhs);
}
template <class TypeInfo>
inline bool operator < (const type_index_base<TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
return lhs < type_index_base<TypeInfo>(rhs);
}
template <class TypeInfo>
inline bool operator > (const type_index_base<TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
return type_index_base<TypeInfo>(rhs) < lhs;
}
template <class TypeInfo>
inline bool operator <= (const type_index_base<TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
return !(lhs > type_index_base<TypeInfo>(rhs));
}
template <class TypeInfo>
inline bool operator >= (const type_index_base<TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
return !(lhs < type_index_base<TypeInfo>(rhs));
}
template <class TypeInfo>
inline bool operator != (const type_index_base<TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
return !(lhs == type_index_base<TypeInfo>(rhs));
}
// ######################### COMPARISONS with TypeInfo END ############################ //
#ifndef BOOST_NO_IOSTREAM
#ifdef BOOST_NO_TEMPLATED_IOSTREAMS
/// Ostream operator that will output demangled name
template <class TypeInfo>
inline std::ostream& operator<<(std::ostream& ostr, const type_index_base<TypeInfo>& ind) {
ostr << ind.pretty_name();
return ostr;
}
#else
/// Ostream operator that will output demangled name
template <class CharT, class TriatT, class TypeInfo>
inline std::basic_ostream<CharT, TriatT>& operator<<(
std::basic_ostream<CharT, TriatT>& ostr,
const type_index_base<TypeInfo>& ind)
{
ostr << ind.pretty_name();
return ostr;
}
#endif // BOOST_NO_TEMPLATED_IOSTREAMS
#endif // BOOST_NO_IOSTREAM
template <class TypeInfo>
inline std::size_t hash_value(const type_index_base<TypeInfo>& lhs) BOOST_NOEXCEPT {
return lhs.hash_code();
}
}}} // namespace boost::typeind::detail
#endif // BOOST_TYPE_INDEX_TYPE_INDEX_BASE_HPP

View File

@ -0,0 +1,204 @@
//
// Copyright (c) Antony Polukhin, 2013-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_TYPE_INDEX_FACADE_HPP
#define BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
// MS compatible compilers support #pragma once
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/config.hpp>
#include <string>
#if !defined(BOOST_NO_IOSTREAM)
#if !defined(BOOST_NO_IOSFWD)
#include <iosfwd> // for std::basic_ostream
#else
#include <ostream>
#endif
#endif
namespace boost { namespace typeind { namespace detail {
/// type_index_facade - use as a public base class for defining new
/// standard-conforming iterators.
///
template <class Derived, class TypeInfo>
class type_index_facade {
private:
Derived& derived() BOOST_NOEXCEPT {
return *static_cast<Derived*>(this);
}
const Derived & derived() const BOOST_NOEXCEPT {
return *static_cast<Derived const*>(this);
}
public:
typedef TypeInfo type_info_t;
typedef type_index_facade<Derived, TypeInfo> this_type;
const type_info_t& type_info() const BOOST_NOEXCEPT {
return derived().type_info();
}
inline const char* raw_name() const BOOST_NOEXCEPT {
return derived().raw_name();
}
inline const char* name() const BOOST_NOEXCEPT {
return derived().name();
}
inline std::string pretty_name() const {
return derived().pretty_name();
}
inline std::size_t hash_code() const BOOST_NOEXCEPT {
return derived().hash_code();
}
inline bool equal(const this_type& rhs) const BOOST_NOEXCEPT {
return derived().equal(rhs.derived());
}
inline bool before(const this_type& rhs) const BOOST_NOEXCEPT {
return derived().before(rhs.derived());
}
};
template <class Derived, class TypeInfo>
inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return lhs.equal(rhs);
}
template <class Derived, class TypeInfo>
inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return lhs.before(rhs);
}
template <class Derived, class TypeInfo>
inline bool operator > (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return rhs < lhs;
}
template <class Derived, class TypeInfo>
inline bool operator <= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return !(lhs > rhs);
}
template <class Derived, class TypeInfo>
inline bool operator >= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return !(lhs < rhs);
}
template <class Derived, class TypeInfo>
inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return !(lhs == rhs);
}
// ######################### COMPARISONS with Derived ############################ //
template <class Derived, class TypeInfo>
inline bool operator == (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return Derived(lhs) == rhs;
}
template <class Derived, class TypeInfo>
inline bool operator < (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return Derived(lhs) < rhs;
}
template <class Derived, class TypeInfo>
inline bool operator > (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return rhs < Derived(lhs);
}
template <class Derived, class TypeInfo>
inline bool operator <= (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return !(Derived(lhs) > rhs);
}
template <class Derived, class TypeInfo>
inline bool operator >= (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return !(Derived(lhs) < rhs);
}
template <class Derived, class TypeInfo>
inline bool operator != (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
return !(Derived(lhs) == rhs);
}
template <class Derived, class TypeInfo>
inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
return lhs == Derived(rhs);
}
template <class Derived, class TypeInfo>
inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
return lhs < Derived(rhs);
}
template <class Derived, class TypeInfo>
inline bool operator > (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
return Derived(rhs) < lhs;
}
template <class Derived, class TypeInfo>
inline bool operator <= (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
return !(lhs > Derived(rhs));
}
template <class Derived, class TypeInfo>
inline bool operator >= (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
return !(lhs < Derived(rhs));
}
template <class Derived, class TypeInfo>
inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
return !(lhs == Derived(rhs));
}
// ######################### COMPARISONS with Derived END ############################ //
#ifndef BOOST_NO_IOSTREAM
#ifdef BOOST_NO_TEMPLATED_IOSTREAMS
/// Ostream operator that will output demangled name
template <class Derived, class TypeInfo>
inline std::ostream& operator<<(std::ostream& ostr, const type_index_facade<Derived, TypeInfo>& ind) {
ostr << ind.pretty_name();
return ostr;
}
#else
/// Ostream operator that will output demangled name
template <class CharT, class TriatT, class Derived, class TypeInfo>
inline std::basic_ostream<CharT, TriatT>& operator<<(
std::basic_ostream<CharT, TriatT>& ostr,
const type_index_facade<Derived, TypeInfo>& ind)
{
ostr << ind.pretty_name();
return ostr;
}
#endif // BOOST_NO_TEMPLATED_IOSTREAMS
#endif // BOOST_NO_IOSTREAM
template <class Derived, class TypeInfo>
inline std::size_t hash_value(const type_index_facade<Derived, TypeInfo>& lhs) BOOST_NOEXCEPT {
return lhs.hash_code();
}
}}} // namespace boost::typeind::detail
#endif // BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP