@@ -27,206 +27,9 @@ namespace cel {
2727
2828class MemoryManager ;
2929
30- template <typename T>
31- class Transient ;
32-
3330template <typename T>
3431class Persistent ;
3532
36- // `Transient` is a handle that is intended to be short lived and may not
37- // actually own the referenced `T`. It is only valid as long as the handle it
38- // was created from or the native C++ value it is wrapping is valid. If you need
39- // to store a handle such that it can escape the current scope use `Persistent`.
40- template <typename T>
41- class Transient final : private base_internal::HandlePolicy<T> {
42- private:
43- using Traits = base_internal::TransientHandleTraits<std::remove_const_t <T>>;
44- using Handle = typename Traits::handle_type;
45-
46- public:
47- // Default constructs the handle, setting it to an empty state. It is
48- // undefined behavior to call any functions that attempt to dereference or
49- // access `T` when in an empty state.
50- Transient () = default ;
51-
52- Transient (const Transient<T>&) = default ;
53-
54- template <typename F,
55- typename = std::enable_if_t <std::is_convertible_v<F*, T*>>>
56- Transient (const Transient<F>& handle) : impl_(handle.impl_) {} // NOLINT
57-
58- Transient (Transient<T>&&) = default ;
59-
60- // Allow implicit conversion from Persistent to Transient, but not the other
61- // way around. This is analogous to implicit conversion from std::string to
62- // std::string_view.
63- Transient (const Persistent<T>& handle); // NOLINT
64-
65- // Allow implicit conversion from Persistent to Transient, but not the other
66- // way around. This is analygous to implicit conversion from std::string to
67- // std::string_view.
68- template <typename F,
69- typename = std::enable_if_t <std::is_convertible_v<F*, T*>>>
70- Transient (const Persistent<F>& handle); // NOLINT
71-
72- Transient<T>& operator =(const Transient<T>&) = default ;
73-
74- template <typename F>
75- std::enable_if_t <std::is_convertible_v<F*, T*>, Transient<T>&> // NOLINT
76- operator =(const Transient<F>& handle) {
77- impl_ = handle.impl_ ;
78- return *this ;
79- }
80-
81- Transient<T>& operator =(Transient<T>&&) = default ;
82-
83- Transient<T>& operator =(const Persistent<T>& handle);
84-
85- // Same as the constructor above, but for the assign operator.
86- template <typename F>
87- std::enable_if_t <std::is_convertible_v<F*, T*>, Transient<T>&> // NOLINT
88- operator =(const Persistent<F>& handle);
89-
90- // Reinterpret the handle of type `T` as type `F`. `T` must be derived from
91- // `F`, `F` must be derived from `T`, or `F` must be the same as `T`.
92- //
93- // Persistent<const Resource> handle;
94- // handle.As<const SubResource>()->SubMethod();
95- template <typename F>
96- std::enable_if_t <
97- std::disjunction_v<std::is_base_of<F, T>, std::is_base_of<T, F>,
98- std::is_same<F, T>>,
99- Transient<F>&>
100- As () ABSL_MUST_USE_RESULT {
101- static_assert (std::is_same_v<Handle, typename Transient<F>::Handle>,
102- " Transient<T> and Transient<F> must have the same "
103- " implementation type" );
104- static_assert (
105- (std::is_const_v<T> == std::is_const_v<F> || std::is_const_v<F>),
106- " Constness cannot be removed, only added using As()" );
107- ABSL_ASSERT (this ->template Is <std::remove_const_t <F>>());
108- // Persistent<T> and Persistent<F> have the same underlying layout
109- // representation, as ensured via the first static_assert, and they have
110- // compatible types such that F is the base of T or T is the base of F, as
111- // ensured via SFINAE on the return value and the second static_assert. Thus
112- // we can saftley reinterpret_cast.
113- return *reinterpret_cast <Transient<F>*>(this );
114- }
115-
116- // Reinterpret the handle of type `T` as type `F`. `T` must be derived from
117- // `F`, `F` must be derived from `T`, or `F` must be the same as `T`.
118- //
119- // Persistent<const Resource> handle;
120- // handle.As<const SubResource>()->SubMethod();
121- template <typename F>
122- std::enable_if_t <
123- std::disjunction_v<std::is_base_of<F, T>, std::is_base_of<T, F>,
124- std::is_same<F, T>>,
125- const Transient<F>&>
126- As () const ABSL_MUST_USE_RESULT {
127- static_assert (std::is_same_v<Handle, typename Transient<F>::Handle>,
128- " Transient<T> and Transient<F> must have the same "
129- " implementation type" );
130- static_assert (
131- (std::is_const_v<T> == std::is_const_v<F> || std::is_const_v<F>),
132- " Constness cannot be removed, only added using As()" );
133- ABSL_ASSERT (this ->template Is <std::remove_const_t <F>>());
134- // Persistent<T> and Persistent<F> have the same underlying layout
135- // representation, as ensured via the first static_assert, and they have
136- // compatible types such that F is the base of T or T is the base of F, as
137- // ensured via SFINAE on the return value and the second static_assert. Thus
138- // we can saftley reinterpret_cast.
139- return *reinterpret_cast <const Transient<F>*>(this );
140- }
141-
142- // Is checks wether `T` is an instance of `F`.
143- template <typename F>
144- bool Is () const {
145- return impl_.template Is <F>();
146- }
147-
148- T& operator *() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
149- ABSL_ASSERT (static_cast <bool >(*this ));
150- return internal::down_cast<T&>(*impl_);
151- }
152-
153- T* operator ->() const {
154- ABSL_ASSERT (static_cast <bool >(*this ));
155- return internal::down_cast<T*>(impl_.operator ->());
156- }
157-
158- // Tests whether the handle is not empty, returning false if it is empty.
159- explicit operator bool () const { return static_cast <bool >(impl_); }
160-
161- friend void swap (Transient<T>& lhs, Transient<T>& rhs) {
162- std::swap (lhs.impl_ , rhs.impl_ );
163- }
164-
165- friend bool operator ==(const Transient<T>& lhs, const Transient<T>& rhs) {
166- return lhs.impl_ == rhs.impl_ ;
167- }
168-
169- template <typename H>
170- friend H AbslHashValue (H state, const Transient<T>& handle) {
171- return H::combine (std::move (state), handle.impl_ );
172- }
173-
174- private:
175- template <typename F>
176- friend class Transient ;
177- template <typename F>
178- friend class Persistent ;
179- template <base_internal::HandleType H, typename F>
180- friend struct base_internal ::HandleFactory;
181- template <typename F>
182- friend bool base_internal::IsManagedHandle (const Transient<F>& handle);
183- template <typename F>
184- friend bool base_internal::IsUnmanagedHandle (const Transient<F>& handle);
185- template <typename F>
186- friend bool base_internal::IsInlinedHandle (const Transient<F>& handle);
187- template <typename F>
188- friend MemoryManager& base_internal::GetMemoryManager (
189- const Transient<F>& handle);
190- template <typename F>
191- friend MemoryManager& base_internal::GetMemoryManager (
192- const Persistent<F>& handle);
193-
194- template <typename ... Args>
195- explicit Transient (base_internal::HandleInPlace, Args&&... args)
196- : impl_(std::forward<Args>(args)...) {}
197-
198- Handle impl_;
199- };
200-
201- template <typename L, typename R>
202- std::enable_if_t <std::is_base_of_v<L, R>, bool > operator ==(
203- const Transient<L>& lhs, const Transient<R>& rhs) {
204- return lhs == rhs.template As <L>();
205- }
206-
207- template <typename L, typename R>
208- std::enable_if_t <std::is_base_of_v<R, L>, bool > operator ==(
209- const Transient<L>& lhs, const Transient<R>& rhs) {
210- return rhs == lhs.template As <R>();
211- }
212-
213- template <typename T>
214- bool operator !=(const Transient<T>& lhs, const Transient<T>& rhs) {
215- return !operator ==(lhs, rhs);
216- }
217-
218- template <typename L, typename R>
219- std::enable_if_t <std::is_base_of_v<L, R>, bool > operator !=(
220- const Transient<L>& lhs, const Transient<R>& rhs) {
221- return !operator ==(lhs, rhs);
222- }
223-
224- template <typename L, typename R>
225- std::enable_if_t <std::is_base_of_v<R, L>, bool > operator !=(
226- const Transient<L>& lhs, const Transient<R>& rhs) {
227- return !operator ==(lhs, rhs);
228- }
229-
23033// `Persistent` is a handle that is intended to be long lived and shares
23134// ownership of the referenced `T`. It is valid so long as
23235// there are 1 or more `Persistent` handles pointing to `T` and the
@@ -256,34 +59,8 @@ class Persistent final : private base_internal::HandlePolicy<T> {
25659 Persistent (Persistent<F>&& handle) // NOLINT
25760 : impl_(std::move(handle.impl_)) {}
25861
259- // Allow Transient handles to be assigned to Persistent handles. This is
260- // similar to std::string_view being assignable to std::string.
261- explicit Persistent (Transient<T> handle) : impl_(handle.impl_) {}
262-
263- // Allow Transient handles to be assigned to Persistent handles. This is
264- // similar to std::string_view being assignable to std::string.
265- template <typename F,
266- typename = std::enable_if_t <std::is_convertible_v<F*, T*>>>
267- explicit Persistent (Transient<F> handle) : impl_(handle.impl_) {}
268-
26962 Persistent<T>& operator =(const Persistent<T>&) = default ;
27063
271- // Allow Transient handles to be assigned to Persistent handles. This is
272- // similar to std::string_view being assignable to std::string.
273- Persistent<T>& operator =(Transient<T> handle) {
274- impl_ = handle.impl_ ;
275- return *this ;
276- }
277-
278- // Allow Transient handles to be assigned to Persistent handles. This is
279- // similar to std::string_view being assignable to std::string.
280- template <typename F>
281- std::enable_if_t <std::is_convertible_v<F*, T*>, Persistent<T>&> // NOLINT
282- operator =(Transient<F> handle) {
283- impl_ = handle.impl_ ;
284- return *this ;
285- }
286-
28764 Persistent<T>& operator =(Persistent<T>&&) = default ;
28865
28966 template <typename F>
@@ -379,22 +156,12 @@ class Persistent final : private base_internal::HandlePolicy<T> {
379156 return lhs.impl_ == rhs.impl_ ;
380157 }
381158
382- friend bool operator ==(const Transient<T>& lhs, const Persistent<T>& rhs) {
383- return lhs.impl_ == rhs.impl_ ;
384- }
385-
386- friend bool operator ==(const Persistent<T>& lhs, const Transient<T>& rhs) {
387- return lhs.impl_ == rhs.impl_ ;
388- }
389-
390159 template <typename H>
391160 friend H AbslHashValue (H state, const Persistent<T>& handle) {
392161 return H::combine (std::move (state), handle.impl_ );
393162 }
394163
395164 private:
396- template <typename F>
397- friend class Transient ;
398165 template <typename F>
399166 friend class Persistent ;
400167 template <base_internal::HandleType H, typename F>
@@ -406,9 +173,6 @@ class Persistent final : private base_internal::HandlePolicy<T> {
406173 template <typename F>
407174 friend bool base_internal::IsInlinedHandle (const Persistent<F>& handle);
408175 template <typename F>
409- friend MemoryManager& base_internal::GetMemoryManager (
410- const Transient<F>& handle);
411- template <typename F>
412176 friend MemoryManager& base_internal::GetMemoryManager (
413177 const Persistent<F>& handle);
414178
@@ -431,33 +195,11 @@ std::enable_if_t<std::is_base_of_v<R, L>, bool> operator==(
431195 return rhs == lhs.template As <R>();
432196}
433197
434- template <typename L, typename R>
435- std::enable_if_t <std::is_base_of_v<L, R>, bool > operator ==(
436- const Transient<L>& lhs, const Persistent<R>& rhs) {
437- return lhs == rhs.template As <L>();
438- }
439-
440- template <typename L, typename R>
441- std::enable_if_t <std::is_base_of_v<R, L>, bool > operator ==(
442- const Persistent<L>& lhs, const Transient<R>& rhs) {
443- return rhs == lhs.template As <R>();
444- }
445-
446198template <typename T>
447199bool operator !=(const Persistent<T>& lhs, const Persistent<T>& rhs) {
448200 return !operator ==(lhs, rhs);
449201}
450202
451- template <typename T>
452- bool operator !=(const Transient<T>& lhs, const Persistent<T>& rhs) {
453- return !operator ==(lhs, rhs);
454- }
455-
456- template <typename T>
457- bool operator !=(const Persistent<T>& lhs, const Transient<T>& rhs) {
458- return !operator ==(lhs, rhs);
459- }
460-
461203template <typename L, typename R>
462204std::enable_if_t <std::is_base_of_v<L, R>, bool > operator !=(
463205 const Persistent<L>& lhs, const Persistent<R>& rhs) {
@@ -470,39 +212,6 @@ std::enable_if_t<std::is_base_of_v<R, L>, bool> operator!=(
470212 return !operator ==(lhs, rhs);
471213}
472214
473- template <typename L, typename R>
474- std::enable_if_t <std::is_base_of_v<L, R>, bool > operator !=(
475- const Transient<L>& lhs, const Persistent<R>& rhs) {
476- return !operator ==(lhs, rhs);
477- }
478-
479- template <typename L, typename R>
480- std::enable_if_t <std::is_base_of_v<R, L>, bool > operator !=(
481- const Persistent<L>& lhs, const Transient<R>& rhs) {
482- return !operator ==(lhs, rhs);
483- }
484-
485- template <typename T>
486- Transient<T>::Transient(const Persistent<T>& handle) : impl_(handle.impl_) {}
487-
488- template <typename T>
489- template <typename F, typename >
490- Transient<T>::Transient(const Persistent<F>& handle) : impl_(handle.impl_) {}
491-
492- template <typename T>
493- Transient<T>& Transient<T>::operator =(const Persistent<T>& handle) {
494- impl_ = handle.impl_ ;
495- return *this ;
496- }
497-
498- template <typename T> // NOLINT
499- template <typename F>
500- std::enable_if_t <std::is_convertible_v<F*, T*>, Transient<T>&>
501- Transient<T>::operator =(const Persistent<F>& handle) {
502- impl_ = handle.impl_ ;
503- return *this ;
504- }
505-
506215} // namespace cel
507216
508217#include " base/internal/handle.post.h" // IWYU pragma: export
0 commit comments