1*635a8641SAndroid Build Coastguard Worker // Copyright 2016 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_OPTIONAL_H_ 6*635a8641SAndroid Build Coastguard Worker #define BASE_OPTIONAL_H_ 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard Worker #include <type_traits> 9*635a8641SAndroid Build Coastguard Worker #include <utility> 10*635a8641SAndroid Build Coastguard Worker 11*635a8641SAndroid Build Coastguard Worker #include "base/logging.h" 12*635a8641SAndroid Build Coastguard Worker #include "base/template_util.h" 13*635a8641SAndroid Build Coastguard Worker 14*635a8641SAndroid Build Coastguard Worker namespace base { 15*635a8641SAndroid Build Coastguard Worker 16*635a8641SAndroid Build Coastguard Worker // Specification: 17*635a8641SAndroid Build Coastguard Worker // http://en.cppreference.com/w/cpp/utility/optional/in_place_t 18*635a8641SAndroid Build Coastguard Worker struct in_place_t {}; 19*635a8641SAndroid Build Coastguard Worker 20*635a8641SAndroid Build Coastguard Worker // Specification: 21*635a8641SAndroid Build Coastguard Worker // http://en.cppreference.com/w/cpp/utility/optional/nullopt_t 22*635a8641SAndroid Build Coastguard Worker struct nullopt_t { nullopt_tnullopt_t23*635a8641SAndroid Build Coastguard Worker constexpr explicit nullopt_t(int) {} 24*635a8641SAndroid Build Coastguard Worker }; 25*635a8641SAndroid Build Coastguard Worker 26*635a8641SAndroid Build Coastguard Worker // Specification: 27*635a8641SAndroid Build Coastguard Worker // http://en.cppreference.com/w/cpp/utility/optional/in_place 28*635a8641SAndroid Build Coastguard Worker constexpr in_place_t in_place = {}; 29*635a8641SAndroid Build Coastguard Worker 30*635a8641SAndroid Build Coastguard Worker // Specification: 31*635a8641SAndroid Build Coastguard Worker // http://en.cppreference.com/w/cpp/utility/optional/nullopt 32*635a8641SAndroid Build Coastguard Worker constexpr nullopt_t nullopt(0); 33*635a8641SAndroid Build Coastguard Worker 34*635a8641SAndroid Build Coastguard Worker // Forward declaration, which is refered by following helpers. 35*635a8641SAndroid Build Coastguard Worker template <typename T> 36*635a8641SAndroid Build Coastguard Worker class Optional; 37*635a8641SAndroid Build Coastguard Worker 38*635a8641SAndroid Build Coastguard Worker namespace internal { 39*635a8641SAndroid Build Coastguard Worker 40*635a8641SAndroid Build Coastguard Worker template <typename T, bool = std::is_trivially_destructible<T>::value> 41*635a8641SAndroid Build Coastguard Worker struct OptionalStorageBase { 42*635a8641SAndroid Build Coastguard Worker // Initializing |empty_| here instead of using default member initializing 43*635a8641SAndroid Build Coastguard Worker // to avoid errors in g++ 4.8. OptionalStorageBaseOptionalStorageBase44*635a8641SAndroid Build Coastguard Worker constexpr OptionalStorageBase() : empty_('\0') {} 45*635a8641SAndroid Build Coastguard Worker 46*635a8641SAndroid Build Coastguard Worker template <class... Args> OptionalStorageBaseOptionalStorageBase47*635a8641SAndroid Build Coastguard Worker constexpr explicit OptionalStorageBase(in_place_t, Args&&... args) 48*635a8641SAndroid Build Coastguard Worker : is_populated_(true), value_(std::forward<Args>(args)...) {} 49*635a8641SAndroid Build Coastguard Worker 50*635a8641SAndroid Build Coastguard Worker // When T is not trivially destructible we must call its 51*635a8641SAndroid Build Coastguard Worker // destructor before deallocating its memory. 52*635a8641SAndroid Build Coastguard Worker // Note that this hides the (implicitly declared) move constructor, which 53*635a8641SAndroid Build Coastguard Worker // would be used for constexpr move constructor in OptionalStorage<T>. 54*635a8641SAndroid Build Coastguard Worker // It is needed iff T is trivially move constructible. However, the current 55*635a8641SAndroid Build Coastguard Worker // is_trivially_{copy,move}_constructible implementation requires 56*635a8641SAndroid Build Coastguard Worker // is_trivially_destructible (which looks a bug, cf: 57*635a8641SAndroid Build Coastguard Worker // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 and 58*635a8641SAndroid Build Coastguard Worker // http://cplusplus.github.io/LWG/lwg-active.html#2116), so it is not 59*635a8641SAndroid Build Coastguard Worker // necessary for this case at the moment. Please see also the destructor 60*635a8641SAndroid Build Coastguard Worker // comment in "is_trivially_destructible = true" specialization below. ~OptionalStorageBaseOptionalStorageBase61*635a8641SAndroid Build Coastguard Worker ~OptionalStorageBase() { 62*635a8641SAndroid Build Coastguard Worker if (is_populated_) 63*635a8641SAndroid Build Coastguard Worker value_.~T(); 64*635a8641SAndroid Build Coastguard Worker } 65*635a8641SAndroid Build Coastguard Worker 66*635a8641SAndroid Build Coastguard Worker template <class... Args> InitOptionalStorageBase67*635a8641SAndroid Build Coastguard Worker void Init(Args&&... args) { 68*635a8641SAndroid Build Coastguard Worker DCHECK(!is_populated_); 69*635a8641SAndroid Build Coastguard Worker ::new (&value_) T(std::forward<Args>(args)...); 70*635a8641SAndroid Build Coastguard Worker is_populated_ = true; 71*635a8641SAndroid Build Coastguard Worker } 72*635a8641SAndroid Build Coastguard Worker 73*635a8641SAndroid Build Coastguard Worker bool is_populated_ = false; 74*635a8641SAndroid Build Coastguard Worker union { 75*635a8641SAndroid Build Coastguard Worker // |empty_| exists so that the union will always be initialized, even when 76*635a8641SAndroid Build Coastguard Worker // it doesn't contain a value. Union members must be initialized for the 77*635a8641SAndroid Build Coastguard Worker // constructor to be 'constexpr'. 78*635a8641SAndroid Build Coastguard Worker char empty_; 79*635a8641SAndroid Build Coastguard Worker T value_; 80*635a8641SAndroid Build Coastguard Worker }; 81*635a8641SAndroid Build Coastguard Worker }; 82*635a8641SAndroid Build Coastguard Worker 83*635a8641SAndroid Build Coastguard Worker template <typename T> 84*635a8641SAndroid Build Coastguard Worker struct OptionalStorageBase<T, true /* trivially destructible */> { 85*635a8641SAndroid Build Coastguard Worker // Initializing |empty_| here instead of using default member initializing 86*635a8641SAndroid Build Coastguard Worker // to avoid errors in g++ 4.8. 87*635a8641SAndroid Build Coastguard Worker constexpr OptionalStorageBase() : empty_('\0') {} 88*635a8641SAndroid Build Coastguard Worker 89*635a8641SAndroid Build Coastguard Worker template <class... Args> 90*635a8641SAndroid Build Coastguard Worker constexpr explicit OptionalStorageBase(in_place_t, Args&&... args) 91*635a8641SAndroid Build Coastguard Worker : is_populated_(true), value_(std::forward<Args>(args)...) {} 92*635a8641SAndroid Build Coastguard Worker 93*635a8641SAndroid Build Coastguard Worker // When T is trivially destructible (i.e. its destructor does nothing) there 94*635a8641SAndroid Build Coastguard Worker // is no need to call it. Implicitly defined destructor is trivial, because 95*635a8641SAndroid Build Coastguard Worker // both members (bool and union containing only variants which are trivially 96*635a8641SAndroid Build Coastguard Worker // destructible) are trivially destructible. 97*635a8641SAndroid Build Coastguard Worker // Explicitly-defaulted destructor is also trivial, but do not use it here, 98*635a8641SAndroid Build Coastguard Worker // because it hides the implicit move constructor. It is needed to implement 99*635a8641SAndroid Build Coastguard Worker // constexpr move constructor in OptionalStorage iff T is trivially move 100*635a8641SAndroid Build Coastguard Worker // constructible. Note that, if T is trivially move constructible, the move 101*635a8641SAndroid Build Coastguard Worker // constructor of OptionalStorageBase<T> is also implicitly defined and it is 102*635a8641SAndroid Build Coastguard Worker // trivially move constructor. If T is not trivially move constructible, 103*635a8641SAndroid Build Coastguard Worker // "not declaring move constructor without destructor declaration" here means 104*635a8641SAndroid Build Coastguard Worker // "delete move constructor", which works because any move constructor of 105*635a8641SAndroid Build Coastguard Worker // OptionalStorage will not refer to it in that case. 106*635a8641SAndroid Build Coastguard Worker 107*635a8641SAndroid Build Coastguard Worker template <class... Args> 108*635a8641SAndroid Build Coastguard Worker void Init(Args&&... args) { 109*635a8641SAndroid Build Coastguard Worker DCHECK(!is_populated_); 110*635a8641SAndroid Build Coastguard Worker ::new (&value_) T(std::forward<Args>(args)...); 111*635a8641SAndroid Build Coastguard Worker is_populated_ = true; 112*635a8641SAndroid Build Coastguard Worker } 113*635a8641SAndroid Build Coastguard Worker 114*635a8641SAndroid Build Coastguard Worker bool is_populated_ = false; 115*635a8641SAndroid Build Coastguard Worker union { 116*635a8641SAndroid Build Coastguard Worker // |empty_| exists so that the union will always be initialized, even when 117*635a8641SAndroid Build Coastguard Worker // it doesn't contain a value. Union members must be initialized for the 118*635a8641SAndroid Build Coastguard Worker // constructor to be 'constexpr'. 119*635a8641SAndroid Build Coastguard Worker char empty_; 120*635a8641SAndroid Build Coastguard Worker T value_; 121*635a8641SAndroid Build Coastguard Worker }; 122*635a8641SAndroid Build Coastguard Worker }; 123*635a8641SAndroid Build Coastguard Worker 124*635a8641SAndroid Build Coastguard Worker // Implement conditional constexpr copy and move constructors. These are 125*635a8641SAndroid Build Coastguard Worker // constexpr if is_trivially_{copy,move}_constructible<T>::value is true 126*635a8641SAndroid Build Coastguard Worker // respectively. If each is true, the corresponding constructor is defined as 127*635a8641SAndroid Build Coastguard Worker // "= default;", which generates a constexpr constructor (In this case, 128*635a8641SAndroid Build Coastguard Worker // the condition of constexpr-ness is satisfied because the base class also has 129*635a8641SAndroid Build Coastguard Worker // compiler generated constexpr {copy,move} constructors). Note that 130*635a8641SAndroid Build Coastguard Worker // placement-new is prohibited in constexpr. 131*635a8641SAndroid Build Coastguard Worker template <typename T, 132*635a8641SAndroid Build Coastguard Worker bool = is_trivially_copy_constructible<T>::value, 133*635a8641SAndroid Build Coastguard Worker bool = std::is_trivially_move_constructible<T>::value> 134*635a8641SAndroid Build Coastguard Worker struct OptionalStorage : OptionalStorageBase<T> { 135*635a8641SAndroid Build Coastguard Worker // This is no trivially {copy,move} constructible case. Other cases are 136*635a8641SAndroid Build Coastguard Worker // defined below as specializations. 137*635a8641SAndroid Build Coastguard Worker 138*635a8641SAndroid Build Coastguard Worker // Accessing the members of template base class requires explicit 139*635a8641SAndroid Build Coastguard Worker // declaration. 140*635a8641SAndroid Build Coastguard Worker using OptionalStorageBase<T>::is_populated_; 141*635a8641SAndroid Build Coastguard Worker using OptionalStorageBase<T>::value_; 142*635a8641SAndroid Build Coastguard Worker using OptionalStorageBase<T>::Init; 143*635a8641SAndroid Build Coastguard Worker 144*635a8641SAndroid Build Coastguard Worker // Inherit constructors (specifically, the in_place constructor). 145*635a8641SAndroid Build Coastguard Worker using OptionalStorageBase<T>::OptionalStorageBase; 146*635a8641SAndroid Build Coastguard Worker 147*635a8641SAndroid Build Coastguard Worker // User defined constructor deletes the default constructor. 148*635a8641SAndroid Build Coastguard Worker // Define it explicitly. 149*635a8641SAndroid Build Coastguard Worker OptionalStorage() = default; 150*635a8641SAndroid Build Coastguard Worker 151*635a8641SAndroid Build Coastguard Worker OptionalStorage(const OptionalStorage& other) { 152*635a8641SAndroid Build Coastguard Worker if (other.is_populated_) 153*635a8641SAndroid Build Coastguard Worker Init(other.value_); 154*635a8641SAndroid Build Coastguard Worker } 155*635a8641SAndroid Build Coastguard Worker 156*635a8641SAndroid Build Coastguard Worker OptionalStorage(OptionalStorage&& other) noexcept( 157*635a8641SAndroid Build Coastguard Worker std::is_nothrow_move_constructible<T>::value) { 158*635a8641SAndroid Build Coastguard Worker if (other.is_populated_) 159*635a8641SAndroid Build Coastguard Worker Init(std::move(other.value_)); 160*635a8641SAndroid Build Coastguard Worker } 161*635a8641SAndroid Build Coastguard Worker }; 162*635a8641SAndroid Build Coastguard Worker 163*635a8641SAndroid Build Coastguard Worker template <typename T> 164*635a8641SAndroid Build Coastguard Worker struct OptionalStorage<T, 165*635a8641SAndroid Build Coastguard Worker true /* trivially copy constructible */, 166*635a8641SAndroid Build Coastguard Worker false /* trivially move constructible */> 167*635a8641SAndroid Build Coastguard Worker : OptionalStorageBase<T> { 168*635a8641SAndroid Build Coastguard Worker using OptionalStorageBase<T>::is_populated_; 169*635a8641SAndroid Build Coastguard Worker using OptionalStorageBase<T>::value_; 170*635a8641SAndroid Build Coastguard Worker using OptionalStorageBase<T>::Init; 171*635a8641SAndroid Build Coastguard Worker using OptionalStorageBase<T>::OptionalStorageBase; 172*635a8641SAndroid Build Coastguard Worker 173*635a8641SAndroid Build Coastguard Worker OptionalStorage() = default; 174*635a8641SAndroid Build Coastguard Worker OptionalStorage(const OptionalStorage& other) = default; 175*635a8641SAndroid Build Coastguard Worker 176*635a8641SAndroid Build Coastguard Worker OptionalStorage(OptionalStorage&& other) noexcept( 177*635a8641SAndroid Build Coastguard Worker std::is_nothrow_move_constructible<T>::value) { 178*635a8641SAndroid Build Coastguard Worker if (other.is_populated_) 179*635a8641SAndroid Build Coastguard Worker Init(std::move(other.value_)); 180*635a8641SAndroid Build Coastguard Worker } 181*635a8641SAndroid Build Coastguard Worker }; 182*635a8641SAndroid Build Coastguard Worker 183*635a8641SAndroid Build Coastguard Worker template <typename T> 184*635a8641SAndroid Build Coastguard Worker struct OptionalStorage<T, 185*635a8641SAndroid Build Coastguard Worker false /* trivially copy constructible */, 186*635a8641SAndroid Build Coastguard Worker true /* trivially move constructible */> 187*635a8641SAndroid Build Coastguard Worker : OptionalStorageBase<T> { 188*635a8641SAndroid Build Coastguard Worker using OptionalStorageBase<T>::is_populated_; 189*635a8641SAndroid Build Coastguard Worker using OptionalStorageBase<T>::value_; 190*635a8641SAndroid Build Coastguard Worker using OptionalStorageBase<T>::Init; 191*635a8641SAndroid Build Coastguard Worker using OptionalStorageBase<T>::OptionalStorageBase; 192*635a8641SAndroid Build Coastguard Worker 193*635a8641SAndroid Build Coastguard Worker OptionalStorage() = default; 194*635a8641SAndroid Build Coastguard Worker OptionalStorage(OptionalStorage&& other) = default; 195*635a8641SAndroid Build Coastguard Worker 196*635a8641SAndroid Build Coastguard Worker OptionalStorage(const OptionalStorage& other) { 197*635a8641SAndroid Build Coastguard Worker if (other.is_populated_) 198*635a8641SAndroid Build Coastguard Worker Init(other.value_); 199*635a8641SAndroid Build Coastguard Worker } 200*635a8641SAndroid Build Coastguard Worker }; 201*635a8641SAndroid Build Coastguard Worker 202*635a8641SAndroid Build Coastguard Worker template <typename T> 203*635a8641SAndroid Build Coastguard Worker struct OptionalStorage<T, 204*635a8641SAndroid Build Coastguard Worker true /* trivially copy constructible */, 205*635a8641SAndroid Build Coastguard Worker true /* trivially move constructible */> 206*635a8641SAndroid Build Coastguard Worker : OptionalStorageBase<T> { 207*635a8641SAndroid Build Coastguard Worker // If both trivially {copy,move} constructible are true, it is not necessary 208*635a8641SAndroid Build Coastguard Worker // to use user-defined constructors. So, just inheriting constructors 209*635a8641SAndroid Build Coastguard Worker // from the base class works. 210*635a8641SAndroid Build Coastguard Worker using OptionalStorageBase<T>::OptionalStorageBase; 211*635a8641SAndroid Build Coastguard Worker }; 212*635a8641SAndroid Build Coastguard Worker 213*635a8641SAndroid Build Coastguard Worker // Base class to support conditionally usable copy-/move- constructors 214*635a8641SAndroid Build Coastguard Worker // and assign operators. 215*635a8641SAndroid Build Coastguard Worker template <typename T> 216*635a8641SAndroid Build Coastguard Worker class OptionalBase { 217*635a8641SAndroid Build Coastguard Worker // This class provides implementation rather than public API, so everything 218*635a8641SAndroid Build Coastguard Worker // should be hidden. Often we use composition, but we cannot in this case 219*635a8641SAndroid Build Coastguard Worker // because of C++ language restriction. 220*635a8641SAndroid Build Coastguard Worker protected: 221*635a8641SAndroid Build Coastguard Worker constexpr OptionalBase() = default; 222*635a8641SAndroid Build Coastguard Worker constexpr OptionalBase(const OptionalBase& other) = default; 223*635a8641SAndroid Build Coastguard Worker constexpr OptionalBase(OptionalBase&& other) = default; 224*635a8641SAndroid Build Coastguard Worker 225*635a8641SAndroid Build Coastguard Worker template <class... Args> 226*635a8641SAndroid Build Coastguard Worker constexpr explicit OptionalBase(in_place_t, Args&&... args) 227*635a8641SAndroid Build Coastguard Worker : storage_(in_place, std::forward<Args>(args)...) {} 228*635a8641SAndroid Build Coastguard Worker 229*635a8641SAndroid Build Coastguard Worker // Implementation of converting constructors. 230*635a8641SAndroid Build Coastguard Worker template <typename U> 231*635a8641SAndroid Build Coastguard Worker explicit OptionalBase(const OptionalBase<U>& other) { 232*635a8641SAndroid Build Coastguard Worker if (other.storage_.is_populated_) 233*635a8641SAndroid Build Coastguard Worker storage_.Init(other.storage_.value_); 234*635a8641SAndroid Build Coastguard Worker } 235*635a8641SAndroid Build Coastguard Worker 236*635a8641SAndroid Build Coastguard Worker template <typename U> 237*635a8641SAndroid Build Coastguard Worker explicit OptionalBase(OptionalBase<U>&& other) { 238*635a8641SAndroid Build Coastguard Worker if (other.storage_.is_populated_) 239*635a8641SAndroid Build Coastguard Worker storage_.Init(std::move(other.storage_.value_)); 240*635a8641SAndroid Build Coastguard Worker } 241*635a8641SAndroid Build Coastguard Worker 242*635a8641SAndroid Build Coastguard Worker ~OptionalBase() = default; 243*635a8641SAndroid Build Coastguard Worker 244*635a8641SAndroid Build Coastguard Worker OptionalBase& operator=(const OptionalBase& other) { 245*635a8641SAndroid Build Coastguard Worker CopyAssign(other); 246*635a8641SAndroid Build Coastguard Worker return *this; 247*635a8641SAndroid Build Coastguard Worker } 248*635a8641SAndroid Build Coastguard Worker 249*635a8641SAndroid Build Coastguard Worker OptionalBase& operator=(OptionalBase&& other) noexcept( 250*635a8641SAndroid Build Coastguard Worker std::is_nothrow_move_assignable<T>::value&& 251*635a8641SAndroid Build Coastguard Worker std::is_nothrow_move_constructible<T>::value) { 252*635a8641SAndroid Build Coastguard Worker MoveAssign(std::move(other)); 253*635a8641SAndroid Build Coastguard Worker return *this; 254*635a8641SAndroid Build Coastguard Worker } 255*635a8641SAndroid Build Coastguard Worker 256*635a8641SAndroid Build Coastguard Worker template <typename U> 257*635a8641SAndroid Build Coastguard Worker void CopyAssign(const OptionalBase<U>& other) { 258*635a8641SAndroid Build Coastguard Worker if (other.storage_.is_populated_) 259*635a8641SAndroid Build Coastguard Worker InitOrAssign(other.storage_.value_); 260*635a8641SAndroid Build Coastguard Worker else 261*635a8641SAndroid Build Coastguard Worker FreeIfNeeded(); 262*635a8641SAndroid Build Coastguard Worker } 263*635a8641SAndroid Build Coastguard Worker 264*635a8641SAndroid Build Coastguard Worker template <typename U> 265*635a8641SAndroid Build Coastguard Worker void MoveAssign(OptionalBase<U>&& other) { 266*635a8641SAndroid Build Coastguard Worker if (other.storage_.is_populated_) 267*635a8641SAndroid Build Coastguard Worker InitOrAssign(std::move(other.storage_.value_)); 268*635a8641SAndroid Build Coastguard Worker else 269*635a8641SAndroid Build Coastguard Worker FreeIfNeeded(); 270*635a8641SAndroid Build Coastguard Worker } 271*635a8641SAndroid Build Coastguard Worker 272*635a8641SAndroid Build Coastguard Worker template <typename U> 273*635a8641SAndroid Build Coastguard Worker void InitOrAssign(U&& value) { 274*635a8641SAndroid Build Coastguard Worker if (storage_.is_populated_) 275*635a8641SAndroid Build Coastguard Worker storage_.value_ = std::forward<U>(value); 276*635a8641SAndroid Build Coastguard Worker else 277*635a8641SAndroid Build Coastguard Worker storage_.Init(std::forward<U>(value)); 278*635a8641SAndroid Build Coastguard Worker } 279*635a8641SAndroid Build Coastguard Worker 280*635a8641SAndroid Build Coastguard Worker void FreeIfNeeded() { 281*635a8641SAndroid Build Coastguard Worker if (!storage_.is_populated_) 282*635a8641SAndroid Build Coastguard Worker return; 283*635a8641SAndroid Build Coastguard Worker storage_.value_.~T(); 284*635a8641SAndroid Build Coastguard Worker storage_.is_populated_ = false; 285*635a8641SAndroid Build Coastguard Worker } 286*635a8641SAndroid Build Coastguard Worker 287*635a8641SAndroid Build Coastguard Worker // For implementing conversion, allow access to other typed OptionalBase 288*635a8641SAndroid Build Coastguard Worker // class. 289*635a8641SAndroid Build Coastguard Worker template <typename U> 290*635a8641SAndroid Build Coastguard Worker friend class OptionalBase; 291*635a8641SAndroid Build Coastguard Worker 292*635a8641SAndroid Build Coastguard Worker OptionalStorage<T> storage_; 293*635a8641SAndroid Build Coastguard Worker }; 294*635a8641SAndroid Build Coastguard Worker 295*635a8641SAndroid Build Coastguard Worker // The following {Copy,Move}{Constructible,Assignable} structs are helpers to 296*635a8641SAndroid Build Coastguard Worker // implement constructor/assign-operator overloading. Specifically, if T is 297*635a8641SAndroid Build Coastguard Worker // is not movable but copyable, Optional<T>'s move constructor should not 298*635a8641SAndroid Build Coastguard Worker // participate in overload resolution. This inheritance trick implements that. 299*635a8641SAndroid Build Coastguard Worker template <bool is_copy_constructible> 300*635a8641SAndroid Build Coastguard Worker struct CopyConstructible {}; 301*635a8641SAndroid Build Coastguard Worker 302*635a8641SAndroid Build Coastguard Worker template <> 303*635a8641SAndroid Build Coastguard Worker struct CopyConstructible<false> { 304*635a8641SAndroid Build Coastguard Worker constexpr CopyConstructible() = default; 305*635a8641SAndroid Build Coastguard Worker constexpr CopyConstructible(const CopyConstructible&) = delete; 306*635a8641SAndroid Build Coastguard Worker constexpr CopyConstructible(CopyConstructible&&) = default; 307*635a8641SAndroid Build Coastguard Worker CopyConstructible& operator=(const CopyConstructible&) = default; 308*635a8641SAndroid Build Coastguard Worker CopyConstructible& operator=(CopyConstructible&&) = default; 309*635a8641SAndroid Build Coastguard Worker }; 310*635a8641SAndroid Build Coastguard Worker 311*635a8641SAndroid Build Coastguard Worker template <bool is_move_constructible> 312*635a8641SAndroid Build Coastguard Worker struct MoveConstructible {}; 313*635a8641SAndroid Build Coastguard Worker 314*635a8641SAndroid Build Coastguard Worker template <> 315*635a8641SAndroid Build Coastguard Worker struct MoveConstructible<false> { 316*635a8641SAndroid Build Coastguard Worker constexpr MoveConstructible() = default; 317*635a8641SAndroid Build Coastguard Worker constexpr MoveConstructible(const MoveConstructible&) = default; 318*635a8641SAndroid Build Coastguard Worker constexpr MoveConstructible(MoveConstructible&&) = delete; 319*635a8641SAndroid Build Coastguard Worker MoveConstructible& operator=(const MoveConstructible&) = default; 320*635a8641SAndroid Build Coastguard Worker MoveConstructible& operator=(MoveConstructible&&) = default; 321*635a8641SAndroid Build Coastguard Worker }; 322*635a8641SAndroid Build Coastguard Worker 323*635a8641SAndroid Build Coastguard Worker template <bool is_copy_assignable> 324*635a8641SAndroid Build Coastguard Worker struct CopyAssignable {}; 325*635a8641SAndroid Build Coastguard Worker 326*635a8641SAndroid Build Coastguard Worker template <> 327*635a8641SAndroid Build Coastguard Worker struct CopyAssignable<false> { 328*635a8641SAndroid Build Coastguard Worker constexpr CopyAssignable() = default; 329*635a8641SAndroid Build Coastguard Worker constexpr CopyAssignable(const CopyAssignable&) = default; 330*635a8641SAndroid Build Coastguard Worker constexpr CopyAssignable(CopyAssignable&&) = default; 331*635a8641SAndroid Build Coastguard Worker CopyAssignable& operator=(const CopyAssignable&) = delete; 332*635a8641SAndroid Build Coastguard Worker CopyAssignable& operator=(CopyAssignable&&) = default; 333*635a8641SAndroid Build Coastguard Worker }; 334*635a8641SAndroid Build Coastguard Worker 335*635a8641SAndroid Build Coastguard Worker template <bool is_move_assignable> 336*635a8641SAndroid Build Coastguard Worker struct MoveAssignable {}; 337*635a8641SAndroid Build Coastguard Worker 338*635a8641SAndroid Build Coastguard Worker template <> 339*635a8641SAndroid Build Coastguard Worker struct MoveAssignable<false> { 340*635a8641SAndroid Build Coastguard Worker constexpr MoveAssignable() = default; 341*635a8641SAndroid Build Coastguard Worker constexpr MoveAssignable(const MoveAssignable&) = default; 342*635a8641SAndroid Build Coastguard Worker constexpr MoveAssignable(MoveAssignable&&) = default; 343*635a8641SAndroid Build Coastguard Worker MoveAssignable& operator=(const MoveAssignable&) = default; 344*635a8641SAndroid Build Coastguard Worker MoveAssignable& operator=(MoveAssignable&&) = delete; 345*635a8641SAndroid Build Coastguard Worker }; 346*635a8641SAndroid Build Coastguard Worker 347*635a8641SAndroid Build Coastguard Worker // Helper to conditionally enable converting constructors and assign operators. 348*635a8641SAndroid Build Coastguard Worker template <typename T, typename U> 349*635a8641SAndroid Build Coastguard Worker struct IsConvertibleFromOptional 350*635a8641SAndroid Build Coastguard Worker : std::integral_constant< 351*635a8641SAndroid Build Coastguard Worker bool, 352*635a8641SAndroid Build Coastguard Worker std::is_constructible<T, Optional<U>&>::value || 353*635a8641SAndroid Build Coastguard Worker std::is_constructible<T, const Optional<U>&>::value || 354*635a8641SAndroid Build Coastguard Worker std::is_constructible<T, Optional<U>&&>::value || 355*635a8641SAndroid Build Coastguard Worker std::is_constructible<T, const Optional<U>&&>::value || 356*635a8641SAndroid Build Coastguard Worker std::is_convertible<Optional<U>&, T>::value || 357*635a8641SAndroid Build Coastguard Worker std::is_convertible<const Optional<U>&, T>::value || 358*635a8641SAndroid Build Coastguard Worker std::is_convertible<Optional<U>&&, T>::value || 359*635a8641SAndroid Build Coastguard Worker std::is_convertible<const Optional<U>&&, T>::value> {}; 360*635a8641SAndroid Build Coastguard Worker 361*635a8641SAndroid Build Coastguard Worker template <typename T, typename U> 362*635a8641SAndroid Build Coastguard Worker struct IsAssignableFromOptional 363*635a8641SAndroid Build Coastguard Worker : std::integral_constant< 364*635a8641SAndroid Build Coastguard Worker bool, 365*635a8641SAndroid Build Coastguard Worker IsConvertibleFromOptional<T, U>::value || 366*635a8641SAndroid Build Coastguard Worker std::is_assignable<T&, Optional<U>&>::value || 367*635a8641SAndroid Build Coastguard Worker std::is_assignable<T&, const Optional<U>&>::value || 368*635a8641SAndroid Build Coastguard Worker std::is_assignable<T&, Optional<U>&&>::value || 369*635a8641SAndroid Build Coastguard Worker std::is_assignable<T&, const Optional<U>&&>::value> {}; 370*635a8641SAndroid Build Coastguard Worker 371*635a8641SAndroid Build Coastguard Worker // Forward compatibility for C++17. 372*635a8641SAndroid Build Coastguard Worker // Introduce one more deeper nested namespace to avoid leaking using std::swap. 373*635a8641SAndroid Build Coastguard Worker namespace swappable_impl { 374*635a8641SAndroid Build Coastguard Worker using std::swap; 375*635a8641SAndroid Build Coastguard Worker 376*635a8641SAndroid Build Coastguard Worker struct IsSwappableImpl { 377*635a8641SAndroid Build Coastguard Worker // Tests if swap can be called. Check<T&>(0) returns true_type iff swap 378*635a8641SAndroid Build Coastguard Worker // is available for T. Otherwise, Check's overload resolution falls back 379*635a8641SAndroid Build Coastguard Worker // to Check(...) declared below thanks to SFINAE, so returns false_type. 380*635a8641SAndroid Build Coastguard Worker template <typename T> 381*635a8641SAndroid Build Coastguard Worker static auto Check(int) 382*635a8641SAndroid Build Coastguard Worker -> decltype(swap(std::declval<T>(), std::declval<T>()), std::true_type()); 383*635a8641SAndroid Build Coastguard Worker 384*635a8641SAndroid Build Coastguard Worker template <typename T> 385*635a8641SAndroid Build Coastguard Worker static std::false_type Check(...); 386*635a8641SAndroid Build Coastguard Worker }; 387*635a8641SAndroid Build Coastguard Worker } // namespace swappable_impl 388*635a8641SAndroid Build Coastguard Worker 389*635a8641SAndroid Build Coastguard Worker template <typename T> 390*635a8641SAndroid Build Coastguard Worker struct IsSwappable : decltype(swappable_impl::IsSwappableImpl::Check<T&>(0)) {}; 391*635a8641SAndroid Build Coastguard Worker 392*635a8641SAndroid Build Coastguard Worker // Forward compatibility for C++20. 393*635a8641SAndroid Build Coastguard Worker template <typename T> 394*635a8641SAndroid Build Coastguard Worker using RemoveCvRefT = std::remove_cv_t<std::remove_reference_t<T>>; 395*635a8641SAndroid Build Coastguard Worker 396*635a8641SAndroid Build Coastguard Worker } // namespace internal 397*635a8641SAndroid Build Coastguard Worker 398*635a8641SAndroid Build Coastguard Worker // On Windows, by default, empty-base class optimization does not work, 399*635a8641SAndroid Build Coastguard Worker // which means even if the base class is empty struct, it still consumes one 400*635a8641SAndroid Build Coastguard Worker // byte for its body. __declspec(empty_bases) enables the optimization. 401*635a8641SAndroid Build Coastguard Worker // cf) 402*635a8641SAndroid Build Coastguard Worker // https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/ 403*635a8641SAndroid Build Coastguard Worker #ifdef OS_WIN 404*635a8641SAndroid Build Coastguard Worker #define OPTIONAL_DECLSPEC_EMPTY_BASES __declspec(empty_bases) 405*635a8641SAndroid Build Coastguard Worker #else 406*635a8641SAndroid Build Coastguard Worker #define OPTIONAL_DECLSPEC_EMPTY_BASES 407*635a8641SAndroid Build Coastguard Worker #endif 408*635a8641SAndroid Build Coastguard Worker 409*635a8641SAndroid Build Coastguard Worker // base::Optional is a Chromium version of the C++17 optional class: 410*635a8641SAndroid Build Coastguard Worker // std::optional documentation: 411*635a8641SAndroid Build Coastguard Worker // http://en.cppreference.com/w/cpp/utility/optional 412*635a8641SAndroid Build Coastguard Worker // Chromium documentation: 413*635a8641SAndroid Build Coastguard Worker // https://chromium.googlesource.com/chromium/src/+/master/docs/optional.md 414*635a8641SAndroid Build Coastguard Worker // 415*635a8641SAndroid Build Coastguard Worker // These are the differences between the specification and the implementation: 416*635a8641SAndroid Build Coastguard Worker // - Constructors do not use 'constexpr' as it is a C++14 extension. 417*635a8641SAndroid Build Coastguard Worker // - 'constexpr' might be missing in some places for reasons specified locally. 418*635a8641SAndroid Build Coastguard Worker // - No exceptions are thrown, because they are banned from Chromium. 419*635a8641SAndroid Build Coastguard Worker // Marked noexcept for only move constructor and move assign operators. 420*635a8641SAndroid Build Coastguard Worker // - All the non-members are in the 'base' namespace instead of 'std'. 421*635a8641SAndroid Build Coastguard Worker // 422*635a8641SAndroid Build Coastguard Worker // Note that T cannot have a constructor T(Optional<T>) etc. Optional<T> checks 423*635a8641SAndroid Build Coastguard Worker // T's constructor (specifically via IsConvertibleFromOptional), and in the 424*635a8641SAndroid Build Coastguard Worker // check whether T can be constructible from Optional<T>, which is recursive 425*635a8641SAndroid Build Coastguard Worker // so it does not work. As of Feb 2018, std::optional C++17 implementation in 426*635a8641SAndroid Build Coastguard Worker // both clang and gcc has same limitation. MSVC SFINAE looks to have different 427*635a8641SAndroid Build Coastguard Worker // behavior, but anyway it reports an error, too. 428*635a8641SAndroid Build Coastguard Worker template <typename T> 429*635a8641SAndroid Build Coastguard Worker class OPTIONAL_DECLSPEC_EMPTY_BASES Optional 430*635a8641SAndroid Build Coastguard Worker : public internal::OptionalBase<T>, 431*635a8641SAndroid Build Coastguard Worker public internal::CopyConstructible<std::is_copy_constructible<T>::value>, 432*635a8641SAndroid Build Coastguard Worker public internal::MoveConstructible<std::is_move_constructible<T>::value>, 433*635a8641SAndroid Build Coastguard Worker public internal::CopyAssignable<std::is_copy_constructible<T>::value && 434*635a8641SAndroid Build Coastguard Worker std::is_copy_assignable<T>::value>, 435*635a8641SAndroid Build Coastguard Worker public internal::MoveAssignable<std::is_move_constructible<T>::value && 436*635a8641SAndroid Build Coastguard Worker std::is_move_assignable<T>::value> { 437*635a8641SAndroid Build Coastguard Worker public: 438*635a8641SAndroid Build Coastguard Worker #undef OPTIONAL_DECLSPEC_EMPTY_BASES 439*635a8641SAndroid Build Coastguard Worker using value_type = T; 440*635a8641SAndroid Build Coastguard Worker 441*635a8641SAndroid Build Coastguard Worker // Defer default/copy/move constructor implementation to OptionalBase. 442*635a8641SAndroid Build Coastguard Worker constexpr Optional() = default; 443*635a8641SAndroid Build Coastguard Worker constexpr Optional(const Optional& other) = default; 444*635a8641SAndroid Build Coastguard Worker constexpr Optional(Optional&& other) noexcept( 445*635a8641SAndroid Build Coastguard Worker std::is_nothrow_move_constructible<T>::value) = default; 446*635a8641SAndroid Build Coastguard Worker 447*635a8641SAndroid Build Coastguard Worker constexpr Optional(nullopt_t) {} // NOLINT(runtime/explicit) 448*635a8641SAndroid Build Coastguard Worker 449*635a8641SAndroid Build Coastguard Worker // Converting copy constructor. "explicit" only if 450*635a8641SAndroid Build Coastguard Worker // std::is_convertible<const U&, T>::value is false. It is implemented by 451*635a8641SAndroid Build Coastguard Worker // declaring two almost same constructors, but that condition in enable_if_t 452*635a8641SAndroid Build Coastguard Worker // is different, so that either one is chosen, thanks to SFINAE. 453*635a8641SAndroid Build Coastguard Worker template < 454*635a8641SAndroid Build Coastguard Worker typename U, 455*635a8641SAndroid Build Coastguard Worker std::enable_if_t<std::is_constructible<T, const U&>::value && 456*635a8641SAndroid Build Coastguard Worker !internal::IsConvertibleFromOptional<T, U>::value && 457*635a8641SAndroid Build Coastguard Worker std::is_convertible<const U&, T>::value, 458*635a8641SAndroid Build Coastguard Worker bool> = false> 459*635a8641SAndroid Build Coastguard Worker Optional(const Optional<U>& other) : internal::OptionalBase<T>(other) {} 460*635a8641SAndroid Build Coastguard Worker 461*635a8641SAndroid Build Coastguard Worker template < 462*635a8641SAndroid Build Coastguard Worker typename U, 463*635a8641SAndroid Build Coastguard Worker std::enable_if_t<std::is_constructible<T, const U&>::value && 464*635a8641SAndroid Build Coastguard Worker !internal::IsConvertibleFromOptional<T, U>::value && 465*635a8641SAndroid Build Coastguard Worker !std::is_convertible<const U&, T>::value, 466*635a8641SAndroid Build Coastguard Worker bool> = false> 467*635a8641SAndroid Build Coastguard Worker explicit Optional(const Optional<U>& other) 468*635a8641SAndroid Build Coastguard Worker : internal::OptionalBase<T>(other) {} 469*635a8641SAndroid Build Coastguard Worker 470*635a8641SAndroid Build Coastguard Worker // Converting move constructor. Similar to converting copy constructor, 471*635a8641SAndroid Build Coastguard Worker // declaring two (explicit and non-explicit) constructors. 472*635a8641SAndroid Build Coastguard Worker template < 473*635a8641SAndroid Build Coastguard Worker typename U, 474*635a8641SAndroid Build Coastguard Worker std::enable_if_t<std::is_constructible<T, U&&>::value && 475*635a8641SAndroid Build Coastguard Worker !internal::IsConvertibleFromOptional<T, U>::value && 476*635a8641SAndroid Build Coastguard Worker std::is_convertible<U&&, T>::value, 477*635a8641SAndroid Build Coastguard Worker bool> = false> 478*635a8641SAndroid Build Coastguard Worker Optional(Optional<U>&& other) : internal::OptionalBase<T>(std::move(other)) {} 479*635a8641SAndroid Build Coastguard Worker 480*635a8641SAndroid Build Coastguard Worker template < 481*635a8641SAndroid Build Coastguard Worker typename U, 482*635a8641SAndroid Build Coastguard Worker std::enable_if_t<std::is_constructible<T, U&&>::value && 483*635a8641SAndroid Build Coastguard Worker !internal::IsConvertibleFromOptional<T, U>::value && 484*635a8641SAndroid Build Coastguard Worker !std::is_convertible<U&&, T>::value, 485*635a8641SAndroid Build Coastguard Worker bool> = false> 486*635a8641SAndroid Build Coastguard Worker explicit Optional(Optional<U>&& other) 487*635a8641SAndroid Build Coastguard Worker : internal::OptionalBase<T>(std::move(other)) {} 488*635a8641SAndroid Build Coastguard Worker 489*635a8641SAndroid Build Coastguard Worker template <class... Args> 490*635a8641SAndroid Build Coastguard Worker constexpr explicit Optional(in_place_t, Args&&... args) 491*635a8641SAndroid Build Coastguard Worker : internal::OptionalBase<T>(in_place, std::forward<Args>(args)...) {} 492*635a8641SAndroid Build Coastguard Worker 493*635a8641SAndroid Build Coastguard Worker template < 494*635a8641SAndroid Build Coastguard Worker class U, 495*635a8641SAndroid Build Coastguard Worker class... Args, 496*635a8641SAndroid Build Coastguard Worker class = std::enable_if_t<std::is_constructible<value_type, 497*635a8641SAndroid Build Coastguard Worker std::initializer_list<U>&, 498*635a8641SAndroid Build Coastguard Worker Args...>::value>> 499*635a8641SAndroid Build Coastguard Worker constexpr explicit Optional(in_place_t, 500*635a8641SAndroid Build Coastguard Worker std::initializer_list<U> il, 501*635a8641SAndroid Build Coastguard Worker Args&&... args) 502*635a8641SAndroid Build Coastguard Worker : internal::OptionalBase<T>(in_place, il, std::forward<Args>(args)...) {} 503*635a8641SAndroid Build Coastguard Worker 504*635a8641SAndroid Build Coastguard Worker // Forward value constructor. Similar to converting constructors, 505*635a8641SAndroid Build Coastguard Worker // conditionally explicit. 506*635a8641SAndroid Build Coastguard Worker template < 507*635a8641SAndroid Build Coastguard Worker typename U = value_type, 508*635a8641SAndroid Build Coastguard Worker std::enable_if_t< 509*635a8641SAndroid Build Coastguard Worker std::is_constructible<T, U&&>::value && 510*635a8641SAndroid Build Coastguard Worker !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value && 511*635a8641SAndroid Build Coastguard Worker !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value && 512*635a8641SAndroid Build Coastguard Worker std::is_convertible<U&&, T>::value, 513*635a8641SAndroid Build Coastguard Worker bool> = false> 514*635a8641SAndroid Build Coastguard Worker constexpr Optional(U&& value) 515*635a8641SAndroid Build Coastguard Worker : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {} 516*635a8641SAndroid Build Coastguard Worker 517*635a8641SAndroid Build Coastguard Worker template < 518*635a8641SAndroid Build Coastguard Worker typename U = value_type, 519*635a8641SAndroid Build Coastguard Worker std::enable_if_t< 520*635a8641SAndroid Build Coastguard Worker std::is_constructible<T, U&&>::value && 521*635a8641SAndroid Build Coastguard Worker !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value && 522*635a8641SAndroid Build Coastguard Worker !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value && 523*635a8641SAndroid Build Coastguard Worker !std::is_convertible<U&&, T>::value, 524*635a8641SAndroid Build Coastguard Worker bool> = false> 525*635a8641SAndroid Build Coastguard Worker constexpr explicit Optional(U&& value) 526*635a8641SAndroid Build Coastguard Worker : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {} 527*635a8641SAndroid Build Coastguard Worker 528*635a8641SAndroid Build Coastguard Worker ~Optional() = default; 529*635a8641SAndroid Build Coastguard Worker 530*635a8641SAndroid Build Coastguard Worker // Defer copy-/move- assign operator implementation to OptionalBase. 531*635a8641SAndroid Build Coastguard Worker Optional& operator=(const Optional& other) = default; 532*635a8641SAndroid Build Coastguard Worker Optional& operator=(Optional&& other) noexcept( 533*635a8641SAndroid Build Coastguard Worker std::is_nothrow_move_assignable<T>::value&& 534*635a8641SAndroid Build Coastguard Worker std::is_nothrow_move_constructible<T>::value) = default; 535*635a8641SAndroid Build Coastguard Worker 536*635a8641SAndroid Build Coastguard Worker Optional& operator=(nullopt_t) { 537*635a8641SAndroid Build Coastguard Worker FreeIfNeeded(); 538*635a8641SAndroid Build Coastguard Worker return *this; 539*635a8641SAndroid Build Coastguard Worker } 540*635a8641SAndroid Build Coastguard Worker 541*635a8641SAndroid Build Coastguard Worker // Perfect-forwarded assignment. 542*635a8641SAndroid Build Coastguard Worker template <typename U> 543*635a8641SAndroid Build Coastguard Worker std::enable_if_t< 544*635a8641SAndroid Build Coastguard Worker !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value && 545*635a8641SAndroid Build Coastguard Worker std::is_constructible<T, U>::value && 546*635a8641SAndroid Build Coastguard Worker std::is_assignable<T&, U>::value && 547*635a8641SAndroid Build Coastguard Worker (!std::is_scalar<T>::value || 548*635a8641SAndroid Build Coastguard Worker !std::is_same<std::decay_t<U>, T>::value), 549*635a8641SAndroid Build Coastguard Worker Optional&> 550*635a8641SAndroid Build Coastguard Worker operator=(U&& value) { 551*635a8641SAndroid Build Coastguard Worker InitOrAssign(std::forward<U>(value)); 552*635a8641SAndroid Build Coastguard Worker return *this; 553*635a8641SAndroid Build Coastguard Worker } 554*635a8641SAndroid Build Coastguard Worker 555*635a8641SAndroid Build Coastguard Worker // Copy assign the state of other. 556*635a8641SAndroid Build Coastguard Worker template <typename U> 557*635a8641SAndroid Build Coastguard Worker std::enable_if_t<!internal::IsAssignableFromOptional<T, U>::value && 558*635a8641SAndroid Build Coastguard Worker std::is_constructible<T, const U&>::value && 559*635a8641SAndroid Build Coastguard Worker std::is_assignable<T&, const U&>::value, 560*635a8641SAndroid Build Coastguard Worker Optional&> 561*635a8641SAndroid Build Coastguard Worker operator=(const Optional<U>& other) { 562*635a8641SAndroid Build Coastguard Worker CopyAssign(other); 563*635a8641SAndroid Build Coastguard Worker return *this; 564*635a8641SAndroid Build Coastguard Worker } 565*635a8641SAndroid Build Coastguard Worker 566*635a8641SAndroid Build Coastguard Worker // Move assign the state of other. 567*635a8641SAndroid Build Coastguard Worker template <typename U> 568*635a8641SAndroid Build Coastguard Worker std::enable_if_t<!internal::IsAssignableFromOptional<T, U>::value && 569*635a8641SAndroid Build Coastguard Worker std::is_constructible<T, U>::value && 570*635a8641SAndroid Build Coastguard Worker std::is_assignable<T&, U>::value, 571*635a8641SAndroid Build Coastguard Worker Optional&> 572*635a8641SAndroid Build Coastguard Worker operator=(Optional<U>&& other) { 573*635a8641SAndroid Build Coastguard Worker MoveAssign(std::move(other)); 574*635a8641SAndroid Build Coastguard Worker return *this; 575*635a8641SAndroid Build Coastguard Worker } 576*635a8641SAndroid Build Coastguard Worker 577*635a8641SAndroid Build Coastguard Worker constexpr const T* operator->() const { 578*635a8641SAndroid Build Coastguard Worker DCHECK(storage_.is_populated_); 579*635a8641SAndroid Build Coastguard Worker return &storage_.value_; 580*635a8641SAndroid Build Coastguard Worker } 581*635a8641SAndroid Build Coastguard Worker 582*635a8641SAndroid Build Coastguard Worker constexpr T* operator->() { 583*635a8641SAndroid Build Coastguard Worker DCHECK(storage_.is_populated_); 584*635a8641SAndroid Build Coastguard Worker return &storage_.value_; 585*635a8641SAndroid Build Coastguard Worker } 586*635a8641SAndroid Build Coastguard Worker 587*635a8641SAndroid Build Coastguard Worker constexpr const T& operator*() const & { 588*635a8641SAndroid Build Coastguard Worker DCHECK(storage_.is_populated_); 589*635a8641SAndroid Build Coastguard Worker return storage_.value_; 590*635a8641SAndroid Build Coastguard Worker } 591*635a8641SAndroid Build Coastguard Worker 592*635a8641SAndroid Build Coastguard Worker constexpr T& operator*() & { 593*635a8641SAndroid Build Coastguard Worker DCHECK(storage_.is_populated_); 594*635a8641SAndroid Build Coastguard Worker return storage_.value_; 595*635a8641SAndroid Build Coastguard Worker } 596*635a8641SAndroid Build Coastguard Worker 597*635a8641SAndroid Build Coastguard Worker constexpr const T&& operator*() const && { 598*635a8641SAndroid Build Coastguard Worker DCHECK(storage_.is_populated_); 599*635a8641SAndroid Build Coastguard Worker return std::move(storage_.value_); 600*635a8641SAndroid Build Coastguard Worker } 601*635a8641SAndroid Build Coastguard Worker 602*635a8641SAndroid Build Coastguard Worker constexpr T&& operator*() && { 603*635a8641SAndroid Build Coastguard Worker DCHECK(storage_.is_populated_); 604*635a8641SAndroid Build Coastguard Worker return std::move(storage_.value_); 605*635a8641SAndroid Build Coastguard Worker } 606*635a8641SAndroid Build Coastguard Worker 607*635a8641SAndroid Build Coastguard Worker constexpr explicit operator bool() const { return storage_.is_populated_; } 608*635a8641SAndroid Build Coastguard Worker 609*635a8641SAndroid Build Coastguard Worker constexpr bool has_value() const { return storage_.is_populated_; } 610*635a8641SAndroid Build Coastguard Worker 611*635a8641SAndroid Build Coastguard Worker constexpr T& value() & { 612*635a8641SAndroid Build Coastguard Worker CHECK(storage_.is_populated_); 613*635a8641SAndroid Build Coastguard Worker return storage_.value_; 614*635a8641SAndroid Build Coastguard Worker } 615*635a8641SAndroid Build Coastguard Worker 616*635a8641SAndroid Build Coastguard Worker constexpr const T& value() const & { 617*635a8641SAndroid Build Coastguard Worker CHECK(storage_.is_populated_); 618*635a8641SAndroid Build Coastguard Worker return storage_.value_; 619*635a8641SAndroid Build Coastguard Worker } 620*635a8641SAndroid Build Coastguard Worker 621*635a8641SAndroid Build Coastguard Worker constexpr T&& value() && { 622*635a8641SAndroid Build Coastguard Worker CHECK(storage_.is_populated_); 623*635a8641SAndroid Build Coastguard Worker return std::move(storage_.value_); 624*635a8641SAndroid Build Coastguard Worker } 625*635a8641SAndroid Build Coastguard Worker 626*635a8641SAndroid Build Coastguard Worker constexpr const T&& value() const && { 627*635a8641SAndroid Build Coastguard Worker CHECK(storage_.is_populated_); 628*635a8641SAndroid Build Coastguard Worker return std::move(storage_.value_); 629*635a8641SAndroid Build Coastguard Worker } 630*635a8641SAndroid Build Coastguard Worker 631*635a8641SAndroid Build Coastguard Worker template <class U> 632*635a8641SAndroid Build Coastguard Worker constexpr T value_or(U&& default_value) const& { 633*635a8641SAndroid Build Coastguard Worker // TODO(mlamouri): add the following assert when possible: 634*635a8641SAndroid Build Coastguard Worker // static_assert(std::is_copy_constructible<T>::value, 635*635a8641SAndroid Build Coastguard Worker // "T must be copy constructible"); 636*635a8641SAndroid Build Coastguard Worker static_assert(std::is_convertible<U, T>::value, 637*635a8641SAndroid Build Coastguard Worker "U must be convertible to T"); 638*635a8641SAndroid Build Coastguard Worker return storage_.is_populated_ 639*635a8641SAndroid Build Coastguard Worker ? storage_.value_ 640*635a8641SAndroid Build Coastguard Worker : static_cast<T>(std::forward<U>(default_value)); 641*635a8641SAndroid Build Coastguard Worker } 642*635a8641SAndroid Build Coastguard Worker 643*635a8641SAndroid Build Coastguard Worker template <class U> 644*635a8641SAndroid Build Coastguard Worker constexpr T value_or(U&& default_value) && { 645*635a8641SAndroid Build Coastguard Worker // TODO(mlamouri): add the following assert when possible: 646*635a8641SAndroid Build Coastguard Worker // static_assert(std::is_move_constructible<T>::value, 647*635a8641SAndroid Build Coastguard Worker // "T must be move constructible"); 648*635a8641SAndroid Build Coastguard Worker static_assert(std::is_convertible<U, T>::value, 649*635a8641SAndroid Build Coastguard Worker "U must be convertible to T"); 650*635a8641SAndroid Build Coastguard Worker return storage_.is_populated_ 651*635a8641SAndroid Build Coastguard Worker ? std::move(storage_.value_) 652*635a8641SAndroid Build Coastguard Worker : static_cast<T>(std::forward<U>(default_value)); 653*635a8641SAndroid Build Coastguard Worker } 654*635a8641SAndroid Build Coastguard Worker 655*635a8641SAndroid Build Coastguard Worker void swap(Optional& other) { 656*635a8641SAndroid Build Coastguard Worker if (!storage_.is_populated_ && !other.storage_.is_populated_) 657*635a8641SAndroid Build Coastguard Worker return; 658*635a8641SAndroid Build Coastguard Worker 659*635a8641SAndroid Build Coastguard Worker if (storage_.is_populated_ != other.storage_.is_populated_) { 660*635a8641SAndroid Build Coastguard Worker if (storage_.is_populated_) { 661*635a8641SAndroid Build Coastguard Worker other.storage_.Init(std::move(storage_.value_)); 662*635a8641SAndroid Build Coastguard Worker FreeIfNeeded(); 663*635a8641SAndroid Build Coastguard Worker } else { 664*635a8641SAndroid Build Coastguard Worker storage_.Init(std::move(other.storage_.value_)); 665*635a8641SAndroid Build Coastguard Worker other.FreeIfNeeded(); 666*635a8641SAndroid Build Coastguard Worker } 667*635a8641SAndroid Build Coastguard Worker return; 668*635a8641SAndroid Build Coastguard Worker } 669*635a8641SAndroid Build Coastguard Worker 670*635a8641SAndroid Build Coastguard Worker DCHECK(storage_.is_populated_ && other.storage_.is_populated_); 671*635a8641SAndroid Build Coastguard Worker using std::swap; 672*635a8641SAndroid Build Coastguard Worker swap(**this, *other); 673*635a8641SAndroid Build Coastguard Worker } 674*635a8641SAndroid Build Coastguard Worker 675*635a8641SAndroid Build Coastguard Worker void reset() { FreeIfNeeded(); } 676*635a8641SAndroid Build Coastguard Worker 677*635a8641SAndroid Build Coastguard Worker template <class... Args> 678*635a8641SAndroid Build Coastguard Worker T& emplace(Args&&... args) { 679*635a8641SAndroid Build Coastguard Worker FreeIfNeeded(); 680*635a8641SAndroid Build Coastguard Worker storage_.Init(std::forward<Args>(args)...); 681*635a8641SAndroid Build Coastguard Worker return storage_.value_; 682*635a8641SAndroid Build Coastguard Worker } 683*635a8641SAndroid Build Coastguard Worker 684*635a8641SAndroid Build Coastguard Worker template <class U, class... Args> 685*635a8641SAndroid Build Coastguard Worker std::enable_if_t< 686*635a8641SAndroid Build Coastguard Worker std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value, 687*635a8641SAndroid Build Coastguard Worker T&> 688*635a8641SAndroid Build Coastguard Worker emplace(std::initializer_list<U> il, Args&&... args) { 689*635a8641SAndroid Build Coastguard Worker FreeIfNeeded(); 690*635a8641SAndroid Build Coastguard Worker storage_.Init(il, std::forward<Args>(args)...); 691*635a8641SAndroid Build Coastguard Worker return storage_.value_; 692*635a8641SAndroid Build Coastguard Worker } 693*635a8641SAndroid Build Coastguard Worker 694*635a8641SAndroid Build Coastguard Worker private: 695*635a8641SAndroid Build Coastguard Worker // Accessing template base class's protected member needs explicit 696*635a8641SAndroid Build Coastguard Worker // declaration to do so. 697*635a8641SAndroid Build Coastguard Worker using internal::OptionalBase<T>::CopyAssign; 698*635a8641SAndroid Build Coastguard Worker using internal::OptionalBase<T>::FreeIfNeeded; 699*635a8641SAndroid Build Coastguard Worker using internal::OptionalBase<T>::InitOrAssign; 700*635a8641SAndroid Build Coastguard Worker using internal::OptionalBase<T>::MoveAssign; 701*635a8641SAndroid Build Coastguard Worker using internal::OptionalBase<T>::storage_; 702*635a8641SAndroid Build Coastguard Worker }; 703*635a8641SAndroid Build Coastguard Worker 704*635a8641SAndroid Build Coastguard Worker // Here after defines comparation operators. The definition follows 705*635a8641SAndroid Build Coastguard Worker // http://en.cppreference.com/w/cpp/utility/optional/operator_cmp 706*635a8641SAndroid Build Coastguard Worker // while bool() casting is replaced by has_value() to meet the chromium 707*635a8641SAndroid Build Coastguard Worker // style guide. 708*635a8641SAndroid Build Coastguard Worker template <class T, class U> 709*635a8641SAndroid Build Coastguard Worker constexpr bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) { 710*635a8641SAndroid Build Coastguard Worker if (lhs.has_value() != rhs.has_value()) 711*635a8641SAndroid Build Coastguard Worker return false; 712*635a8641SAndroid Build Coastguard Worker if (!lhs.has_value()) 713*635a8641SAndroid Build Coastguard Worker return true; 714*635a8641SAndroid Build Coastguard Worker return *lhs == *rhs; 715*635a8641SAndroid Build Coastguard Worker } 716*635a8641SAndroid Build Coastguard Worker 717*635a8641SAndroid Build Coastguard Worker template <class T, class U> 718*635a8641SAndroid Build Coastguard Worker constexpr bool operator!=(const Optional<T>& lhs, const Optional<U>& rhs) { 719*635a8641SAndroid Build Coastguard Worker if (lhs.has_value() != rhs.has_value()) 720*635a8641SAndroid Build Coastguard Worker return true; 721*635a8641SAndroid Build Coastguard Worker if (!lhs.has_value()) 722*635a8641SAndroid Build Coastguard Worker return false; 723*635a8641SAndroid Build Coastguard Worker return *lhs != *rhs; 724*635a8641SAndroid Build Coastguard Worker } 725*635a8641SAndroid Build Coastguard Worker 726*635a8641SAndroid Build Coastguard Worker template <class T, class U> 727*635a8641SAndroid Build Coastguard Worker constexpr bool operator<(const Optional<T>& lhs, const Optional<U>& rhs) { 728*635a8641SAndroid Build Coastguard Worker if (!rhs.has_value()) 729*635a8641SAndroid Build Coastguard Worker return false; 730*635a8641SAndroid Build Coastguard Worker if (!lhs.has_value()) 731*635a8641SAndroid Build Coastguard Worker return true; 732*635a8641SAndroid Build Coastguard Worker return *lhs < *rhs; 733*635a8641SAndroid Build Coastguard Worker } 734*635a8641SAndroid Build Coastguard Worker 735*635a8641SAndroid Build Coastguard Worker template <class T, class U> 736*635a8641SAndroid Build Coastguard Worker constexpr bool operator<=(const Optional<T>& lhs, const Optional<U>& rhs) { 737*635a8641SAndroid Build Coastguard Worker if (!lhs.has_value()) 738*635a8641SAndroid Build Coastguard Worker return true; 739*635a8641SAndroid Build Coastguard Worker if (!rhs.has_value()) 740*635a8641SAndroid Build Coastguard Worker return false; 741*635a8641SAndroid Build Coastguard Worker return *lhs <= *rhs; 742*635a8641SAndroid Build Coastguard Worker } 743*635a8641SAndroid Build Coastguard Worker 744*635a8641SAndroid Build Coastguard Worker template <class T, class U> 745*635a8641SAndroid Build Coastguard Worker constexpr bool operator>(const Optional<T>& lhs, const Optional<U>& rhs) { 746*635a8641SAndroid Build Coastguard Worker if (!lhs.has_value()) 747*635a8641SAndroid Build Coastguard Worker return false; 748*635a8641SAndroid Build Coastguard Worker if (!rhs.has_value()) 749*635a8641SAndroid Build Coastguard Worker return true; 750*635a8641SAndroid Build Coastguard Worker return *lhs > *rhs; 751*635a8641SAndroid Build Coastguard Worker } 752*635a8641SAndroid Build Coastguard Worker 753*635a8641SAndroid Build Coastguard Worker template <class T, class U> 754*635a8641SAndroid Build Coastguard Worker constexpr bool operator>=(const Optional<T>& lhs, const Optional<U>& rhs) { 755*635a8641SAndroid Build Coastguard Worker if (!rhs.has_value()) 756*635a8641SAndroid Build Coastguard Worker return true; 757*635a8641SAndroid Build Coastguard Worker if (!lhs.has_value()) 758*635a8641SAndroid Build Coastguard Worker return false; 759*635a8641SAndroid Build Coastguard Worker return *lhs >= *rhs; 760*635a8641SAndroid Build Coastguard Worker } 761*635a8641SAndroid Build Coastguard Worker 762*635a8641SAndroid Build Coastguard Worker template <class T> 763*635a8641SAndroid Build Coastguard Worker constexpr bool operator==(const Optional<T>& opt, nullopt_t) { 764*635a8641SAndroid Build Coastguard Worker return !opt; 765*635a8641SAndroid Build Coastguard Worker } 766*635a8641SAndroid Build Coastguard Worker 767*635a8641SAndroid Build Coastguard Worker template <class T> 768*635a8641SAndroid Build Coastguard Worker constexpr bool operator==(nullopt_t, const Optional<T>& opt) { 769*635a8641SAndroid Build Coastguard Worker return !opt; 770*635a8641SAndroid Build Coastguard Worker } 771*635a8641SAndroid Build Coastguard Worker 772*635a8641SAndroid Build Coastguard Worker template <class T> 773*635a8641SAndroid Build Coastguard Worker constexpr bool operator!=(const Optional<T>& opt, nullopt_t) { 774*635a8641SAndroid Build Coastguard Worker return opt.has_value(); 775*635a8641SAndroid Build Coastguard Worker } 776*635a8641SAndroid Build Coastguard Worker 777*635a8641SAndroid Build Coastguard Worker template <class T> 778*635a8641SAndroid Build Coastguard Worker constexpr bool operator!=(nullopt_t, const Optional<T>& opt) { 779*635a8641SAndroid Build Coastguard Worker return opt.has_value(); 780*635a8641SAndroid Build Coastguard Worker } 781*635a8641SAndroid Build Coastguard Worker 782*635a8641SAndroid Build Coastguard Worker template <class T> 783*635a8641SAndroid Build Coastguard Worker constexpr bool operator<(const Optional<T>& opt, nullopt_t) { 784*635a8641SAndroid Build Coastguard Worker return false; 785*635a8641SAndroid Build Coastguard Worker } 786*635a8641SAndroid Build Coastguard Worker 787*635a8641SAndroid Build Coastguard Worker template <class T> 788*635a8641SAndroid Build Coastguard Worker constexpr bool operator<(nullopt_t, const Optional<T>& opt) { 789*635a8641SAndroid Build Coastguard Worker return opt.has_value(); 790*635a8641SAndroid Build Coastguard Worker } 791*635a8641SAndroid Build Coastguard Worker 792*635a8641SAndroid Build Coastguard Worker template <class T> 793*635a8641SAndroid Build Coastguard Worker constexpr bool operator<=(const Optional<T>& opt, nullopt_t) { 794*635a8641SAndroid Build Coastguard Worker return !opt; 795*635a8641SAndroid Build Coastguard Worker } 796*635a8641SAndroid Build Coastguard Worker 797*635a8641SAndroid Build Coastguard Worker template <class T> 798*635a8641SAndroid Build Coastguard Worker constexpr bool operator<=(nullopt_t, const Optional<T>& opt) { 799*635a8641SAndroid Build Coastguard Worker return true; 800*635a8641SAndroid Build Coastguard Worker } 801*635a8641SAndroid Build Coastguard Worker 802*635a8641SAndroid Build Coastguard Worker template <class T> 803*635a8641SAndroid Build Coastguard Worker constexpr bool operator>(const Optional<T>& opt, nullopt_t) { 804*635a8641SAndroid Build Coastguard Worker return opt.has_value(); 805*635a8641SAndroid Build Coastguard Worker } 806*635a8641SAndroid Build Coastguard Worker 807*635a8641SAndroid Build Coastguard Worker template <class T> 808*635a8641SAndroid Build Coastguard Worker constexpr bool operator>(nullopt_t, const Optional<T>& opt) { 809*635a8641SAndroid Build Coastguard Worker return false; 810*635a8641SAndroid Build Coastguard Worker } 811*635a8641SAndroid Build Coastguard Worker 812*635a8641SAndroid Build Coastguard Worker template <class T> 813*635a8641SAndroid Build Coastguard Worker constexpr bool operator>=(const Optional<T>& opt, nullopt_t) { 814*635a8641SAndroid Build Coastguard Worker return true; 815*635a8641SAndroid Build Coastguard Worker } 816*635a8641SAndroid Build Coastguard Worker 817*635a8641SAndroid Build Coastguard Worker template <class T> 818*635a8641SAndroid Build Coastguard Worker constexpr bool operator>=(nullopt_t, const Optional<T>& opt) { 819*635a8641SAndroid Build Coastguard Worker return !opt; 820*635a8641SAndroid Build Coastguard Worker } 821*635a8641SAndroid Build Coastguard Worker 822*635a8641SAndroid Build Coastguard Worker template <class T, class U> 823*635a8641SAndroid Build Coastguard Worker constexpr bool operator==(const Optional<T>& opt, const U& value) { 824*635a8641SAndroid Build Coastguard Worker return opt.has_value() ? *opt == value : false; 825*635a8641SAndroid Build Coastguard Worker } 826*635a8641SAndroid Build Coastguard Worker 827*635a8641SAndroid Build Coastguard Worker template <class T, class U> 828*635a8641SAndroid Build Coastguard Worker constexpr bool operator==(const U& value, const Optional<T>& opt) { 829*635a8641SAndroid Build Coastguard Worker return opt.has_value() ? value == *opt : false; 830*635a8641SAndroid Build Coastguard Worker } 831*635a8641SAndroid Build Coastguard Worker 832*635a8641SAndroid Build Coastguard Worker template <class T, class U> 833*635a8641SAndroid Build Coastguard Worker constexpr bool operator!=(const Optional<T>& opt, const U& value) { 834*635a8641SAndroid Build Coastguard Worker return opt.has_value() ? *opt != value : true; 835*635a8641SAndroid Build Coastguard Worker } 836*635a8641SAndroid Build Coastguard Worker 837*635a8641SAndroid Build Coastguard Worker template <class T, class U> 838*635a8641SAndroid Build Coastguard Worker constexpr bool operator!=(const U& value, const Optional<T>& opt) { 839*635a8641SAndroid Build Coastguard Worker return opt.has_value() ? value != *opt : true; 840*635a8641SAndroid Build Coastguard Worker } 841*635a8641SAndroid Build Coastguard Worker 842*635a8641SAndroid Build Coastguard Worker template <class T, class U> 843*635a8641SAndroid Build Coastguard Worker constexpr bool operator<(const Optional<T>& opt, const U& value) { 844*635a8641SAndroid Build Coastguard Worker return opt.has_value() ? *opt < value : true; 845*635a8641SAndroid Build Coastguard Worker } 846*635a8641SAndroid Build Coastguard Worker 847*635a8641SAndroid Build Coastguard Worker template <class T, class U> 848*635a8641SAndroid Build Coastguard Worker constexpr bool operator<(const U& value, const Optional<T>& opt) { 849*635a8641SAndroid Build Coastguard Worker return opt.has_value() ? value < *opt : false; 850*635a8641SAndroid Build Coastguard Worker } 851*635a8641SAndroid Build Coastguard Worker 852*635a8641SAndroid Build Coastguard Worker template <class T, class U> 853*635a8641SAndroid Build Coastguard Worker constexpr bool operator<=(const Optional<T>& opt, const U& value) { 854*635a8641SAndroid Build Coastguard Worker return opt.has_value() ? *opt <= value : true; 855*635a8641SAndroid Build Coastguard Worker } 856*635a8641SAndroid Build Coastguard Worker 857*635a8641SAndroid Build Coastguard Worker template <class T, class U> 858*635a8641SAndroid Build Coastguard Worker constexpr bool operator<=(const U& value, const Optional<T>& opt) { 859*635a8641SAndroid Build Coastguard Worker return opt.has_value() ? value <= *opt : false; 860*635a8641SAndroid Build Coastguard Worker } 861*635a8641SAndroid Build Coastguard Worker 862*635a8641SAndroid Build Coastguard Worker template <class T, class U> 863*635a8641SAndroid Build Coastguard Worker constexpr bool operator>(const Optional<T>& opt, const U& value) { 864*635a8641SAndroid Build Coastguard Worker return opt.has_value() ? *opt > value : false; 865*635a8641SAndroid Build Coastguard Worker } 866*635a8641SAndroid Build Coastguard Worker 867*635a8641SAndroid Build Coastguard Worker template <class T, class U> 868*635a8641SAndroid Build Coastguard Worker constexpr bool operator>(const U& value, const Optional<T>& opt) { 869*635a8641SAndroid Build Coastguard Worker return opt.has_value() ? value > *opt : true; 870*635a8641SAndroid Build Coastguard Worker } 871*635a8641SAndroid Build Coastguard Worker 872*635a8641SAndroid Build Coastguard Worker template <class T, class U> 873*635a8641SAndroid Build Coastguard Worker constexpr bool operator>=(const Optional<T>& opt, const U& value) { 874*635a8641SAndroid Build Coastguard Worker return opt.has_value() ? *opt >= value : false; 875*635a8641SAndroid Build Coastguard Worker } 876*635a8641SAndroid Build Coastguard Worker 877*635a8641SAndroid Build Coastguard Worker template <class T, class U> 878*635a8641SAndroid Build Coastguard Worker constexpr bool operator>=(const U& value, const Optional<T>& opt) { 879*635a8641SAndroid Build Coastguard Worker return opt.has_value() ? value >= *opt : true; 880*635a8641SAndroid Build Coastguard Worker } 881*635a8641SAndroid Build Coastguard Worker 882*635a8641SAndroid Build Coastguard Worker template <class T> 883*635a8641SAndroid Build Coastguard Worker constexpr Optional<std::decay_t<T>> make_optional(T&& value) { 884*635a8641SAndroid Build Coastguard Worker return Optional<std::decay_t<T>>(std::forward<T>(value)); 885*635a8641SAndroid Build Coastguard Worker } 886*635a8641SAndroid Build Coastguard Worker 887*635a8641SAndroid Build Coastguard Worker template <class T, class... Args> 888*635a8641SAndroid Build Coastguard Worker constexpr Optional<T> make_optional(Args&&... args) { 889*635a8641SAndroid Build Coastguard Worker return Optional<T>(in_place, std::forward<Args>(args)...); 890*635a8641SAndroid Build Coastguard Worker } 891*635a8641SAndroid Build Coastguard Worker 892*635a8641SAndroid Build Coastguard Worker template <class T, class U, class... Args> 893*635a8641SAndroid Build Coastguard Worker constexpr Optional<T> make_optional(std::initializer_list<U> il, 894*635a8641SAndroid Build Coastguard Worker Args&&... args) { 895*635a8641SAndroid Build Coastguard Worker return Optional<T>(in_place, il, std::forward<Args>(args)...); 896*635a8641SAndroid Build Coastguard Worker } 897*635a8641SAndroid Build Coastguard Worker 898*635a8641SAndroid Build Coastguard Worker // Partial specialization for a function template is not allowed. Also, it is 899*635a8641SAndroid Build Coastguard Worker // not allowed to add overload function to std namespace, while it is allowed 900*635a8641SAndroid Build Coastguard Worker // to specialize the template in std. Thus, swap() (kind of) overloading is 901*635a8641SAndroid Build Coastguard Worker // defined in base namespace, instead. 902*635a8641SAndroid Build Coastguard Worker template <class T> 903*635a8641SAndroid Build Coastguard Worker std::enable_if_t<std::is_move_constructible<T>::value && 904*635a8641SAndroid Build Coastguard Worker internal::IsSwappable<T>::value> 905*635a8641SAndroid Build Coastguard Worker swap(Optional<T>& lhs, Optional<T>& rhs) { 906*635a8641SAndroid Build Coastguard Worker lhs.swap(rhs); 907*635a8641SAndroid Build Coastguard Worker } 908*635a8641SAndroid Build Coastguard Worker 909*635a8641SAndroid Build Coastguard Worker } // namespace base 910*635a8641SAndroid Build Coastguard Worker 911*635a8641SAndroid Build Coastguard Worker namespace std { 912*635a8641SAndroid Build Coastguard Worker 913*635a8641SAndroid Build Coastguard Worker template <class T> 914*635a8641SAndroid Build Coastguard Worker struct hash<base::Optional<T>> { 915*635a8641SAndroid Build Coastguard Worker size_t operator()(const base::Optional<T>& opt) const { 916*635a8641SAndroid Build Coastguard Worker return opt == base::nullopt ? 0 : std::hash<T>()(*opt); 917*635a8641SAndroid Build Coastguard Worker } 918*635a8641SAndroid Build Coastguard Worker }; 919*635a8641SAndroid Build Coastguard Worker 920*635a8641SAndroid Build Coastguard Worker } // namespace std 921*635a8641SAndroid Build Coastguard Worker 922*635a8641SAndroid Build Coastguard Worker #endif // BASE_OPTIONAL_H_ 923