301 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			301 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
//
 | 
						|
// Copyright (c) Antony Polukhin, 2013-2015.
 | 
						|
//
 | 
						|
//
 | 
						|
// 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
 | 
						|
 | 
						|
#include <boost/config.hpp>
 | 
						|
#include <string>
 | 
						|
#include <cstring>
 | 
						|
 | 
						|
#if !defined(BOOST_NO_IOSTREAM)
 | 
						|
#if !defined(BOOST_NO_IOSFWD)
 | 
						|
#include <iosfwd>               // for std::basic_ostream
 | 
						|
#else
 | 
						|
#include <ostream>
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef BOOST_HAS_PRAGMA_ONCE
 | 
						|
# pragma once
 | 
						|
#endif
 | 
						|
 | 
						|
// Forward declaration from #include <boost/functional/hash_fwd.hpp>
 | 
						|
namespace boost {
 | 
						|
    template <class It> std::size_t hash_range(It, It);
 | 
						|
}
 | 
						|
 | 
						|
namespace boost { namespace typeindex {
 | 
						|
 | 
						|
/// \class type_index_facade
 | 
						|
///
 | 
						|
/// This class takes care about the comparison operators, hash functions and 
 | 
						|
/// ostream operators. Use this class as a public base class for defining new
 | 
						|
/// type_info-conforming classes.
 | 
						|
///
 | 
						|
/// \b Example:
 | 
						|
/// \code
 | 
						|
/// class stl_type_index: public type_index_facade<stl_type_index, std::type_info> 
 | 
						|
/// {
 | 
						|
/// public:
 | 
						|
///     typedef std::type_info type_info_t;
 | 
						|
/// private:
 | 
						|
///     const type_info_t* data_;
 | 
						|
///
 | 
						|
/// public:
 | 
						|
///     stl_type_index(const type_info_t& data) noexcept
 | 
						|
///         : data_(&data)
 | 
						|
///     {}
 | 
						|
/// // ...
 | 
						|
/// };
 | 
						|
/// \endcode
 | 
						|
///
 | 
						|
/// \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:
 | 
						|
    /// @cond
 | 
						|
    BOOST_CXX14_CONSTEXPR const Derived & derived() const BOOST_NOEXCEPT {
 | 
						|
      return *static_cast<Derived const*>(this);
 | 
						|
    }
 | 
						|
    /// @endcond
 | 
						|
public:
 | 
						|
    typedef TypeInfo                                type_info_t;
 | 
						|
 | 
						|
    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
 | 
						|
    /// \return Name of a type. By default returns Derived::raw_name().
 | 
						|
    inline const char* name() const BOOST_NOEXCEPT {
 | 
						|
        return derived().raw_name();
 | 
						|
    }
 | 
						|
 | 
						|
    /// \b Override: This function \b may be redefined in Derived class. Overrides may throw.
 | 
						|
    /// \return Human readable type name. By default returns Derived::name().
 | 
						|
    inline std::string pretty_name() const {
 | 
						|
        return derived().name();
 | 
						|
    }
 | 
						|
 | 
						|
    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
 | 
						|
    /// \return True if two types are equal. By default compares types by raw_name().
 | 
						|
    inline bool equal(const Derived& rhs) const BOOST_NOEXCEPT {
 | 
						|
        const char* const left = derived().raw_name();
 | 
						|
        const char* const right = rhs.raw_name();
 | 
						|
        return left == right || !std::strcmp(left, right);
 | 
						|
    }
 | 
						|
 | 
						|
    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
 | 
						|
    /// \return True if rhs is greater than this. By default compares types by raw_name().
 | 
						|
    inline bool before(const Derived& rhs) const BOOST_NOEXCEPT {
 | 
						|
        const char* const left = derived().raw_name();
 | 
						|
        const char* const right = rhs.raw_name();
 | 
						|
        return left != right && std::strcmp(left, right) < 0;
 | 
						|
    }
 | 
						|
 | 
						|
    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
 | 
						|
    /// \return Hash code of a type. By default hashes types by raw_name().
 | 
						|
    /// \note <boost/functional/hash.hpp> has to be included if this function is used.
 | 
						|
    inline std::size_t hash_code() const BOOST_NOEXCEPT {
 | 
						|
        const char* const name_raw = derived().raw_name();
 | 
						|
        return boost::hash_range(name_raw, name_raw + std::strlen(name_raw));
 | 
						|
    }
 | 
						|
 | 
						|
#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.
 | 
						|
    ///
 | 
						|
    /// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw. 
 | 
						|
    /// Overrides \b must remove const, volatile && and & modifiers from T.
 | 
						|
    /// \tparam T Type for which type_index must be created.
 | 
						|
    /// \return type_index for type T.
 | 
						|
    template <class T>
 | 
						|
    static Derived type_id() BOOST_NOEXCEPT;
 | 
						|
 | 
						|
    /// This is a factory method that is used to create instances of Derived classes.
 | 
						|
    /// boost::typeindex::type_id_with_cvr() will call this method, if Derived has same type as boost::typeindex::type_index.
 | 
						|
    ///
 | 
						|
    /// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw. 
 | 
						|
    /// Overrides \b must \b not remove const, volatile && and & modifiers from T.
 | 
						|
    /// \tparam T Type for which type_index must be created.
 | 
						|
    /// \return type_index for type T.
 | 
						|
    template <class T>
 | 
						|
    static Derived type_id_with_cvr() BOOST_NOEXCEPT;
 | 
						|
 | 
						|
    /// This is a factory method that is used to create instances of Derived classes.
 | 
						|
    /// boost::typeindex::type_id_runtime(const T&) will call this method, if Derived has same type as boost::typeindex::type_index.
 | 
						|
    ///
 | 
						|
    /// \b Override: This function \b may be redefined and made public in Derived class.
 | 
						|
    /// \param variable Variable which runtime type will be stored in type_index.
 | 
						|
    /// \return type_index with runtime type of variable.
 | 
						|
    template <class T>
 | 
						|
    static Derived type_id_runtime(const T& variable) BOOST_NOEXCEPT;
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
};
 | 
						|
 | 
						|
/// @cond
 | 
						|
template <class Derived, class TypeInfo>
 | 
						|
BOOST_CXX14_CONSTEXPR inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
 | 
						|
    return static_cast<Derived const&>(lhs).equal(static_cast<Derived const&>(rhs));
 | 
						|
}
 | 
						|
 | 
						|
template <class Derived, class TypeInfo>
 | 
						|
BOOST_CXX14_CONSTEXPR inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
 | 
						|
    return static_cast<Derived const&>(lhs).before(static_cast<Derived const&>(rhs));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
template <class Derived, class TypeInfo>
 | 
						|
BOOST_CXX14_CONSTEXPR 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>
 | 
						|
BOOST_CXX14_CONSTEXPR 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>
 | 
						|
BOOST_CXX14_CONSTEXPR 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>
 | 
						|
BOOST_CXX14_CONSTEXPR 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 ############################ //
 | 
						|
 | 
						|
/// @endcond
 | 
						|
 | 
						|
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
 | 
						|
 | 
						|
/// noexcept comparison operators for type_index_facade classes.
 | 
						|
bool operator ==, !=, <, ... (const type_index_facade& lhs, const type_index_facade& rhs) noexcept;
 | 
						|
 | 
						|
/// noexcept comparison operators for type_index_facade and it's TypeInfo classes.
 | 
						|
bool operator ==, !=, <, ... (const type_index_facade& lhs, const TypeInfo& rhs) noexcept;
 | 
						|
 | 
						|
/// noexcept comparison operators for type_index_facade's TypeInfo and type_index_facade classes.
 | 
						|
bool operator ==, !=, <, ... (const TypeInfo& lhs, const type_index_facade& rhs) noexcept;
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef BOOST_NO_IOSTREAM
 | 
						|
#ifdef BOOST_NO_TEMPLATED_IOSTREAMS
 | 
						|
/// @cond
 | 
						|
/// 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 << static_cast<Derived const&>(ind).pretty_name();
 | 
						|
    return ostr;
 | 
						|
}
 | 
						|
/// @endcond
 | 
						|
#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 << static_cast<Derived const&>(ind).pretty_name();
 | 
						|
    return ostr;
 | 
						|
}
 | 
						|
#endif // BOOST_NO_TEMPLATED_IOSTREAMS
 | 
						|
#endif // BOOST_NO_IOSTREAM
 | 
						|
 | 
						|
/// This free function is used by Boost's unordered containers.
 | 
						|
/// \note <boost/functional/hash.hpp> has to be included if this function is used.
 | 
						|
template <class Derived, class TypeInfo>
 | 
						|
inline std::size_t hash_value(const type_index_facade<Derived, TypeInfo>& lhs) BOOST_NOEXCEPT {
 | 
						|
    return static_cast<Derived const&>(lhs).hash_code();
 | 
						|
}
 | 
						|
 | 
						|
}} // namespace boost::typeindex
 | 
						|
 | 
						|
#endif // BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
 | 
						|
 |