diff --git a/include/boost/type_index.hpp b/include/boost/type_index.hpp index dec4530..7bd2c2b 100644 --- a/include/boost/type_index.hpp +++ b/include/boost/type_index.hpp @@ -86,11 +86,12 @@ typedef type_index::type_info_t type_info; /// std::cout << ti.pretty_name(); // Outputs 'int' /// \endcode /// +/// \tparam T Type for which type_index must be created. /// \throw Nothing. /// \return boost::typeind::type_index with information about the specified type T. template inline type_index type_id() BOOST_NOEXCEPT { - return type_index::construct(); + return type_index::type_id(); } /// Function for constructing boost::type_index instance for type T. @@ -105,11 +106,12 @@ inline type_index type_id() BOOST_NOEXCEPT { /// std::cout << ti.pretty_name(); // Outputs 'int&' /// \endcode /// +/// \tparam T Type for which type_index must be created. /// \throw Nothing. /// \return boost::typeind::type_index with information about the specified type T. template inline type_index type_id_with_cvr() BOOST_NOEXCEPT { - return type_index::construct_with_cvr(); + return type_index::type_id_with_cvr(); } /// Function that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index. @@ -135,10 +137,9 @@ inline type_index type_id_with_cvr() BOOST_NOEXCEPT { /// \return boost::typeind::type_index with information about the specified variable. template inline type_index type_id_runtime(const T& runtime_val) BOOST_NOEXCEPT { - return type_index::construct_runtime(runtime_val); + return type_index::type_id_runtime(runtime_val); } -/// Function that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index. /// Function that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index. /// /// Retunrs runtime information about specified type. @@ -161,7 +162,7 @@ inline type_index type_id_runtime(const T& runtime_val) BOOST_NOEXCEPT { /// \return boost::typeind::type_index with information about the specified variable. template inline type_index type_id_runtime(const T* runtime_val) { - return type_index::construct_runtime(runtime_val); + return type_index::type_id_runtime(runtime_val); } }} // namespace boost::typeind diff --git a/include/boost/type_index/ctti_type_index.hpp b/include/boost/type_index/ctti_type_index.hpp index 41a2fbb..cdf0728 100644 --- a/include/boost/type_index/ctti_type_index.hpp +++ b/include/boost/type_index/ctti_type_index.hpp @@ -48,12 +48,21 @@ inline const ctti_data& ctti_construct() BOOST_NOEXCEPT { } // namespace detail /// \class ctti_type_index +/// This class is a wrapper that pretends to work exactly like stl_type_info, but does +/// not require RTTI support. For description of functions see type_index_facade. +/// +/// This class produces slightly longer type names, so consider using stl_type_index +/// in situations when typeid() is working. class ctti_type_index: public type_index_facade { const detail::ctti_data* data_; public: typedef detail::ctti_data type_info_t; + inline ctti_type_index() BOOST_NOEXCEPT + : data_(&detail::ctti_construct()) + {} + inline ctti_type_index(const type_info_t& data) BOOST_NOEXCEPT : data_(&data) {} @@ -64,21 +73,21 @@ public: inline std::size_t hash_code() const BOOST_NOEXCEPT; template - inline static ctti_type_index construct() BOOST_NOEXCEPT; + inline static ctti_type_index type_id() BOOST_NOEXCEPT; template - inline static ctti_type_index construct_with_cvr() BOOST_NOEXCEPT; + inline static ctti_type_index type_id_with_cvr() BOOST_NOEXCEPT; template - inline static ctti_type_index construct_runtime(const T* variable) BOOST_NOEXCEPT; + inline static ctti_type_index type_id_runtime(const T* variable) BOOST_NOEXCEPT; template - inline static ctti_type_index construct_runtime(const T& variable) BOOST_NOEXCEPT; + inline static ctti_type_index type_id_runtime(const T& variable) BOOST_NOEXCEPT; }; template -inline ctti_type_index ctti_type_index::construct() BOOST_NOEXCEPT { +inline ctti_type_index ctti_type_index::type_id() BOOST_NOEXCEPT { typedef BOOST_DEDUCED_TYPENAME boost::remove_reference::type no_ref_t; typedef BOOST_DEDUCED_TYPENAME boost::remove_cv::type no_cvr_t; return detail::ctti_construct(); @@ -87,13 +96,13 @@ inline ctti_type_index ctti_type_index::construct() BOOST_NOEXCEPT { template -inline ctti_type_index ctti_type_index::construct_with_cvr() BOOST_NOEXCEPT { +inline ctti_type_index ctti_type_index::type_id_with_cvr() BOOST_NOEXCEPT { return detail::ctti_construct(); } template -inline ctti_type_index ctti_type_index::construct_runtime(const T* rtti_val) BOOST_NOEXCEPT { +inline ctti_type_index ctti_type_index::type_id_runtime(const T* rtti_val) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT_MSG(sizeof(T) && false, "type_id_runtime(const T*) and type_index::construct_runtime(const T*) require RTTI"); @@ -101,7 +110,7 @@ inline ctti_type_index ctti_type_index::construct_runtime(const T* rtti_val) BOO } template -inline ctti_type_index ctti_type_index::construct_runtime(const T& rtti_val) BOOST_NOEXCEPT { +inline ctti_type_index ctti_type_index::type_id_runtime(const T& rtti_val) BOOST_NOEXCEPT { BOOST_STATIC_ASSERT_MSG(sizeof(T) && false, "type_id_runtime(const T&) and type_index::construct_runtime(const T&) require RTTI"); diff --git a/include/boost/type_index/stl_type_index.hpp b/include/boost/type_index/stl_type_index.hpp index 080d9db..a5f9a0b 100644 --- a/include/boost/type_index/stl_type_index.hpp +++ b/include/boost/type_index/stl_type_index.hpp @@ -61,6 +61,10 @@ namespace boost { namespace typeind { /// \class stl_type_index +/// This class is a wrapper around std::type_info, that workarounds issues and provides +/// much more rich interface. For description of functions see type_index_facade. +/// +/// This class requires typeid() to work. For cases when RTTI is disabled see ctti_type_index. class stl_type_index : public type_index_facade< stl_type_index, @@ -82,6 +86,10 @@ private: const type_info_t* data_; public: + inline stl_type_index() BOOST_NOEXCEPT + : data_(&typeid(void)) + {} + inline stl_type_index(const type_info_t& data) BOOST_NOEXCEPT : data_(&data) {} @@ -97,16 +105,16 @@ public: inline bool before(const stl_type_index& rhs) const BOOST_NOEXCEPT; template - inline static stl_type_index construct() BOOST_NOEXCEPT; + inline static stl_type_index type_id() BOOST_NOEXCEPT; template - inline static stl_type_index construct_with_cvr() BOOST_NOEXCEPT; + inline static stl_type_index type_id_with_cvr() BOOST_NOEXCEPT; template - inline static stl_type_index construct_runtime(const T* variable); + inline static stl_type_index type_id_runtime(const T* variable); template - inline static stl_type_index construct_runtime(const T& value) BOOST_NOEXCEPT; + inline static stl_type_index type_id_runtime(const T& value) BOOST_NOEXCEPT; }; inline const stl_type_index::type_info_t& stl_type_index::type_info() const BOOST_NOEXCEPT { @@ -210,7 +218,7 @@ inline bool stl_type_index::before(const stl_type_index& rhs) const BOOST_NOEXCE template -inline stl_type_index stl_type_index::construct() BOOST_NOEXCEPT { +inline stl_type_index stl_type_index::type_id() BOOST_NOEXCEPT { typedef BOOST_DEDUCED_TYPENAME boost::remove_reference::type no_ref_t; typedef BOOST_DEDUCED_TYPENAME boost::remove_cv::type no_cvr_t; @@ -228,7 +236,7 @@ namespace detail { } template -inline stl_type_index stl_type_index::construct_with_cvr() BOOST_NOEXCEPT { +inline stl_type_index stl_type_index::type_id_with_cvr() BOOST_NOEXCEPT { typedef typename boost::mpl::if_c< boost::is_reference::value || boost::is_const::value @@ -241,7 +249,7 @@ inline stl_type_index stl_type_index::construct_with_cvr() BOOST_NOEXCEPT { } template -inline stl_type_index stl_type_index::construct_runtime(const T* rtti_val) { +inline stl_type_index stl_type_index::type_id_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"); @@ -250,7 +258,7 @@ inline stl_type_index stl_type_index::construct_runtime(const T* rtti_val) { } template -inline stl_type_index stl_type_index::construct_runtime(const T& value) BOOST_NOEXCEPT { +inline stl_type_index stl_type_index::type_id_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"); diff --git a/include/boost/type_index/type_index_facade.hpp b/include/boost/type_index/type_index_facade.hpp index 60fb384..f4571c7 100644 --- a/include/boost/type_index/type_index_facade.hpp +++ b/include/boost/type_index/type_index_facade.hpp @@ -106,6 +106,49 @@ public: inline std::size_t hash_code() const BOOST_NOEXCEPT { return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name())); } + +#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED) +protected: + /// This is a factory method that is used to create instances of Derived classes. + /// boost::typeind::type_id() will call this method, if Derived has same type as boost::typeind::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 + static Derived type_id() BOOST_NOEXCEPT; + + /// This is a factory method that is used to create instances of Derived classes. + /// boost::typeind::type_id_with_cvr() will call this method, if Derived has same type as boost::typeind::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 + static Derived type_id_with_cvr() BOOST_NOEXCEPT; + + /// This is a factory method that is used to create instances of Derived classes. + /// boost::typeind::type_id_runtime(const T*) will call this method, if Derived has same type as boost::typeind::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 + static Derived type_id_runtime(const T* variable); + + /// This is a factory method that is used to create instances of Derived classes. + /// boost::typeind::type_id_runtime(const T&) will call this method, if Derived has same type as boost::typeind::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 + static Derived type_id_runtime(const T& variablel) BOOST_NOEXCEPT; + +#endif + }; /// @cond diff --git a/test/type_index_test.cpp b/test/type_index_test.cpp index d1a1dec..cf05730 100644 --- a/test/type_index_test.cpp +++ b/test/type_index_test.cpp @@ -35,6 +35,30 @@ BOOST_AUTO_TEST_CASE(names_matches_type_id) BOOST_CHECK_EQUAL(type_id().name(), type_id().name()); } +BOOST_AUTO_TEST_CASE(default_construction) +{ + using namespace boost::typeind; + type_index ti1, ti2; + BOOST_CHECK_EQUAL(ti1, ti2); + BOOST_CHECK_EQUAL(type_id(), ti1); + + BOOST_CHECK_EQUAL(type_id().name(), ti1.name()); + BOOST_CHECK_NE(type_id(), ti1); +} + + +BOOST_AUTO_TEST_CASE(copy_construction) +{ + using namespace boost::typeind; + type_index ti1, ti2 = type_id(); + BOOST_CHECK_NE(ti1, ti2); + ti1 = ti2; + BOOST_CHECK_EQUAL(ti2, ti1); + + const type_index ti3(ti1); + BOOST_CHECK_EQUAL(ti3, ti1); +} + BOOST_AUTO_TEST_CASE(comparators_type_id) { using namespace boost::typeind;