Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:03:45

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // Copyright (c) Lewis Baker
0003 // Licenced under MIT license. See LICENSE.txt for details.
0004 ///////////////////////////////////////////////////////////////////////////////
0005 #ifndef CPPCORO_DETAIL_MANUAL_LIFETIME_HPP_INCLUDED
0006 #define CPPCORO_DETAIL_MANUAL_LIFETIME_HPP_INCLUDED
0007 
0008 #include <type_traits>
0009 #include <memory>
0010 
0011 namespace cppcoro::detail
0012 {
0013     template<typename T>
0014     struct manual_lifetime
0015     {
0016     public:
0017         manual_lifetime() noexcept {}
0018         ~manual_lifetime() noexcept {}
0019 
0020         manual_lifetime(const manual_lifetime&) = delete;
0021         manual_lifetime(manual_lifetime&&) = delete;
0022         manual_lifetime& operator=(const manual_lifetime&) = delete;
0023         manual_lifetime& operator=(manual_lifetime&&) = delete;
0024 
0025         template<typename... Args>
0026         std::enable_if_t<std::is_constructible_v<T, Args&&...>> construct(Args&&... args)
0027             noexcept(std::is_nothrow_constructible_v<T, Args&&...>)
0028         {
0029             ::new (static_cast<void*>(std::addressof(m_value))) T(static_cast<Args&&>(args)...);
0030         }
0031 
0032         void destruct() noexcept(std::is_nothrow_destructible_v<T>)
0033         {
0034             m_value.~T();
0035         }
0036 
0037         std::add_pointer_t<T> operator->() noexcept { return std::addressof(**this); }
0038         std::add_pointer_t<const T> operator->() const noexcept { return std::addressof(**this); }
0039 
0040         T& operator*() & noexcept { return m_value; }
0041         const T& operator*() const & noexcept { return m_value; }
0042         T&& operator*() && noexcept { return static_cast<T&&>(m_value); }
0043         const T&& operator*() const && noexcept { return static_cast<const T&&>(m_value); }
0044 
0045     private:
0046         union {
0047             T m_value;
0048         };
0049     };
0050 
0051     template<typename T>
0052     struct manual_lifetime<T&>
0053     {
0054     public:
0055         manual_lifetime() noexcept {}
0056         ~manual_lifetime() noexcept {}
0057 
0058         manual_lifetime(const manual_lifetime&) = delete;
0059         manual_lifetime(manual_lifetime&&) = delete;
0060         manual_lifetime& operator=(const manual_lifetime&) = delete;
0061         manual_lifetime& operator=(manual_lifetime&&) = delete;
0062 
0063         void construct(T& value) noexcept
0064         {
0065             m_value = std::addressof(value);
0066         }
0067 
0068         void destruct() noexcept {}
0069 
0070         T* operator->() noexcept { return m_value; }
0071         const T* operator->() const noexcept { return m_value; }
0072 
0073         T& operator*() noexcept { return *m_value; }
0074         const T& operator*() const noexcept { return *m_value; }
0075 
0076     private:
0077         T* m_value;
0078     };
0079 
0080     template<typename T>
0081     struct manual_lifetime<T&&>
0082     {
0083     public:
0084         manual_lifetime() noexcept {}
0085         ~manual_lifetime() noexcept {}
0086 
0087         manual_lifetime(const manual_lifetime&) = delete;
0088         manual_lifetime(manual_lifetime&&) = delete;
0089         manual_lifetime& operator=(const manual_lifetime&) = delete;
0090         manual_lifetime& operator=(manual_lifetime&&) = delete;
0091 
0092         void construct(T&& value) noexcept
0093         {
0094             m_value = std::addressof(value);
0095         }
0096 
0097         void destruct() noexcept {}
0098 
0099         T* operator->() noexcept { return m_value; }
0100         const T* operator->() const noexcept { return m_value; }
0101 
0102         T& operator*() & noexcept { return *m_value; }
0103         const T& operator*() const & noexcept { return *m_value; }
0104         T&& operator*() && noexcept { return static_cast<T&&>(*m_value); }
0105         const T&& operator*() const && noexcept { return static_cast<const T&&>(*m_value); }
0106 
0107     private:
0108         T* m_value;
0109     };
0110 
0111     template<>
0112     struct manual_lifetime<void>
0113     {
0114         void construct() noexcept {}
0115         void destruct() noexcept {}
0116         void operator*() const noexcept {}
0117     };
0118 }
0119 
0120 #endif