| 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 // This header is for backwards compatibility only, and will be removed soon. | 
|  | 12 // Include webrtc/api/optional.h instead. | 
|  | 13 | 
| 11 #ifndef WEBRTC_RTC_BASE_OPTIONAL_H_ | 14 #ifndef WEBRTC_RTC_BASE_OPTIONAL_H_ | 
| 12 #define WEBRTC_RTC_BASE_OPTIONAL_H_ | 15 #define WEBRTC_RTC_BASE_OPTIONAL_H_ | 
| 13 | 16 | 
| 14 #include <algorithm> | 17 #include "webrtc/api/optional.h" | 
| 15 #include <memory> |  | 
| 16 #include <utility> |  | 
| 17 |  | 
| 18 #ifdef UNIT_TEST |  | 
| 19 #include <iomanip> |  | 
| 20 #include <ostream> |  | 
| 21 #endif  // UNIT_TEST |  | 
| 22 |  | 
| 23 #include "webrtc/api/array_view.h" |  | 
| 24 #include "webrtc/rtc_base/checks.h" |  | 
| 25 #include "webrtc/rtc_base/sanitizer.h" |  | 
| 26 |  | 
| 27 namespace rtc { |  | 
| 28 |  | 
| 29 namespace optional_internal { |  | 
| 30 |  | 
| 31 #if RTC_HAS_ASAN |  | 
| 32 |  | 
| 33 // This is a non-inlined function. The optimizer can't see inside it.  It |  | 
| 34 // prevents the compiler from generating optimized code that reads value_ even |  | 
| 35 // if it is unset. Although safe, this causes memory sanitizers to complain. |  | 
| 36 void* FunctionThatDoesNothingImpl(void*); |  | 
| 37 |  | 
| 38 template <typename T> |  | 
| 39 inline T* FunctionThatDoesNothing(T* x) { |  | 
| 40   return reinterpret_cast<T*>( |  | 
| 41       FunctionThatDoesNothingImpl(reinterpret_cast<void*>(x))); |  | 
| 42 } |  | 
| 43 |  | 
| 44 #else |  | 
| 45 |  | 
| 46 template <typename T> |  | 
| 47 inline T* FunctionThatDoesNothing(T* x) { return x; } |  | 
| 48 |  | 
| 49 #endif |  | 
| 50 |  | 
| 51 }  // namespace optional_internal |  | 
| 52 |  | 
| 53 // Simple std::optional-wannabe. It either contains a T or not. |  | 
| 54 // |  | 
| 55 // 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 |  | 
| 57 // assume that it just doesn't contain a value anymore. |  | 
| 58 // |  | 
| 59 // Examples of good places to use Optional: |  | 
| 60 // |  | 
| 61 // - As a class or struct member, when the member doesn't always have a value: |  | 
| 62 //     struct Prisoner { |  | 
| 63 //       std::string name; |  | 
| 64 //       Optional<int> cell_number;  // Empty if not currently incarcerated. |  | 
| 65 //     }; |  | 
| 66 // |  | 
| 67 // - As a return value for functions that may fail to return a value on all |  | 
| 68 //   allowed inputs. For example, a function that searches an array might |  | 
| 69 //   return an Optional<size_t> (the index where it found the element, or |  | 
| 70 //   nothing if it didn't find it); and a function that parses numbers might |  | 
| 71 //   return Optional<double> (the parsed number, or nothing if parsing failed). |  | 
| 72 // |  | 
| 73 // Examples of bad places to use Optional: |  | 
| 74 // |  | 
| 75 // - As a return value for functions that may fail because of disallowed |  | 
| 76 //   inputs. For example, a string length function should not return |  | 
| 77 //   Optional<size_t> so that it can return nothing in case the caller passed |  | 
| 78 //   it a null pointer; the function should probably use RTC_[D]CHECK instead, |  | 
| 79 //   and return plain size_t. |  | 
| 80 // |  | 
| 81 // - As a return value for functions that may fail to return a value on all |  | 
| 82 //   allowed inputs, but need to tell the caller what went wrong. Returning |  | 
| 83 //   Optional<double> when parsing a single number as in the example above |  | 
| 84 //   might make sense, but any larger parse job is probably going to need to |  | 
| 85 //   tell the caller what the problem was, not just that there was one. |  | 
| 86 // |  | 
| 87 // - As a non-mutable function argument. When you want to pass a value of a |  | 
| 88 //   type T that can fail to be there, const T* is almost always both fastest |  | 
| 89 //   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*, |  | 
| 91 //   but this is a micro-optimization. In general, stick to const T*.) |  | 
| 92 // |  | 
| 93 // TODO(kwiberg): Get rid of this class when the standard library has |  | 
| 94 // std::optional (and we're allowed to use it). |  | 
| 95 template <typename T> |  | 
| 96 class Optional final { |  | 
| 97  public: |  | 
| 98   // Construct an empty Optional. |  | 
| 99   Optional() : has_value_(false), empty_('\0') { |  | 
| 100     PoisonValue(); |  | 
| 101   } |  | 
| 102 |  | 
| 103   // Construct an Optional that contains a value. |  | 
| 104   explicit Optional(const T& value) : has_value_(true) { |  | 
| 105     new (&value_) T(value); |  | 
| 106   } |  | 
| 107   explicit Optional(T&& value) : has_value_(true) { |  | 
| 108     new (&value_) T(std::move(value)); |  | 
| 109   } |  | 
| 110 |  | 
| 111   // Copy constructor: copies the value from m if it has one. |  | 
| 112   Optional(const Optional& m) : has_value_(m.has_value_) { |  | 
| 113     if (has_value_) |  | 
| 114       new (&value_) T(m.value_); |  | 
| 115     else |  | 
| 116       PoisonValue(); |  | 
| 117   } |  | 
| 118 |  | 
| 119   // Move constructor: if m has a value, moves the value from m, leaving m |  | 
| 120   // still in a state where it has a value, but a moved-from one (the |  | 
| 121   // properties of which depends on T; the only general guarantee is that we |  | 
| 122   // can destroy m). |  | 
| 123   Optional(Optional&& m) : has_value_(m.has_value_) { |  | 
| 124     if (has_value_) |  | 
| 125       new (&value_) T(std::move(m.value_)); |  | 
| 126     else |  | 
| 127       PoisonValue(); |  | 
| 128   } |  | 
| 129 |  | 
| 130   ~Optional() { |  | 
| 131     if (has_value_) |  | 
| 132       value_.~T(); |  | 
| 133     else |  | 
| 134       UnpoisonValue(); |  | 
| 135   } |  | 
| 136 |  | 
| 137   // Copy assignment. Uses T's copy assignment if both sides have a value, T's |  | 
| 138   // copy constructor if only the right-hand side has a value. |  | 
| 139   Optional& operator=(const Optional& m) { |  | 
| 140     if (m.has_value_) { |  | 
| 141       if (has_value_) { |  | 
| 142         value_ = m.value_;  // T's copy assignment. |  | 
| 143       } else { |  | 
| 144         UnpoisonValue(); |  | 
| 145         new (&value_) T(m.value_);  // T's copy constructor. |  | 
| 146         has_value_ = true; |  | 
| 147       } |  | 
| 148     } else { |  | 
| 149       reset(); |  | 
| 150     } |  | 
| 151     return *this; |  | 
| 152   } |  | 
| 153 |  | 
| 154   // Move assignment. Uses T's move assignment if both sides have a value, T's |  | 
| 155   // move constructor if only the right-hand side has a value. The state of m |  | 
| 156   // after it's been moved from is as for the move constructor. |  | 
| 157   Optional& operator=(Optional&& m) { |  | 
| 158     if (m.has_value_) { |  | 
| 159       if (has_value_) { |  | 
| 160         value_ = std::move(m.value_);  // T's move assignment. |  | 
| 161       } else { |  | 
| 162         UnpoisonValue(); |  | 
| 163         new (&value_) T(std::move(m.value_));  // T's move constructor. |  | 
| 164         has_value_ = true; |  | 
| 165       } |  | 
| 166     } else { |  | 
| 167       reset(); |  | 
| 168     } |  | 
| 169     return *this; |  | 
| 170   } |  | 
| 171 |  | 
| 172   // Swap the values if both m1 and m2 have values; move the value if only one |  | 
| 173   // of them has one. |  | 
| 174   friend void swap(Optional& m1, Optional& m2) { |  | 
| 175     if (m1.has_value_) { |  | 
| 176       if (m2.has_value_) { |  | 
| 177         // Both have values: swap. |  | 
| 178         using std::swap; |  | 
| 179         swap(m1.value_, m2.value_); |  | 
| 180       } else { |  | 
| 181         // Only m1 has a value: move it to m2. |  | 
| 182         m2.UnpoisonValue(); |  | 
| 183         new (&m2.value_) T(std::move(m1.value_)); |  | 
| 184         m1.value_.~T();  // Destroy the moved-from value. |  | 
| 185         m1.has_value_ = false; |  | 
| 186         m2.has_value_ = true; |  | 
| 187         m1.PoisonValue(); |  | 
| 188       } |  | 
| 189     } else if (m2.has_value_) { |  | 
| 190       // Only m2 has a value: move it to m1. |  | 
| 191       m1.UnpoisonValue(); |  | 
| 192       new (&m1.value_) T(std::move(m2.value_)); |  | 
| 193       m2.value_.~T();  // Destroy the moved-from value. |  | 
| 194       m1.has_value_ = true; |  | 
| 195       m2.has_value_ = false; |  | 
| 196       m2.PoisonValue(); |  | 
| 197     } |  | 
| 198   } |  | 
| 199 |  | 
| 200   // Destroy any contained value. Has no effect if we have no value. |  | 
| 201   void reset() { |  | 
| 202     if (!has_value_) |  | 
| 203       return; |  | 
| 204     value_.~T(); |  | 
| 205     has_value_ = false; |  | 
| 206     PoisonValue(); |  | 
| 207   } |  | 
| 208 |  | 
| 209   template <class... Args> |  | 
| 210   void emplace(Args&&... args) { |  | 
| 211     if (has_value_) |  | 
| 212       value_.~T(); |  | 
| 213     else |  | 
| 214       UnpoisonValue(); |  | 
| 215     new (&value_) T(std::forward<Args>(args)...); |  | 
| 216     has_value_ = true; |  | 
| 217   } |  | 
| 218 |  | 
| 219   // Conversion to bool to test if we have a value. |  | 
| 220   explicit operator bool() const { return has_value_; } |  | 
| 221   bool has_value() const { return has_value_; } |  | 
| 222 |  | 
| 223   // Dereferencing. Only allowed if we have a value. |  | 
| 224   const T* operator->() const { |  | 
| 225     RTC_DCHECK(has_value_); |  | 
| 226     return &value_; |  | 
| 227   } |  | 
| 228   T* operator->() { |  | 
| 229     RTC_DCHECK(has_value_); |  | 
| 230     return &value_; |  | 
| 231   } |  | 
| 232   const T& operator*() const { |  | 
| 233     RTC_DCHECK(has_value_); |  | 
| 234     return value_; |  | 
| 235   } |  | 
| 236   T& operator*() { |  | 
| 237     RTC_DCHECK(has_value_); |  | 
| 238     return value_; |  | 
| 239   } |  | 
| 240   const T& value() const { |  | 
| 241     RTC_DCHECK(has_value_); |  | 
| 242     return value_; |  | 
| 243   } |  | 
| 244   T& value() { |  | 
| 245     RTC_DCHECK(has_value_); |  | 
| 246     return value_; |  | 
| 247   } |  | 
| 248 |  | 
| 249   // Dereference with a default value in case we don't have a value. |  | 
| 250   const T& value_or(const T& default_val) const { |  | 
| 251     // The no-op call prevents the compiler from generating optimized code that |  | 
| 252     // reads value_ even if !has_value_, but only if FunctionThatDoesNothing is |  | 
| 253     // not completely inlined; see its declaration.). |  | 
| 254     return has_value_ ? *optional_internal::FunctionThatDoesNothing(&value_) |  | 
| 255                       : default_val; |  | 
| 256   } |  | 
| 257 |  | 
| 258   // Dereference and move value. |  | 
| 259   T MoveValue() { |  | 
| 260     RTC_DCHECK(has_value_); |  | 
| 261     return std::move(value_); |  | 
| 262   } |  | 
| 263 |  | 
| 264   // Equality tests. Two Optionals are equal if they contain equivalent values, |  | 
| 265   // or if they're both empty. |  | 
| 266   friend bool operator==(const Optional& m1, const Optional& m2) { |  | 
| 267     return m1.has_value_ && m2.has_value_ ? m1.value_ == m2.value_ |  | 
| 268                                           : m1.has_value_ == m2.has_value_; |  | 
| 269   } |  | 
| 270   friend bool operator==(const Optional& opt, const T& value) { |  | 
| 271     return opt.has_value_ && opt.value_ == value; |  | 
| 272   } |  | 
| 273   friend bool operator==(const T& value, const Optional& opt) { |  | 
| 274     return opt.has_value_ && value == opt.value_; |  | 
| 275   } |  | 
| 276 |  | 
| 277   friend bool operator!=(const Optional& m1, const Optional& m2) { |  | 
| 278     return m1.has_value_ && m2.has_value_ ? m1.value_ != m2.value_ |  | 
| 279                                           : m1.has_value_ != m2.has_value_; |  | 
| 280   } |  | 
| 281   friend bool operator!=(const Optional& opt, const T& value) { |  | 
| 282     return !opt.has_value_ || opt.value_ != value; |  | 
| 283   } |  | 
| 284   friend bool operator!=(const T& value, const Optional& opt) { |  | 
| 285     return !opt.has_value_ || value != opt.value_; |  | 
| 286   } |  | 
| 287 |  | 
| 288  private: |  | 
| 289   // Tell sanitizers that value_ shouldn't be touched. |  | 
| 290   void PoisonValue() { |  | 
| 291     rtc::AsanPoison(rtc::MakeArrayView(&value_, 1)); |  | 
| 292     rtc::MsanMarkUninitialized(rtc::MakeArrayView(&value_, 1)); |  | 
| 293   } |  | 
| 294 |  | 
| 295   // Tell sanitizers that value_ is OK to touch again. |  | 
| 296   void UnpoisonValue() { |  | 
| 297     rtc::AsanUnpoison(rtc::MakeArrayView(&value_, 1)); |  | 
| 298   } |  | 
| 299 |  | 
| 300   bool has_value_;  // True iff value_ contains a live value. |  | 
| 301   union { |  | 
| 302     // 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 |  | 
| 304     // trigger compiler warnings. |  | 
| 305     char empty_; |  | 
| 306     // By placing value_ in a union, we get to manage its construction and |  | 
| 307     // destruction manually: the Optional constructors won't automatically |  | 
| 308     // construct it, and the Optional destructor won't automatically destroy |  | 
| 309     // it. Basically, this just allocates a properly sized and aligned block of |  | 
| 310     // memory in which we can manually put a T with placement new. |  | 
| 311     T value_; |  | 
| 312   }; |  | 
| 313 }; |  | 
| 314 |  | 
| 315 #ifdef UNIT_TEST |  | 
| 316 namespace optional_internal { |  | 
| 317 |  | 
| 318 // Checks if there's a valid PrintTo(const T&, std::ostream*) call for T. |  | 
| 319 template <typename T> |  | 
| 320 struct HasPrintTo { |  | 
| 321  private: |  | 
| 322   struct No {}; |  | 
| 323 |  | 
| 324   template <typename T2> |  | 
| 325   static auto Test(const T2& obj) |  | 
| 326       -> decltype(PrintTo(obj, std::declval<std::ostream*>())); |  | 
| 327 |  | 
| 328   template <typename> |  | 
| 329   static No Test(...); |  | 
| 330 |  | 
| 331  public: |  | 
| 332   static constexpr bool value = |  | 
| 333       !std::is_same<decltype(Test<T>(std::declval<const T&>())), No>::value; |  | 
| 334 }; |  | 
| 335 |  | 
| 336 // Checks if there's a valid operator<<(std::ostream&, const T&) call for T. |  | 
| 337 template <typename T> |  | 
| 338 struct HasOstreamOperator { |  | 
| 339  private: |  | 
| 340   struct No {}; |  | 
| 341 |  | 
| 342   template <typename T2> |  | 
| 343   static auto Test(const T2& obj) |  | 
| 344       -> decltype(std::declval<std::ostream&>() << obj); |  | 
| 345 |  | 
| 346   template <typename> |  | 
| 347   static No Test(...); |  | 
| 348 |  | 
| 349  public: |  | 
| 350   static constexpr bool value = |  | 
| 351       !std::is_same<decltype(Test<T>(std::declval<const T&>())), No>::value; |  | 
| 352 }; |  | 
| 353 |  | 
| 354 // Prefer using PrintTo to print the object. |  | 
| 355 template <typename T> |  | 
| 356 typename std::enable_if<HasPrintTo<T>::value, void>::type OptionalPrintToHelper( |  | 
| 357     const T& value, |  | 
| 358     std::ostream* os) { |  | 
| 359   PrintTo(value, os); |  | 
| 360 } |  | 
| 361 |  | 
| 362 // Fall back to operator<<(std::ostream&, ...) if it exists. |  | 
| 363 template <typename T> |  | 
| 364 typename std::enable_if<HasOstreamOperator<T>::value && !HasPrintTo<T>::value, |  | 
| 365                         void>::type |  | 
| 366 OptionalPrintToHelper(const T& value, std::ostream* os) { |  | 
| 367   *os << value; |  | 
| 368 } |  | 
| 369 |  | 
| 370 inline void OptionalPrintObjectBytes(const unsigned char* bytes, |  | 
| 371                                      size_t size, |  | 
| 372                                      std::ostream* os) { |  | 
| 373   *os << "<optional with " << size << "-byte object ["; |  | 
| 374   for (size_t i = 0; i != size; ++i) { |  | 
| 375     *os << (i == 0 ? "" : ((i & 1) ? "-" : " ")); |  | 
| 376     *os << std::hex << std::setw(2) << std::setfill('0') |  | 
| 377         << static_cast<int>(bytes[i]); |  | 
| 378   } |  | 
| 379   *os << "]>"; |  | 
| 380 } |  | 
| 381 |  | 
| 382 // As a final back-up, just print the contents of the objcets byte-wise. |  | 
| 383 template <typename T> |  | 
| 384 typename std::enable_if<!HasOstreamOperator<T>::value && !HasPrintTo<T>::value, |  | 
| 385                         void>::type |  | 
| 386 OptionalPrintToHelper(const T& value, std::ostream* os) { |  | 
| 387   OptionalPrintObjectBytes(reinterpret_cast<const unsigned char*>(&value), |  | 
| 388                            sizeof(value), os); |  | 
| 389 } |  | 
| 390 |  | 
| 391 }  // namespace optional_internal |  | 
| 392 |  | 
| 393 // PrintTo is used by gtest to print out the results of tests. We want to ensure |  | 
| 394 // the object contained in an Optional can be printed out if it's set, while |  | 
| 395 // avoiding touching the object's storage if it is undefined. |  | 
| 396 template <typename T> |  | 
| 397 void PrintTo(const rtc::Optional<T>& opt, std::ostream* os) { |  | 
| 398   if (opt) { |  | 
| 399     optional_internal::OptionalPrintToHelper(*opt, os); |  | 
| 400   } else { |  | 
| 401     *os << "<empty optional>"; |  | 
| 402   } |  | 
| 403 } |  | 
| 404 |  | 
| 405 #endif  // UNIT_TEST |  | 
| 406 |  | 
| 407 }  // namespace rtc |  | 
| 408 | 18 | 
| 409 #endif  // WEBRTC_RTC_BASE_OPTIONAL_H_ | 19 #endif  // WEBRTC_RTC_BASE_OPTIONAL_H_ | 
| OLD | NEW | 
|---|