xref: /aosp_15_r20/external/libchrome/base/optional.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
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