1111#define PHASAR_UTILS_MAYBEUNIQUEPTR_H_
1212
1313#include " llvm/ADT/PointerIntPair.h"
14+ #include " llvm/Support/PointerLikeTypeTraits.h"
1415
1516#include < memory>
1617#include < type_traits>
@@ -39,8 +40,12 @@ template <typename T, bool RequireAlignment> class MaybeUniquePtrBase {
3940};
4041
4142template <typename T> class MaybeUniquePtrBase <T, true > {
43+ struct PointerTraits : llvm::PointerLikeTypeTraits<T *> {
44+ static constexpr int NumLowBitsAvailable = 1 ;
45+ };
46+
4247protected:
43- llvm::PointerIntPair<T *, 1 , bool > Data{};
48+ llvm::PointerIntPair<T *, 1 , bool , PointerTraits > Data{};
4449
4550 constexpr MaybeUniquePtrBase (T *Ptr, bool Owns) noexcept : Data{Ptr, Owns} {}
4651 constexpr MaybeUniquePtrBase () noexcept = default;
@@ -61,12 +66,15 @@ class MaybeUniquePtr : detail::MaybeUniquePtrBase<T, RequireAlignment> {
6166 constexpr MaybeUniquePtr () noexcept = default;
6267
6368 constexpr MaybeUniquePtr (T *Pointer, bool Owns = false ) noexcept
64- : detail::MaybeUniquePtrBase<T, RequireAlignment>(Pointer, Owns) {}
69+ : detail::MaybeUniquePtrBase<T, RequireAlignment>(Pointer,
70+ Owns && Pointer) {}
6571
6672 constexpr MaybeUniquePtr (std::unique_ptr<T> &&Owner) noexcept
6773 : MaybeUniquePtr(Owner.release(), true) {}
6874
69- template <typename TT>
75+ template <typename TT,
76+ typename = std::enable_if_t <!std::is_same_v<T, TT> &&
77+ std::is_convertible_v<TT *, T *>>>
7078 constexpr MaybeUniquePtr (std::unique_ptr<TT> &&Owner) noexcept
7179 : MaybeUniquePtr(Owner.release(), true) {}
7280
@@ -92,16 +100,20 @@ class MaybeUniquePtr : detail::MaybeUniquePtrBase<T, RequireAlignment> {
92100 if (owns ()) {
93101 delete Data.getPointer ();
94102 }
95- Data = {Owner.release (), true };
103+ auto *Ptr = Owner.release ();
104+ Data = {Ptr, Ptr != nullptr };
96105 return *this ;
97106 }
98107
99- template <typename TT>
108+ template <typename TT,
109+ typename = std::enable_if_t <!std::is_same_v<T, TT> &&
110+ std::is_convertible_v<TT *, T *>>>
100111 constexpr MaybeUniquePtr &operator =(std::unique_ptr<TT> &&Owner) noexcept {
101112 if (owns ()) {
102113 delete Data.getPointer ();
103114 }
104- Data = {Owner.release (), true };
115+ auto *Ptr = Owner.release ();
116+ Data = {Ptr, Ptr != nullptr };
105117 return *this ;
106118 }
107119
@@ -118,24 +130,16 @@ class MaybeUniquePtr : detail::MaybeUniquePtrBase<T, RequireAlignment> {
118130 }
119131 }
120132
121- [[nodiscard]] constexpr T *get () noexcept { return Data.getPointer (); }
122- [[nodiscard]] constexpr const T *get () const noexcept {
123- return Data.getPointer ();
124- }
133+ [[nodiscard]] constexpr T *get () const noexcept { return Data.getPointer (); }
125134
126- [[nodiscard]] constexpr T *operator ->() noexcept { return get (); }
127- [[nodiscard]] constexpr const T *operator ->() const noexcept { return get (); }
135+ [[nodiscard]] constexpr T *operator ->() const noexcept { return get (); }
128136
129- [[nodiscard]] constexpr T &operator *() noexcept {
130- assert (get () != nullptr );
131- return *get ();
132- }
133- [[nodiscard]] constexpr const T &operator *() const noexcept {
137+ [[nodiscard]] constexpr T &operator *() const noexcept {
134138 assert (get () != nullptr );
135139 return *get ();
136140 }
137141
138- T *release () noexcept {
142+ constexpr T *release () noexcept {
139143 Data.setInt (false );
140144 return Data.getPointer ();
141145 }
@@ -147,8 +151,19 @@ class MaybeUniquePtr : detail::MaybeUniquePtrBase<T, RequireAlignment> {
147151 Data = {};
148152 }
149153
154+ template <typename TT>
155+ constexpr void reset (MaybeUniquePtr<TT> &&Other) noexcept {
156+ *this = std::move (Other);
157+ }
158+
159+ template <typename TT>
160+ constexpr void reset (std::unique_ptr<TT> &&Other) noexcept {
161+ *this = std::move (Other);
162+ }
163+
150164 [[nodiscard]] constexpr bool owns () const noexcept {
151- return Data.getInt () && Data.getPointer ();
165+ assert (Data.getPointer () || !Data.getInt ());
166+ return Data.getInt ();
152167 }
153168
154169 constexpr friend bool operator ==(const MaybeUniquePtr &LHS,
0 commit comments