// // Copyright (c) Chris Glover, 2016. // // // 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_RUNTIME_CAST_REGISTER_RUNTIME_CLASS_HPP #define BOOST_TYPE_INDEX_RUNTIME_CAST_REGISTER_RUNTIME_CLASS_HPP /// \file register_runtime_class.hpp /// \brief Contains the macro BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS #include #include #ifdef BOOST_HAS_PRAGMA_ONCE # pragma once #endif namespace boost { namespace typeindex { namespace detail { template inline type_index runtime_class_construct_type_id(T const*) { return type_id(); } } // namespace detail /// @cond #define BOOST_TYPE_INDEX_CHECK_BASE_(r, data, Base) \ if(void const* ret_val = this->Base::boost_type_index_find_instance_(idx)) return ret_val; /// @endcond /// \def BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS /// \brief Macro used to make a class compatible with boost::typeindex::runtime_cast /// /// BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS generates a virtual function /// in the current class that, when combined with the supplied base class information, allows /// boost::typeindex::runtime_cast to accurately convert between dynamic types of instances of /// the current class. /// /// \b Example: /// \code /// struct base1 { /// BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(BOOST_TYPE_INDEX_NO_BASE_CLASS) /// virtual ~base1(); /// }; /// /// struct base2 { /// BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(BOOST_TYPE_INDEX_NO_BASE_CLASS) /// virtual ~base2(); /// }; /// /// struct derived1 : base1 { /// BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS((base1)) /// }; /// /// struct derived2 : base1, base2 { /// BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS((base1)(base2)) /// }; /// /// ... /// /// base1* pb1 = get_object(); /// if(derived2* pb2 = boost::typeindex::runtime_cast(pb1)) /// { /* ... */ } /// \endcode /// /// \param base_class_seq A Boost.Preprocessor sequence of the current class' direct bases, or /// BOOST_PP_SEQ_NIL if this class has no direct base classes. #define BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS(base_class_seq) \ BOOST_TYPE_INDEX_REGISTER_CLASS \ virtual void const* boost_type_index_find_instance_(boost::typeindex::type_index const& idx) const BOOST_NOEXCEPT { \ if(idx == boost::typeindex::detail::runtime_class_construct_type_id(this)) \ return this; \ BOOST_PP_SEQ_FOR_EACH(BOOST_TYPE_INDEX_CHECK_BASE_, _, base_class_seq) \ return NULL; \ } }} // namespace boost::typeindex #define BOOST_TYPE_INDEX_NO_BASE_CLASS BOOST_PP_SEQ_NIL #endif // BOOST_TYPE_INDEX_RUNTIME_CAST_REGISTER_RUNTIME_CLASS_HPP