/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Basic/CustomizableOptional.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- CustomizableOptional.h - Optional with custom storage ----*- C++ -*-===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #ifndef CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H |
10 | | #define CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H |
11 | | |
12 | | #include "llvm/ADT/Hashing.h" |
13 | | #include "llvm/Support/Compiler.h" |
14 | | #include "llvm/Support/type_traits.h" |
15 | | #include <cassert> |
16 | | #include <new> |
17 | | #include <optional> |
18 | | #include <utility> |
19 | | |
20 | | namespace clang { |
21 | | |
22 | | namespace optional_detail { |
23 | | template <typename> class OptionalStorage; |
24 | | } // namespace optional_detail |
25 | | |
26 | | // Optional type which internal storage can be specialized by providing |
27 | | // OptionalStorage. The interface follows std::optional. |
28 | | template <typename T> class CustomizableOptional { |
29 | | optional_detail::OptionalStorage<T> Storage; |
30 | | |
31 | | public: |
32 | | using value_type = T; |
33 | | |
34 | 20.3M | constexpr CustomizableOptional() = default; clang::CustomizableOptional<clang::FileEntryRef>::CustomizableOptional() Line | Count | Source | 34 | 17.8M | constexpr CustomizableOptional() = default; |
clang::CustomizableOptional<clang::DirectoryEntryRef>::CustomizableOptional() Line | Count | Source | 34 | 2.48M | constexpr CustomizableOptional() = default; |
|
35 | 6.65M | constexpr CustomizableOptional(std::nullopt_t) {} clang::CustomizableOptional<clang::FileEntryRef>::CustomizableOptional(std::__1::nullopt_t) Line | Count | Source | 35 | 6.65M | constexpr CustomizableOptional(std::nullopt_t) {} |
Unexecuted instantiation: clang::CustomizableOptional<clang::DirectoryEntryRef>::CustomizableOptional(std::__1::nullopt_t) |
36 | | |
37 | 22.1M | constexpr CustomizableOptional(const T &y) : Storage(std::in_place, y) {} clang::CustomizableOptional<clang::FileEntryRef>::CustomizableOptional(clang::FileEntryRef const&) Line | Count | Source | 37 | 9.35M | constexpr CustomizableOptional(const T &y) : Storage(std::in_place, y) {} |
clang::CustomizableOptional<clang::DirectoryEntryRef>::CustomizableOptional(clang::DirectoryEntryRef const&) Line | Count | Source | 37 | 12.8M | constexpr CustomizableOptional(const T &y) : Storage(std::in_place, y) {} |
|
38 | | constexpr CustomizableOptional(const CustomizableOptional &O) = default; |
39 | | |
40 | | constexpr CustomizableOptional(T &&y) |
41 | 14.0M | : Storage(std::in_place, std::move(y)) {} clang::CustomizableOptional<clang::FileEntryRef>::CustomizableOptional(clang::FileEntryRef&&) Line | Count | Source | 41 | 8.65M | : Storage(std::in_place, std::move(y)) {} |
clang::CustomizableOptional<clang::DirectoryEntryRef>::CustomizableOptional(clang::DirectoryEntryRef&&) Line | Count | Source | 41 | 5.37M | : Storage(std::in_place, std::move(y)) {} |
|
42 | | constexpr CustomizableOptional(CustomizableOptional &&O) = default; |
43 | | |
44 | | template <typename... ArgTypes> |
45 | | constexpr CustomizableOptional(std::in_place_t, ArgTypes &&...Args) |
46 | | : Storage(std::in_place, std::forward<ArgTypes>(Args)...) {} |
47 | | |
48 | | // Allow conversion from std::optional<T>. |
49 | | constexpr CustomizableOptional(const std::optional<T> &y) |
50 | | : CustomizableOptional(y ? *y : CustomizableOptional()) {} |
51 | | constexpr CustomizableOptional(std::optional<T> &&y) |
52 | 10.4M | : CustomizableOptional(y ? std::move(*y)10.1M : CustomizableOptional()331k ) {} clang::CustomizableOptional<clang::FileEntryRef>::CustomizableOptional(std::__1::optional<clang::FileEntryRef>&&) Line | Count | Source | 52 | 4.98M | : CustomizableOptional(y ? std::move(*y)4.78M : CustomizableOptional()200k ) {} |
clang::CustomizableOptional<clang::DirectoryEntryRef>::CustomizableOptional(std::__1::optional<clang::DirectoryEntryRef>&&) Line | Count | Source | 52 | 5.48M | : CustomizableOptional(y ? std::move(*y)5.35M : CustomizableOptional()131k ) {} |
|
53 | | |
54 | 9.38k | CustomizableOptional &operator=(T &&y) { |
55 | 9.38k | Storage = std::move(y); |
56 | 9.38k | return *this; |
57 | 9.38k | } clang::CustomizableOptional<clang::FileEntryRef>::operator=(clang::FileEntryRef&&) Line | Count | Source | 54 | 5.58k | CustomizableOptional &operator=(T &&y) { | 55 | 5.58k | Storage = std::move(y); | 56 | 5.58k | return *this; | 57 | 5.58k | } |
clang::CustomizableOptional<clang::DirectoryEntryRef>::operator=(clang::DirectoryEntryRef&&) Line | Count | Source | 54 | 3.79k | CustomizableOptional &operator=(T &&y) { | 55 | 3.79k | Storage = std::move(y); | 56 | 3.79k | return *this; | 57 | 3.79k | } |
|
58 | | CustomizableOptional &operator=(CustomizableOptional &&O) = default; |
59 | | |
60 | | /// Create a new object by constructing it in place with the given arguments. |
61 | | template <typename... ArgTypes> void emplace(ArgTypes &&...Args) { |
62 | | Storage.emplace(std::forward<ArgTypes>(Args)...); |
63 | | } |
64 | | |
65 | 11.5M | CustomizableOptional &operator=(const T &y) { |
66 | 11.5M | Storage = y; |
67 | 11.5M | return *this; |
68 | 11.5M | } clang::CustomizableOptional<clang::DirectoryEntryRef>::operator=(clang::DirectoryEntryRef const&) Line | Count | Source | 65 | 2.03M | CustomizableOptional &operator=(const T &y) { | 66 | 2.03M | Storage = y; | 67 | 2.03M | return *this; | 68 | 2.03M | } |
clang::CustomizableOptional<clang::FileEntryRef>::operator=(clang::FileEntryRef const&) Line | Count | Source | 65 | 9.49M | CustomizableOptional &operator=(const T &y) { | 66 | 9.49M | Storage = y; | 67 | 9.49M | return *this; | 68 | 9.49M | } |
|
69 | | CustomizableOptional &operator=(const CustomizableOptional &O) = default; |
70 | | |
71 | | void reset() { Storage.reset(); } |
72 | | |
73 | | LLVM_DEPRECATED("Use &*X instead.", "&*X") |
74 | | constexpr const T *getPointer() const { return &Storage.value(); } |
75 | | LLVM_DEPRECATED("Use &*X instead.", "&*X") |
76 | | T *getPointer() { return &Storage.value(); } |
77 | | LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X") |
78 | | constexpr const T &value() const & { return Storage.value(); } |
79 | | LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X") |
80 | | T &value() & { return Storage.value(); } |
81 | | |
82 | 195M | constexpr explicit operator bool() const { return has_value(); } clang::CustomizableOptional<clang::FileEntryRef>::operator bool() const Line | Count | Source | 82 | 182M | constexpr explicit operator bool() const { return has_value(); } |
clang::CustomizableOptional<clang::DirectoryEntryRef>::operator bool() const Line | Count | Source | 82 | 13.3M | constexpr explicit operator bool() const { return has_value(); } |
|
83 | 255M | constexpr bool has_value() const { return Storage.has_value(); } clang::CustomizableOptional<clang::DirectoryEntryRef>::has_value() const Line | Count | Source | 83 | 14.0M | constexpr bool has_value() const { return Storage.has_value(); } |
clang::CustomizableOptional<clang::FileEntryRef>::has_value() const Line | Count | Source | 83 | 241M | constexpr bool has_value() const { return Storage.has_value(); } |
|
84 | 163M | constexpr const T *operator->() const { return &Storage.value(); } clang::CustomizableOptional<clang::DirectoryEntryRef>::operator->() const Line | Count | Source | 84 | 421k | constexpr const T *operator->() const { return &Storage.value(); } |
clang::CustomizableOptional<clang::FileEntryRef>::operator->() const Line | Count | Source | 84 | 162M | constexpr const T *operator->() const { return &Storage.value(); } |
|
85 | 35.2M | T *operator->() { return &Storage.value(); } clang::CustomizableOptional<clang::FileEntryRef>::operator->() Line | Count | Source | 85 | 19.8M | T *operator->() { return &Storage.value(); } |
clang::CustomizableOptional<clang::DirectoryEntryRef>::operator->() Line | Count | Source | 85 | 15.3M | T *operator->() { return &Storage.value(); } |
|
86 | 5.44M | constexpr const T &operator*() const & { return Storage.value(); } clang::CustomizableOptional<clang::FileEntryRef>::operator*() const & Line | Count | Source | 86 | 1.12M | constexpr const T &operator*() const & { return Storage.value(); } |
clang::CustomizableOptional<clang::DirectoryEntryRef>::operator*() const & Line | Count | Source | 86 | 4.32M | constexpr const T &operator*() const & { return Storage.value(); } |
|
87 | 55.5M | T &operator*() & { return Storage.value(); } clang::CustomizableOptional<clang::FileEntryRef>::operator*() & Line | Count | Source | 87 | 54.3M | T &operator*() & { return Storage.value(); } |
clang::CustomizableOptional<clang::DirectoryEntryRef>::operator*() & Line | Count | Source | 87 | 1.18M | T &operator*() & { return Storage.value(); } |
|
88 | | |
89 | | template <typename U> constexpr T value_or(U &&alt) const & { |
90 | | return has_value() ? operator*() : std::forward<U>(alt); |
91 | | } |
92 | | |
93 | | LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X") |
94 | | T &&value() && { return std::move(Storage.value()); } |
95 | 415k | T &&operator*() && { return std::move(Storage.value()); } clang::CustomizableOptional<clang::DirectoryEntryRef>::operator*() && Line | Count | Source | 95 | 8.02k | T &&operator*() && { return std::move(Storage.value()); } |
clang::CustomizableOptional<clang::FileEntryRef>::operator*() && Line | Count | Source | 95 | 407k | T &&operator*() && { return std::move(Storage.value()); } |
|
96 | | |
97 | | template <typename U> T value_or(U &&alt) && { |
98 | | return has_value() ? std::move(operator*()) : std::forward<U>(alt); |
99 | | } |
100 | | |
101 | | // Allow conversion to std::optional<T>. |
102 | | explicit operator std::optional<T> &() const & { |
103 | | return *this ? **this : std::optional<T>(); |
104 | | } |
105 | | explicit operator std::optional<T> &&() const && { |
106 | | return *this ? std::move(**this) : std::optional<T>(); |
107 | | } |
108 | | }; |
109 | | |
110 | | template <typename T> |
111 | | CustomizableOptional(const T &) -> CustomizableOptional<T>; |
112 | | |
113 | | template <class T> |
114 | 29 | llvm::hash_code hash_value(const CustomizableOptional<T> &O) { |
115 | 29 | return O ? llvm::hash_combine(true, *O) : llvm::hash_value(false)0 ; |
116 | 29 | } |
117 | | |
118 | | template <typename T, typename U> |
119 | | constexpr bool operator==(const CustomizableOptional<T> &X, |
120 | 2.19M | const CustomizableOptional<U> &Y) { |
121 | 2.19M | if (X && Y2.19M ) |
122 | 2.19M | return *X == *Y; |
123 | 540 | return X.has_value() == Y.has_value(); |
124 | 2.19M | } bool clang::operator==<clang::FileEntryRef, clang::FileEntryRef>(clang::CustomizableOptional<clang::FileEntryRef> const&, clang::CustomizableOptional<clang::FileEntryRef> const&) Line | Count | Source | 120 | 37.0k | const CustomizableOptional<U> &Y) { | 121 | 37.0k | if (X && Y36.5k ) | 122 | 36.4k | return *X == *Y; | 123 | 539 | return X.has_value() == Y.has_value(); | 124 | 37.0k | } |
bool clang::operator==<clang::DirectoryEntryRef, clang::DirectoryEntryRef>(clang::CustomizableOptional<clang::DirectoryEntryRef> const&, clang::CustomizableOptional<clang::DirectoryEntryRef> const&) Line | Count | Source | 120 | 2.15M | const CustomizableOptional<U> &Y) { | 121 | 2.15M | if (X && Y2.15M ) | 122 | 2.15M | return *X == *Y; | 123 | 1 | return X.has_value() == Y.has_value(); | 124 | 2.15M | } |
|
125 | | |
126 | | template <typename T, typename U> |
127 | | constexpr bool operator!=(const CustomizableOptional<T> &X, |
128 | 338k | const CustomizableOptional<U> &Y) { |
129 | 338k | return !(X == Y); |
130 | 338k | } bool clang::operator!=<clang::FileEntryRef, clang::FileEntryRef>(clang::CustomizableOptional<clang::FileEntryRef> const&, clang::CustomizableOptional<clang::FileEntryRef> const&) Line | Count | Source | 128 | 5 | const CustomizableOptional<U> &Y) { | 129 | 5 | return !(X == Y); | 130 | 5 | } |
bool clang::operator!=<clang::DirectoryEntryRef, clang::DirectoryEntryRef>(clang::CustomizableOptional<clang::DirectoryEntryRef> const&, clang::CustomizableOptional<clang::DirectoryEntryRef> const&) Line | Count | Source | 128 | 338k | const CustomizableOptional<U> &Y) { | 129 | 338k | return !(X == Y); | 130 | 338k | } |
|
131 | | |
132 | | template <typename T, typename U> |
133 | | constexpr bool operator<(const CustomizableOptional<T> &X, |
134 | | const CustomizableOptional<U> &Y) { |
135 | | if (X && Y) |
136 | | return *X < *Y; |
137 | | return X.has_value() < Y.has_value(); |
138 | | } |
139 | | |
140 | | template <typename T, typename U> |
141 | | constexpr bool operator<=(const CustomizableOptional<T> &X, |
142 | | const CustomizableOptional<U> &Y) { |
143 | | return !(Y < X); |
144 | | } |
145 | | |
146 | | template <typename T, typename U> |
147 | | constexpr bool operator>(const CustomizableOptional<T> &X, |
148 | | const CustomizableOptional<U> &Y) { |
149 | | return Y < X; |
150 | | } |
151 | | |
152 | | template <typename T, typename U> |
153 | | constexpr bool operator>=(const CustomizableOptional<T> &X, |
154 | | const CustomizableOptional<U> &Y) { |
155 | | return !(X < Y); |
156 | | } |
157 | | |
158 | | template <typename T> |
159 | | constexpr bool operator==(const CustomizableOptional<T> &X, std::nullopt_t) { |
160 | | return !X; |
161 | | } |
162 | | |
163 | | template <typename T> |
164 | | constexpr bool operator==(std::nullopt_t, const CustomizableOptional<T> &X) { |
165 | | return X == std::nullopt; |
166 | | } |
167 | | |
168 | | template <typename T> |
169 | | constexpr bool operator!=(const CustomizableOptional<T> &X, std::nullopt_t) { |
170 | | return !(X == std::nullopt); |
171 | | } |
172 | | |
173 | | template <typename T> |
174 | | constexpr bool operator!=(std::nullopt_t, const CustomizableOptional<T> &X) { |
175 | | return X != std::nullopt; |
176 | | } |
177 | | |
178 | | template <typename T> |
179 | | constexpr bool operator<(const CustomizableOptional<T> &, std::nullopt_t) { |
180 | | return false; |
181 | | } |
182 | | |
183 | | template <typename T> |
184 | | constexpr bool operator<(std::nullopt_t, const CustomizableOptional<T> &X) { |
185 | | return X.has_value(); |
186 | | } |
187 | | |
188 | | template <typename T> |
189 | | constexpr bool operator<=(const CustomizableOptional<T> &X, std::nullopt_t) { |
190 | | return !(std::nullopt < X); |
191 | | } |
192 | | |
193 | | template <typename T> |
194 | | constexpr bool operator<=(std::nullopt_t, const CustomizableOptional<T> &X) { |
195 | | return !(X < std::nullopt); |
196 | | } |
197 | | |
198 | | template <typename T> |
199 | | constexpr bool operator>(const CustomizableOptional<T> &X, std::nullopt_t) { |
200 | | return std::nullopt < X; |
201 | | } |
202 | | |
203 | | template <typename T> |
204 | | constexpr bool operator>(std::nullopt_t, const CustomizableOptional<T> &X) { |
205 | | return X < std::nullopt; |
206 | | } |
207 | | |
208 | | template <typename T> |
209 | | constexpr bool operator>=(const CustomizableOptional<T> &X, std::nullopt_t) { |
210 | | return std::nullopt <= X; |
211 | | } |
212 | | |
213 | | template <typename T> |
214 | | constexpr bool operator>=(std::nullopt_t, const CustomizableOptional<T> &X) { |
215 | | return X <= std::nullopt; |
216 | | } |
217 | | |
218 | | template <typename T> |
219 | 24 | constexpr bool operator==(const CustomizableOptional<T> &X, const T &Y) { |
220 | 24 | return X && *X == Y; |
221 | 24 | } |
222 | | |
223 | | template <typename T> |
224 | 18.1k | constexpr bool operator==(const T &X, const CustomizableOptional<T> &Y) { |
225 | 18.1k | return Y && X == *Y18.0k ; |
226 | 18.1k | } bool clang::operator==<clang::FileEntryRef>(clang::FileEntryRef const&, clang::CustomizableOptional<clang::FileEntryRef> const&) Line | Count | Source | 224 | 3.60k | constexpr bool operator==(const T &X, const CustomizableOptional<T> &Y) { | 225 | 3.60k | return Y && X == *Y; | 226 | 3.60k | } |
bool clang::operator==<clang::DirectoryEntryRef>(clang::DirectoryEntryRef const&, clang::CustomizableOptional<clang::DirectoryEntryRef> const&) Line | Count | Source | 224 | 14.5k | constexpr bool operator==(const T &X, const CustomizableOptional<T> &Y) { | 225 | 14.5k | return Y && X == *Y14.4k ; | 226 | 14.5k | } |
|
227 | | |
228 | | template <typename T> |
229 | | constexpr bool operator!=(const CustomizableOptional<T> &X, const T &Y) { |
230 | | return !(X == Y); |
231 | | } |
232 | | |
233 | | template <typename T> |
234 | 3.60k | constexpr bool operator!=(const T &X, const CustomizableOptional<T> &Y) { |
235 | 3.60k | return !(X == Y); |
236 | 3.60k | } |
237 | | |
238 | | template <typename T> |
239 | | constexpr bool operator<(const CustomizableOptional<T> &X, const T &Y) { |
240 | | return !X || *X < Y; |
241 | | } |
242 | | |
243 | | template <typename T> |
244 | | constexpr bool operator<(const T &X, const CustomizableOptional<T> &Y) { |
245 | | return Y && X < *Y; |
246 | | } |
247 | | |
248 | | template <typename T> |
249 | | constexpr bool operator<=(const CustomizableOptional<T> &X, const T &Y) { |
250 | | return !(Y < X); |
251 | | } |
252 | | |
253 | | template <typename T> |
254 | | constexpr bool operator<=(const T &X, const CustomizableOptional<T> &Y) { |
255 | | return !(Y < X); |
256 | | } |
257 | | |
258 | | template <typename T> |
259 | | constexpr bool operator>(const CustomizableOptional<T> &X, const T &Y) { |
260 | | return Y < X; |
261 | | } |
262 | | |
263 | | template <typename T> |
264 | | constexpr bool operator>(const T &X, const CustomizableOptional<T> &Y) { |
265 | | return Y < X; |
266 | | } |
267 | | |
268 | | template <typename T> |
269 | | constexpr bool operator>=(const CustomizableOptional<T> &X, const T &Y) { |
270 | | return !(X < Y); |
271 | | } |
272 | | |
273 | | template <typename T> |
274 | | constexpr bool operator>=(const T &X, const CustomizableOptional<T> &Y) { |
275 | | return !(X < Y); |
276 | | } |
277 | | |
278 | | } // namespace clang |
279 | | |
280 | | #endif // CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H |