123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- //
- // Copyright (c) 2013-2019 Antony Polukhin.
- //
- //
- // 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 <boost/container_hash/hash_fwd.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
- 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 Derived class header \b must include <boost/container_hash/hash.hpp>, \b unless this function is redefined in
- /// Derived class to not use boost::hash_range().
- 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/container_hash/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
|