forked from boostorg/type_index
Reimplement and simplify design using type_index_facade class
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
204
include/boost/type_index/type_index_facade.hpp
Normal file
204
include/boost/type_index/type_index_facade.hpp
Normal 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
|
||||
|
Reference in New Issue
Block a user