boost/log/utility/type_info_wrapper.hpp
/* * Copyright Andrey Semashev 2007 - 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) */ /*! * \file type_info_wrapper.hpp * \author Andrey Semashev * \date 15.04.2007 * * The header contains implementation of a type information wrapper. */ #ifndef BOOST_LOG_UTILITY_TYPE_INFO_WRAPPER_HPP_INCLUDED_ #define BOOST_LOG_UTILITY_TYPE_INFO_WRAPPER_HPP_INCLUDED_ #include <typeinfo> #include <string> #include <boost/core/demangle.hpp> #include <boost/core/explicit_operator_bool.hpp> #include <boost/log/detail/config.hpp> #include <boost/log/detail/header.hpp> #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif #if defined(__GNUC__) #pragma message "Boost.Log: This header is deprecated, use Boost.TypeIndex instead." #elif defined(_MSC_VER) #pragma message("Boost.Log: This header is deprecated, use Boost.TypeIndex instead.") #endif namespace boost { BOOST_LOG_OPEN_NAMESPACE /*! * \brief A simple <tt>std::type_info</tt> wrapper that implements value semantic for type information objects * * The type info wrapper is very useful for storing type information objects in containers, * as a key or value. It also provides a number of useful features, such as default construction * and assignment support, an empty state and extended support for human-friendly type names. */ class type_info_wrapper { private: #ifndef BOOST_LOG_DOXYGEN_PASS //! An inaccessible type to indicate an uninitialized state of the wrapper struct BOOST_SYMBOL_VISIBLE uninitialized {}; #endif // BOOST_LOG_DOXYGEN_PASS private: //! A pointer to the actual type info std::type_info const* info; public: /*! * Default constructor * * \post <tt>!*this == true</tt> */ type_info_wrapper() BOOST_NOEXCEPT : info(&typeid(uninitialized)) {} /*! * Copy constructor * * \post <tt>*this == that</tt> * \param that Source type info wrapper to copy from */ type_info_wrapper(type_info_wrapper const& that) BOOST_NOEXCEPT : info(that.info) {} /*! * Conversion constructor * * \post <tt>*this == that && !!*this</tt> * \param that Type info object to be wrapped */ type_info_wrapper(std::type_info const& that) BOOST_NOEXCEPT : info(&that) {} /*! * \return \c true if the type info wrapper was initialized with a particular type, * \c false if the wrapper was default-constructed and not yet initialized */ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT() /*! * Stored type info getter * * \pre <tt>!!*this</tt> * \return Constant reference to the wrapped type info object */ std::type_info const& get() const BOOST_NOEXCEPT { return *info; } /*! * Swaps two instances of the wrapper */ void swap(type_info_wrapper& that) BOOST_NOEXCEPT { std::type_info const* temp = info; info = that.info; that.info = temp; } /*! * The method returns the contained type name string in a possibly more readable format than <tt>get().name()</tt> * * \pre <tt>!!*this</tt> * \return Type name string */ std::string pretty_name() const { if (!this->operator!()) return boost::core::demangle(info->name()); else return "[uninitialized]"; } /*! * \return \c false if the type info wrapper was initialized with a particular type, * \c true if the wrapper was default-constructed and not yet initialized */ bool operator! () const BOOST_NOEXCEPT { return (info == &typeid(uninitialized) || *info == typeid(uninitialized)); } /*! * Equality comparison * * \param that Comparand * \return If either this object or comparand is in empty state and the other is not, the result is \c false. * If both arguments are empty, the result is \c true. If both arguments are not empty, the result * is \c true if this object wraps the same type as the comparand and \c false otherwise. */ bool operator== (type_info_wrapper const& that) const BOOST_NOEXCEPT { return (info == that.info || *info == *that.info); } /*! * Ordering operator * * \pre <tt>!!*this && !!that</tt> * \param that Comparand * \return \c true if this object wraps type info object that is ordered before * the type info object in the comparand, \c false otherwise * \note The results of this operator are only consistent within a single run of application. * The result may change for the same types after rebuilding or even restarting the application. */ bool operator< (type_info_wrapper const& that) const BOOST_NOEXCEPT { return static_cast< bool >(info->before(*that.info)); } }; //! Inequality operator inline bool operator!= (type_info_wrapper const& left, type_info_wrapper const& right) BOOST_NOEXCEPT { return !left.operator==(right); } //! Ordering operator inline bool operator<= (type_info_wrapper const& left, type_info_wrapper const& right) BOOST_NOEXCEPT { return (left.operator==(right) || left.operator<(right)); } //! Ordering operator inline bool operator> (type_info_wrapper const& left, type_info_wrapper const& right) BOOST_NOEXCEPT { return !(left.operator==(right) || left.operator<(right)); } //! Ordering operator inline bool operator>= (type_info_wrapper const& left, type_info_wrapper const& right) BOOST_NOEXCEPT { return !left.operator<(right); } //! Free swap for type info wrapper inline void swap(type_info_wrapper& left, type_info_wrapper& right) BOOST_NOEXCEPT { left.swap(right); } //! The function for exception serialization to string inline std::string to_string(type_info_wrapper const& ti) { return ti.pretty_name(); } BOOST_LOG_CLOSE_NAMESPACE // namespace log } // namespace boost #include <boost/log/detail/footer.hpp> #endif // BOOST_LOG_UTILITY_TYPE_INFO_WRAPPER_HPP_INCLUDED_





