Skip to content

Commit 69f4f56

Browse files
jckingkyessenov
authored andcommitted
Internal change
PiperOrigin-RevId: 453261653
1 parent ac2f3b2 commit 69f4f56

17 files changed

Lines changed: 100 additions & 696 deletions

base/handle.h

Lines changed: 0 additions & 291 deletions
Original file line numberDiff line numberDiff line change
@@ -27,206 +27,9 @@ namespace cel {
2727

2828
class MemoryManager;
2929

30-
template <typename T>
31-
class Transient;
32-
3330
template <typename T>
3431
class 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-
446198
template <typename T>
447199
bool 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-
461203
template <typename L, typename R>
462204
std::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

base/internal/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,5 +88,6 @@ cc_library(
8888
"@com_google_absl//absl/numeric:bits",
8989
"@com_google_absl//absl/strings",
9090
"@com_google_absl//absl/strings:cord",
91+
"@com_google_absl//absl/types:variant",
9192
],
9293
)

0 commit comments

Comments
 (0)