Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-17 08:52:04

0001 // Copyright (c) 2018-2025 Jean-Louis Leroy
0002 // Distributed under the Boost Software License, Version 1.0.
0003 // See accompanying file LICENSE_1_0.txt
0004 // or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_OPENMETHOD_POLICY_STD_RTTI_HPP
0007 #define BOOST_OPENMETHOD_POLICY_STD_RTTI_HPP
0008 
0009 #include <boost/openmethod/preamble.hpp>
0010 
0011 #ifndef BOOST_NO_RTTI
0012 #include <typeindex>
0013 #include <typeinfo>
0014 #include <boost/core/demangle.hpp>
0015 #endif
0016 
0017 namespace boost::openmethod::policies {
0018 
0019 //! Implements the @ref rtti policy using standard RTTI.
0020 //!
0021 //! `std_rtti` implements the `rtti` policy using the standard C++ RTTI system.
0022 //! It is the default RTTI policy.
0023 struct std_rtti : rtti {
0024     //! A RttiFn metafunction.
0025     //!
0026     //! @tparam Registry The registry containing this policy.
0027     template<class Registry>
0028     struct fn {
0029 #ifndef BOOST_NO_RTTI
0030         //! Tests if a class is polymorphic.
0031         //!
0032         //! Evaluates to `true` if `Class` is a polymorphic class, as defined by
0033         //! the C++ standard, i.e. a class that contains at least one virtual
0034         //! function.
0035         //!
0036         //! @tparam Class A class.
0037         template<class Class>
0038         static constexpr bool is_polymorphic = std::is_polymorphic_v<Class>;
0039 
0040         //! Returns the static @ref type_id of a type.
0041         //!
0042         //! Returns `&typeid(Class)`, cast to `type_id`.
0043         //!
0044         //! @tparam Class A class.
0045         //! @return The static type_id of Class.
0046         template<class Class>
0047         static auto static_type() -> type_id {
0048             return &typeid(Class);
0049         }
0050 
0051         //! Returns the dynamic @ref type_id of an object.
0052         //!
0053         //! Returns `&typeid(obj)`, cast to `type_id`.
0054         //!
0055         //! @tparam Class A registered class.
0056         //! @param obj A reference to an instance of `Class`.
0057         //! @return The type_id of `obj`'s class.
0058         template<class Class>
0059         static auto dynamic_type(const Class& obj) -> type_id {
0060             return &typeid(obj);
0061         }
0062 
0063         //! Writes a representation of a @ref type_id to a stream.
0064         //!
0065         //! Writes the demangled name of the class identified by `type` to
0066         //! `stream`.
0067         //!
0068         //! @tparam Stream A SimpleOutputStream.
0069         //! @param type The `type_id` to write.
0070         //! @param stream The stream to write to.
0071         template<typename Stream>
0072         static auto type_name(type_id type, Stream& stream) -> void {
0073             stream << boost::core::demangle(
0074                 reinterpret_cast<const std::type_info*>(type)->name());
0075         }
0076 
0077         //! Returns a key that uniquely identifies a class.
0078         //!
0079         //! C++ does *not* guarantee that there is a single instance of
0080         //! `std::type_info` per type. `std_rtti` uses the addresses of
0081         //! `std::type_index` objects as `type_id`s. Thus, the same class may
0082         //! have multiple corresponding `type_id`s. `std::type_index` objects,
0083         //! on the other hand, are guaranteed to compare as equal iff they
0084         //! correspond to the same class, and they can be used to identify the
0085         //! `type_id`s pertaining to the same class.
0086         //!
0087         //! @param type A `type_id`.
0088         //! @return A `std::type_index` for `type` (cast to a `const std::type_info&`).
0089         static auto type_index(type_id type) -> std::type_index {
0090             return std::type_index(
0091                 *reinterpret_cast<const std::type_info*>(type));
0092         }
0093 
0094         //! Casts an object to a type.
0095         //!
0096         //! Casts `obj` to a reference to an instance of `D`, using
0097         //! `dynamic_cast`.
0098         //!
0099         //! @tparam D A reference to a subclass of `B`.
0100         //! @tparam B A registered class.
0101         //! @param obj A reference to an instance of `B`.
0102         template<typename D, typename B>
0103         static auto dynamic_cast_ref(B&& obj) -> D {
0104             return dynamic_cast<D>(obj);
0105         }
0106 #endif
0107     };
0108 };
0109 
0110 } // namespace boost::openmethod::policies
0111 
0112 #endif