Back to home page

EIC code displayed by LXR

 
 

    


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

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_INTEROP_UNIQUE_PTR_HPP
0007 #define BOOST_OPENMETHOD_INTEROP_UNIQUE_PTR_HPP
0008 
0009 #include <boost/openmethod/core.hpp>
0010 
0011 #include <memory>
0012 
0013 namespace boost::openmethod {
0014 
0015 //! Specialize virtual_traits for std::unique_ptr by value.
0016 //!
0017 //! @tparam Class A class type, possibly cv-qualified.
0018 //! @tparam Registry A @ref registry.
0019 template<class Class, class Registry>
0020 struct virtual_traits<std::unique_ptr<Class>, Registry> {
0021     //! `Class`, stripped from cv-qualifiers.
0022     using virtual_type = std::remove_cv_t<Class>;
0023 
0024     //! Return a reference to a non-modifiable `Class` object.
0025     //! @param arg A reference to a `std::unique_ptr<Class>`.
0026     //! @return A reference to the object pointed to.
0027     static auto peek(const std::unique_ptr<Class>& arg) -> const Class& {
0028         return *arg;
0029     }
0030 
0031     //! Cast to a type.
0032     //!
0033     //! Cast a reference to the managed object, using `static_cast` if possible,
0034     //! and `Registry::rtti::dynamic_cast_ref` otherwise. If the cast succeeds,
0035     //! transfer ownership to a `std::unique_ptr` to the target type, and return
0036     //! it.
0037     //!
0038     //! @tparam Derived A xvalue reference to a `std::unique_ptr`.
0039     //! @param obj A xvalue reference to a `std::unique_ptr`.
0040     //! @return A `std::unique_ptr<Derived::element_type>`.
0041     template<typename Derived>
0042     static auto cast(std::unique_ptr<Class>&& ptr) {
0043         if constexpr (detail::requires_dynamic_cast<Class&, Derived&>) {
0044             auto p = &Registry::rtti::template dynamic_cast_ref<
0045                 typename Derived::element_type&>(*ptr);
0046             ptr.release();
0047             return Derived(p);
0048         } else {
0049             auto p = &static_cast<typename Derived::element_type&>(*ptr);
0050             ptr.release();
0051             return Derived(p);
0052         }
0053     }
0054 
0055     //! Rebind to a different element type.
0056     //!
0057     //! @tparam Other The new element type.
0058     template<class Other>
0059     using rebind = std::unique_ptr<Other>;
0060 };
0061 
0062 //! Alias for a `virtual_ptr<std::unique_ptr<T>>`.
0063 template<class Class, class Registry = BOOST_OPENMETHOD_DEFAULT_REGISTRY>
0064 using unique_virtual_ptr = virtual_ptr<std::unique_ptr<Class>, Registry>;
0065 
0066 //! Create a new object and return a `unique_virtual_ptr` to it.
0067 //!
0068 //! Create an object using `std::make_unique`, and return a @ref
0069 //! unique_virtual_ptr pointing to it. Since the exact class of the object is
0070 //! known, the `virtual_ptr` is created using @ref final_virtual_ptr.
0071 //!
0072 //! `Class` is _not_ required to be a polymorphic class.
0073 //!
0074 //! @tparam Class The class of the object to create.
0075 //! @tparam Registry A @ref registry.
0076 //! @tparam T Types of the arguments to pass to the constructor of `Class`.
0077 //! @param args Arguments to pass to the constructor of `Class`.
0078 //! @return A `unique_virtual_ptr<Class, Registry>` pointing to a newly
0079 //! created object of type `Class`.
0080 template<
0081     class Class, class Registry = BOOST_OPENMETHOD_DEFAULT_REGISTRY,
0082     typename... T>
0083 inline auto make_unique_virtual(T&&... args) {
0084     return final_virtual_ptr<Registry>(
0085         std::make_unique<Class>(std::forward<T>(args)...));
0086 }
0087 
0088 namespace aliases {
0089 using boost::openmethod::make_unique_virtual;
0090 using boost::openmethod::unique_virtual_ptr;
0091 } // namespace aliases
0092 
0093 } // namespace boost::openmethod
0094 
0095 #endif