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