File indexing completed on 2025-01-30 10:03:45
0001
0002
0003
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