OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #ifndef WEBRTC_RTC_BASE_OPTIONAL_H_ | 11 #ifndef WEBRTC_API_OPTIONAL_H_ |
12 #define WEBRTC_RTC_BASE_OPTIONAL_H_ | 12 #define WEBRTC_API_OPTIONAL_H_ |
13 | 13 |
14 #include <algorithm> | 14 #include <algorithm> |
15 #include <memory> | 15 #include <memory> |
16 #include <utility> | 16 #include <utility> |
17 | 17 |
18 #ifdef UNIT_TEST | 18 #ifdef UNIT_TEST |
19 #include <iomanip> | 19 #include <iomanip> |
20 #include <ostream> | 20 #include <ostream> |
21 #endif // UNIT_TEST | 21 #endif // UNIT_TEST |
22 | 22 |
(...skipping 14 matching lines...) Expand all Loading... |
37 | 37 |
38 template <typename T> | 38 template <typename T> |
39 inline T* FunctionThatDoesNothing(T* x) { | 39 inline T* FunctionThatDoesNothing(T* x) { |
40 return reinterpret_cast<T*>( | 40 return reinterpret_cast<T*>( |
41 FunctionThatDoesNothingImpl(reinterpret_cast<void*>(x))); | 41 FunctionThatDoesNothingImpl(reinterpret_cast<void*>(x))); |
42 } | 42 } |
43 | 43 |
44 #else | 44 #else |
45 | 45 |
46 template <typename T> | 46 template <typename T> |
47 inline T* FunctionThatDoesNothing(T* x) { return x; } | 47 inline T* FunctionThatDoesNothing(T* x) { |
| 48 return x; |
| 49 } |
48 | 50 |
49 #endif | 51 #endif |
50 | 52 |
51 } // namespace optional_internal | 53 } // namespace optional_internal |
52 | 54 |
53 // Simple std::optional-wannabe. It either contains a T or not. | 55 // Simple std::optional-wannabe. It either contains a T or not. |
54 // | 56 // |
55 // A moved-from Optional<T> may only be destroyed, and assigned to if T allows | 57 // A moved-from Optional<T> may only be destroyed, and assigned to if T allows |
56 // being assigned to after having been moved from. Specifically, you may not | 58 // being assigned to after having been moved from. Specifically, you may not |
57 // assume that it just doesn't contain a value anymore. | 59 // assume that it just doesn't contain a value anymore. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 // and cleanest. (If you're *sure* that the the caller will always already | 91 // and cleanest. (If you're *sure* that the the caller will always already |
90 // have an Optional<T>, const Optional<T>& is slightly faster than const T*, | 92 // have an Optional<T>, const Optional<T>& is slightly faster than const T*, |
91 // but this is a micro-optimization. In general, stick to const T*.) | 93 // but this is a micro-optimization. In general, stick to const T*.) |
92 // | 94 // |
93 // TODO(kwiberg): Get rid of this class when the standard library has | 95 // TODO(kwiberg): Get rid of this class when the standard library has |
94 // std::optional (and we're allowed to use it). | 96 // std::optional (and we're allowed to use it). |
95 template <typename T> | 97 template <typename T> |
96 class Optional final { | 98 class Optional final { |
97 public: | 99 public: |
98 // Construct an empty Optional. | 100 // Construct an empty Optional. |
99 Optional() : has_value_(false), empty_('\0') { | 101 Optional() : has_value_(false), empty_('\0') { PoisonValue(); } |
100 PoisonValue(); | |
101 } | |
102 | 102 |
103 // Construct an Optional that contains a value. | 103 // Construct an Optional that contains a value. |
104 explicit Optional(const T& value) : has_value_(true) { | 104 explicit Optional(const T& value) : has_value_(true) { |
105 new (&value_) T(value); | 105 new (&value_) T(value); |
106 } | 106 } |
107 explicit Optional(T&& value) : has_value_(true) { | 107 explicit Optional(T&& value) : has_value_(true) { |
108 new (&value_) T(std::move(value)); | 108 new (&value_) T(std::move(value)); |
109 } | 109 } |
110 | 110 |
111 // Copy constructor: copies the value from m if it has one. | 111 // Copy constructor: copies the value from m if it has one. |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 } | 286 } |
287 | 287 |
288 private: | 288 private: |
289 // Tell sanitizers that value_ shouldn't be touched. | 289 // Tell sanitizers that value_ shouldn't be touched. |
290 void PoisonValue() { | 290 void PoisonValue() { |
291 rtc::AsanPoison(rtc::MakeArrayView(&value_, 1)); | 291 rtc::AsanPoison(rtc::MakeArrayView(&value_, 1)); |
292 rtc::MsanMarkUninitialized(rtc::MakeArrayView(&value_, 1)); | 292 rtc::MsanMarkUninitialized(rtc::MakeArrayView(&value_, 1)); |
293 } | 293 } |
294 | 294 |
295 // Tell sanitizers that value_ is OK to touch again. | 295 // Tell sanitizers that value_ is OK to touch again. |
296 void UnpoisonValue() { | 296 void UnpoisonValue() { rtc::AsanUnpoison(rtc::MakeArrayView(&value_, 1)); } |
297 rtc::AsanUnpoison(rtc::MakeArrayView(&value_, 1)); | |
298 } | |
299 | 297 |
300 bool has_value_; // True iff value_ contains a live value. | 298 bool has_value_; // True iff value_ contains a live value. |
301 union { | 299 union { |
302 // empty_ exists only to make it possible to initialize the union, even when | 300 // empty_ exists only to make it possible to initialize the union, even when |
303 // it doesn't contain any data. If the union goes uninitialized, it may | 301 // it doesn't contain any data. If the union goes uninitialized, it may |
304 // trigger compiler warnings. | 302 // trigger compiler warnings. |
305 char empty_; | 303 char empty_; |
306 // By placing value_ in a union, we get to manage its construction and | 304 // By placing value_ in a union, we get to manage its construction and |
307 // destruction manually: the Optional constructors won't automatically | 305 // destruction manually: the Optional constructors won't automatically |
308 // construct it, and the Optional destructor won't automatically destroy | 306 // construct it, and the Optional destructor won't automatically destroy |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 optional_internal::OptionalPrintToHelper(*opt, os); | 397 optional_internal::OptionalPrintToHelper(*opt, os); |
400 } else { | 398 } else { |
401 *os << "<empty optional>"; | 399 *os << "<empty optional>"; |
402 } | 400 } |
403 } | 401 } |
404 | 402 |
405 #endif // UNIT_TEST | 403 #endif // UNIT_TEST |
406 | 404 |
407 } // namespace rtc | 405 } // namespace rtc |
408 | 406 |
409 #endif // WEBRTC_RTC_BASE_OPTIONAL_H_ | 407 #endif // WEBRTC_API_OPTIONAL_H_ |
OLD | NEW |