| 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 |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 // copy constructor if only the right-hand side has a value. | 125 // copy constructor if only the right-hand side has a value. |
| 126 Optional& operator=(const Optional& m) { | 126 Optional& operator=(const Optional& m) { |
| 127 if (m.has_value_) { | 127 if (m.has_value_) { |
| 128 if (has_value_) { | 128 if (has_value_) { |
| 129 value_ = m.value_; // T's copy assignment. | 129 value_ = m.value_; // T's copy assignment. |
| 130 } else { | 130 } else { |
| 131 UnpoisonValue(); | 131 UnpoisonValue(); |
| 132 new (&value_) T(m.value_); // T's copy constructor. | 132 new (&value_) T(m.value_); // T's copy constructor. |
| 133 has_value_ = true; | 133 has_value_ = true; |
| 134 } | 134 } |
| 135 } else if (has_value_) { | 135 } else { |
| 136 value_.~T(); | 136 reset(); |
| 137 has_value_ = false; | |
| 138 PoisonValue(); | |
| 139 } | 137 } |
| 140 return *this; | 138 return *this; |
| 141 } | 139 } |
| 142 | 140 |
| 143 // Move assignment. Uses T's move assignment if both sides have a value, T's | 141 // Move assignment. Uses T's move assignment if both sides have a value, T's |
| 144 // move constructor if only the right-hand side has a value. The state of m | 142 // move constructor if only the right-hand side has a value. The state of m |
| 145 // after it's been moved from is as for the move constructor. | 143 // after it's been moved from is as for the move constructor. |
| 146 Optional& operator=(Optional&& m) { | 144 Optional& operator=(Optional&& m) { |
| 147 if (m.has_value_) { | 145 if (m.has_value_) { |
| 148 if (has_value_) { | 146 if (has_value_) { |
| 149 value_ = std::move(m.value_); // T's move assignment. | 147 value_ = std::move(m.value_); // T's move assignment. |
| 150 } else { | 148 } else { |
| 151 UnpoisonValue(); | 149 UnpoisonValue(); |
| 152 new (&value_) T(std::move(m.value_)); // T's move constructor. | 150 new (&value_) T(std::move(m.value_)); // T's move constructor. |
| 153 has_value_ = true; | 151 has_value_ = true; |
| 154 } | 152 } |
| 155 } else if (has_value_) { | 153 } else { |
| 156 value_.~T(); | 154 reset(); |
| 157 has_value_ = false; | |
| 158 PoisonValue(); | |
| 159 } | 155 } |
| 160 return *this; | 156 return *this; |
| 161 } | 157 } |
| 162 | 158 |
| 163 // Swap the values if both m1 and m2 have values; move the value if only one | 159 // Swap the values if both m1 and m2 have values; move the value if only one |
| 164 // of them has one. | 160 // of them has one. |
| 165 friend void swap(Optional& m1, Optional& m2) { | 161 friend void swap(Optional& m1, Optional& m2) { |
| 166 if (m1.has_value_) { | 162 if (m1.has_value_) { |
| 167 if (m2.has_value_) { | 163 if (m2.has_value_) { |
| 168 // Both have values: swap. | 164 // Both have values: swap. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 181 // Only m2 has a value: move it to m1. | 177 // Only m2 has a value: move it to m1. |
| 182 m1.UnpoisonValue(); | 178 m1.UnpoisonValue(); |
| 183 new (&m1.value_) T(std::move(m2.value_)); | 179 new (&m1.value_) T(std::move(m2.value_)); |
| 184 m2.value_.~T(); // Destroy the moved-from value. | 180 m2.value_.~T(); // Destroy the moved-from value. |
| 185 m1.has_value_ = true; | 181 m1.has_value_ = true; |
| 186 m2.has_value_ = false; | 182 m2.has_value_ = false; |
| 187 m2.PoisonValue(); | 183 m2.PoisonValue(); |
| 188 } | 184 } |
| 189 } | 185 } |
| 190 | 186 |
| 187 // Destroy any contained value. Has no effect if we have no value. |
| 188 void reset() { |
| 189 if (!has_value_) |
| 190 return; |
| 191 value_.~T(); |
| 192 has_value_ = false; |
| 193 PoisonValue(); |
| 194 } |
| 195 |
| 191 // Conversion to bool to test if we have a value. | 196 // Conversion to bool to test if we have a value. |
| 192 explicit operator bool() const { return has_value_; } | 197 explicit operator bool() const { return has_value_; } |
| 193 | 198 |
| 194 // Dereferencing. Only allowed if we have a value. | 199 // Dereferencing. Only allowed if we have a value. |
| 195 const T* operator->() const { | 200 const T* operator->() const { |
| 196 RTC_DCHECK(has_value_); | 201 RTC_DCHECK(has_value_); |
| 197 return &value_; | 202 return &value_; |
| 198 } | 203 } |
| 199 T* operator->() { | 204 T* operator->() { |
| 200 RTC_DCHECK(has_value_); | 205 RTC_DCHECK(has_value_); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 // construct it, and the Optional destructor won't automatically destroy | 258 // construct it, and the Optional destructor won't automatically destroy |
| 254 // it. Basically, this just allocates a properly sized and aligned block of | 259 // it. Basically, this just allocates a properly sized and aligned block of |
| 255 // memory in which we can manually put a T with placement new. | 260 // memory in which we can manually put a T with placement new. |
| 256 T value_; | 261 T value_; |
| 257 }; | 262 }; |
| 258 }; | 263 }; |
| 259 | 264 |
| 260 } // namespace rtc | 265 } // namespace rtc |
| 261 | 266 |
| 262 #endif // WEBRTC_BASE_OPTIONAL_H_ | 267 #endif // WEBRTC_BASE_OPTIONAL_H_ |
| OLD | NEW |