|
15 | 15 | #ifndef THIRD_PARTY_CEL_CPP_OPTIONAL_REF_H_ |
16 | 16 | #define THIRD_PARTY_CEL_CPP_OPTIONAL_REF_H_ |
17 | 17 |
|
18 | | -#include <memory> |
| 18 | +#include <optional> |
19 | 19 | #include <type_traits> |
20 | 20 |
|
21 | | -#include "absl/base/attributes.h" |
22 | 21 | #include "absl/base/macros.h" |
23 | | -#include "absl/base/nullability.h" |
24 | | -#include "absl/base/optimization.h" |
25 | | -#include "absl/types/optional.h" |
26 | | -#include "absl/utility/utility.h" |
| 22 | +#include "absl/types/optional_ref.h" |
27 | 23 |
|
28 | 24 | namespace cel { |
29 | 25 |
|
30 | 26 | // `optional_ref<T>` looks and feels like `absl::optional<T>`, but instead of |
31 | 27 | // owning the underlying value, it retains a reference to the value it accepts |
32 | 28 | // in its constructor. |
33 | 29 | template <typename T> |
34 | | -class optional_ref final { |
35 | | - public: |
36 | | - static_assert(!std::is_reference_v<T>, "T must not be a reference."); |
37 | | - static_assert(!std::is_same_v<absl::nullopt_t, std::remove_cv_t<T>>, |
38 | | - "optional_ref<absl::nullopt_t> is not allowed."); |
39 | | - static_assert(!std::is_same_v<absl::in_place_t, std::remove_cv_t<T>>, |
40 | | - "optional_ref<absl::in_place_t> is not allowed."); |
41 | | - |
42 | | - using value_type = T; |
43 | | - |
44 | | - optional_ref() = default; |
45 | | - |
46 | | - // NOLINTNEXTLINE(google-explicit-constructor) |
47 | | - constexpr optional_ref(absl::nullopt_t) : optional_ref() {} |
48 | | - |
49 | | - // NOLINTNEXTLINE(google-explicit-constructor) |
50 | | - constexpr optional_ref(T& value ABSL_ATTRIBUTE_LIFETIME_BOUND) |
51 | | - : value_(std::addressof(value)) {} |
52 | | - |
53 | | - template < |
54 | | - typename U, |
55 | | - typename = std::enable_if_t<std::conjunction_v< |
56 | | - std::is_const<T>, std::is_same<std::decay_t<U>, std::decay_t<T>>>>> |
57 | | - // NOLINTNEXTLINE(google-explicit-constructor) |
58 | | - constexpr optional_ref( |
59 | | - const absl::optional<U>& value ABSL_ATTRIBUTE_LIFETIME_BOUND) |
60 | | - : value_(value.has_value() ? std::addressof(*value) : nullptr) {} |
61 | | - |
62 | | - template <typename U, typename = std::enable_if_t< |
63 | | - std::is_same_v<std::decay_t<U>, std::decay_t<T>>>> |
64 | | - // NOLINTNEXTLINE(google-explicit-constructor) |
65 | | - constexpr optional_ref(absl::optional<U>& value ABSL_ATTRIBUTE_LIFETIME_BOUND) |
66 | | - : value_(value.has_value() ? std::addressof(*value) : nullptr) {} |
67 | | - |
68 | | - template < |
69 | | - typename U, |
70 | | - typename = std::enable_if_t<std::conjunction_v< |
71 | | - std::negation<std::is_same<U, T>>, |
72 | | - std::is_convertible<std::add_pointer_t<U>, std::add_pointer_t<T>>>>> |
73 | | - // NOLINTNEXTLINE(google-explicit-constructor) |
74 | | - constexpr optional_ref(const optional_ref<U>& other) : value_(other.value_) {} |
75 | | - |
76 | | - optional_ref(const optional_ref<T>&) = default; |
77 | | - |
78 | | - optional_ref<T>& operator=(const optional_ref<T>&) = delete; |
79 | | - |
80 | | - constexpr bool has_value() const { return value_ != nullptr; } |
81 | | - |
82 | | - constexpr explicit operator bool() const { return has_value(); } |
83 | | - |
84 | | - constexpr T& value() const { |
85 | | - return ABSL_PREDICT_TRUE(has_value()) |
86 | | - ? *value_ |
87 | | - // Replicate the same error logic as in `absl::optional`'s |
88 | | - // `value()`. It either throws an exception or aborts the |
89 | | - // program. We intentionally ignore the return value of |
90 | | - // the constructed optional's value as we only need to run |
91 | | - // the code for error checking. |
92 | | - : ((void)absl::optional<T>().value(), *value_); |
93 | | - } |
94 | | - |
95 | | - constexpr T& operator*() const { |
96 | | - ABSL_ASSERT(has_value()); |
97 | | - return *value_; |
98 | | - } |
99 | | - |
100 | | - constexpr T* absl_nonnull operator->() const { |
101 | | - ABSL_ASSERT(has_value()); |
102 | | - return value_; |
103 | | - } |
104 | | - |
105 | | - private: |
106 | | - template <typename U> |
107 | | - friend class optional_ref; |
108 | | - |
109 | | - T* const value_ = nullptr; |
110 | | -}; |
111 | | - |
112 | | -template <typename T> |
113 | | -optional_ref(const T&) -> optional_ref<const T>; |
114 | | - |
115 | | -template <typename T> |
116 | | -optional_ref(T&) -> optional_ref<T>; |
117 | | - |
118 | | -template <typename T> |
119 | | -optional_ref(const absl::optional<T>&) -> optional_ref<const T>; |
120 | | - |
121 | | -template <typename T> |
122 | | -optional_ref(absl::optional<T>&) -> optional_ref<T>; |
123 | | - |
124 | | -template <typename T> |
125 | | -constexpr bool operator==(const optional_ref<T>& lhs, absl::nullopt_t) { |
126 | | - return !lhs.has_value(); |
127 | | -} |
128 | | - |
129 | | -template <typename T> |
130 | | -constexpr bool operator==(absl::nullopt_t, const optional_ref<T>& rhs) { |
131 | | - return !rhs.has_value(); |
132 | | -} |
133 | | - |
134 | | -template <typename T> |
135 | | -constexpr bool operator!=(const optional_ref<T>& lhs, absl::nullopt_t) { |
136 | | - return !operator==(lhs, absl::nullopt); |
137 | | -} |
138 | | - |
139 | | -template <typename T> |
140 | | -constexpr bool operator!=(absl::nullopt_t, const optional_ref<T>& rhs) { |
141 | | - return !operator==(absl::nullopt, rhs); |
142 | | -} |
| 30 | +using optional_ref ABSL_DEPRECATE_AND_INLINE() = absl::optional_ref<T>; |
143 | 31 |
|
144 | 32 | namespace common_internal { |
145 | 33 |
|
146 | 34 | template <typename T> |
147 | | -absl::optional<std::decay_t<T>> AsOptional(optional_ref<T> ref) { |
| 35 | +[[nodiscard]] |
| 36 | +std::optional<std::decay_t<T>> AsOptional(absl::optional_ref<T> ref) { |
148 | 37 | if (ref) { |
149 | 38 | return *ref; |
150 | 39 | } |
151 | | - return absl::nullopt; |
| 40 | + return std::nullopt; |
152 | 41 | } |
153 | 42 |
|
154 | 43 | template <typename T> |
155 | | -absl::optional<T> AsOptional(absl::optional<T> opt) { |
| 44 | +[[nodiscard]] |
| 45 | +std::optional<T> AsOptional(std::optional<T> opt) { |
156 | 46 | return opt; |
157 | 47 | } |
158 | 48 |
|
|
0 commit comments