Use default std::optional if it is provided
[WebKit-https.git] / Source / WTF / wtf / Optional.h
1 // Copyright (C) 2011 - 2012 Andrzej Krzemienski.
2 //
3 // Use, modification, and distribution is subject to the Boost Software
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // The idea and interface is based on Boost.Optional library
8 // authored by Fernando Luis Cacciola Carballal
9 //
10 // Boost Software License - Version 1.0 - August 17th, 2003
11 //
12 // Permission is hereby granted, free of charge, to any person or organization
13 // obtaining a copy of the software and accompanying documentation covered by
14 // this license (the "Software") to use, reproduce, display, distribute,
15 // execute, and transmit the Software, and to prepare derivative works of the
16 // Software, and to permit third-parties to whom the Software is furnished to
17 // do so, all subject to the following:
18 //
19 // The copyright notices in the Software and this entire statement, including
20 // the above license grant, this restriction and the following disclaimer,
21 // must be included in all copies of the Software, in whole or in part, and
22 // all derivative works of the Software, unless such copies or derivative
23 // works are solely in the form of machine-executable object code generated by
24 // a source language processor.
25 //
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
29 // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
30 // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
31 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32 // DEALINGS IN THE SOFTWARE.
33
34 // Copied from https://github.com/akrzemi1/Optional (8456c3923776b33b4ae852734273fe934c3e4e61)
35
36 // Modified to make it compile with exceptions disabled.
37
38 #pragma once
39
40 # include <utility>
41 # include <type_traits>
42 # include <initializer_list>
43 # include <cassert>
44 # include <string>
45 # include <stdexcept>
46 # include <wtf/Assertions.h>
47 # include <wtf/Compiler.h>
48 # include <wtf/StdLibExtras.h>
49
50 #if !COMPILER(MSVC) && __has_include(<optional>)
51 # include <optional>
52 #endif
53
54 #if !COMPILER(MSVC) && defined(__cpp_lib_optional) && __cpp_lib_optional >= 201603
55
56 // Use default std::optional.
57
58 #else
59
60 # define TR2_OPTIONAL_REQUIRES(...) typename std::enable_if<__VA_ARGS__::value, bool>::type = false
61
62 # if defined __GNUC__ // NOTE: GNUC is also defined for Clang
63 #   if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
64 #     define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
65 #   elif (__GNUC__ > 4)
66 #     define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
67 #   endif
68 #
69 #   if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)
70 #     define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
71 #   elif (__GNUC__ > 4)
72 #     define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
73 #   endif
74 #
75 #   if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) && (__GNUC_PATCHLEVEL__ >= 1)
76 #     define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
77 #   elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)
78 #     define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
79 #   elif (__GNUC__ > 4)
80 #     define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
81 #   endif
82 # endif
83 #
84 # if defined __clang_major__
85 #   if (__clang_major__ == 3 && __clang_minor__ >= 5)
86 #     define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
87 #   elif (__clang_major__ > 3)
88 #     define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
89 #   endif
90 #   if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
91 #     define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
92 #   elif (__clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ >= 2)
93 #     define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
94 #   endif
95 # endif
96 #
97 # if defined _MSC_VER
98 #   if (_MSC_VER >= 1900)
99 #     define TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
100 #   endif
101 # endif
102
103 # if defined __clang__
104 #   if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9)
105 #     define OPTIONAL_HAS_THIS_RVALUE_REFS 1
106 #   else
107 #     define OPTIONAL_HAS_THIS_RVALUE_REFS 0
108 #   endif
109 # elif defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
110 #   define OPTIONAL_HAS_THIS_RVALUE_REFS 1
111 # elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
112 #   define OPTIONAL_HAS_THIS_RVALUE_REFS 1
113 # else
114 #   define OPTIONAL_HAS_THIS_RVALUE_REFS 0
115 # endif
116
117
118 # if defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
119 #   define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 1
120 #   define OPTIONAL_CONSTEXPR_INIT_LIST constexpr
121 # else
122 #   define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 0
123 #   define OPTIONAL_CONSTEXPR_INIT_LIST
124 # endif
125
126 # // In C++11 constexpr implies const, so we need to make non-const members also non-constexpr
127 # if (defined __cplusplus) && (__cplusplus == 201103L)
128 #   define OPTIONAL_MUTABLE_CONSTEXPR
129 # else
130 #   define OPTIONAL_MUTABLE_CONSTEXPR constexpr
131 # endif
132
133 #if COMPILER_SUPPORTS(EXCEPTIONS)
134 #define __THROW_EXCEPTION(__exception) throw __exception;
135 #define __NOEXCEPT noexcept
136 #define __NOEXCEPT_(__exception) noexcept(__exception)
137 #else
138 #define __THROW_EXCEPTION(__exception) do { (void)__exception; CRASH(); } while (0);
139 #define __NOEXCEPT
140 #define __NOEXCEPT_(...)
141 #endif
142
143 namespace std {
144 namespace detail_ {
145
146 // NOTE: All our target compilers support is_trivially_destructible.
147 // // BEGIN workaround for missing is_trivially_destructible
148 // # if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
149 //     // leave it: it is already there
150 // # elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
151 //     // leave it: it is already there
152 // # elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
153 //     // leave it: it is already there
154 // # elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
155 //     // leave it: the user doesn't want it
156 // # else
157 //     template <typename T>
158 //     using is_trivially_destructible = std::has_trivial_destructor<T>;
159 // # endif
160 // // END workaround for missing is_trivially_destructible
161
162 #if COMPILER_SUPPORTS(EXCEPTIONS)
163 # if defined(TR2_OPTIONAL_GCC_4_7_AND_HIGHER___) || defined(TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_) || defined(TR2_OPTIONAL_MSVC_2015_AND_HIGHER___)
164     // leave it; our metafunctions are already defined.
165     template <typename T>
166     using is_nothrow_move_constructible = std::is_nothrow_move_constructible<T>;
167     template <typename T>
168     using is_nothrow_move_assignable = std::is_nothrow_move_assignable<T>;
169 # elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
170     // leave it: the user doesn't want it
171 # else
172
173
174 // workaround for missing traits in GCC and CLANG
175 template <class T>
176 struct is_nothrow_move_constructible
177 {
178   constexpr static bool value = std::is_nothrow_constructible<T, T&&>::value;
179 };
180
181
182 template <class T, class U>
183 struct is_assignable
184 {
185   template <class X, class Y>
186   constexpr static bool has_assign(...) { return false; }
187
188   template <class X, class Y, size_t S = sizeof((std::declval<X>() = std::declval<Y>(), true)) >
189   // the comma operator is necessary for the cases where operator= returns void
190   constexpr static bool has_assign(bool) { return true; }
191
192   constexpr static bool value = has_assign<T, U>(true);
193 };
194
195
196 template <class T>
197 struct is_nothrow_move_assignable
198 {
199   template <class X, bool has_any_move_assign>
200   struct has_nothrow_move_assign {
201     constexpr static bool value = false;
202   };
203
204   template <class X>
205   struct has_nothrow_move_assign<X, true> {
206     constexpr static bool value = __NOEXCEPT_( std::declval<X&>() = std::declval<X&&>() );
207   };
208
209   constexpr static bool value = has_nothrow_move_assign<T, is_assignable<T&, T&&>::value>::value;
210 };
211 // end workaround
212
213
214 # endif
215 #endif
216
217 } // namespace detail_
218
219 // 20.5.4, optional for object types
220 template <class T> class optional;
221
222 // 20.5.5, optional for lvalue reference types
223 template <class T> class optional<T&>;
224
225 namespace detail_ {
226
227 // workaround: std utility functions aren't constexpr yet
228 template <class T> inline constexpr T&& constexpr_forward(typename std::remove_reference<T>::type& t) __NOEXCEPT
229 {
230   return static_cast<T&&>(t);
231 }
232
233 template <class T> inline constexpr T&& constexpr_forward(typename std::remove_reference<T>::type&& t) __NOEXCEPT
234 {
235     static_assert(!std::is_lvalue_reference<T>::value, "!!");
236     return static_cast<T&&>(t);
237 }
238
239 template <class T> inline constexpr typename std::remove_reference<T>::type&& constexpr_move(T&& t) __NOEXCEPT
240 {
241     return static_cast<typename std::remove_reference<T>::type&&>(t);
242 }
243
244 #if defined NDEBUG
245 # define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR)
246 #else
247 # define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) ((CHECK) ? (EXPR) : ([]{assert(!#CHECK);}(), (EXPR)))
248 #endif
249
250
251 // static_addressof: a constexpr version of addressof
252 template <typename T>
253 struct has_overloaded_addressof
254 {
255   template <class X>
256   constexpr static bool has_overload(...) { return false; }
257
258   template <class X, size_t S = sizeof(std::declval<X&>().operator&()) >
259   constexpr static bool has_overload(bool) { return true; }
260
261   constexpr static bool value = has_overload<T>(true);
262 };
263
264 template <typename T, TR2_OPTIONAL_REQUIRES(!has_overloaded_addressof<T>)>
265 constexpr T* static_addressof(T& ref)
266 {
267   return &ref;
268 }
269
270 template <typename T, TR2_OPTIONAL_REQUIRES(has_overloaded_addressof<T>)>
271 T* static_addressof(T& ref)
272 {
273   return std::addressof(ref);
274 }
275
276
277 // the call to convert<A>(b) has return type A and converts b to type A iff b decltype(b) is implicitly convertible to A
278 template <class U>
279 constexpr U convert(U v) { return v; }
280
281 } // namespace detail
282
283
284 constexpr struct trivial_init_t{} trivial_init{};
285
286
287 // 20.5.7, Disengaged state indicator
288 struct nullopt_t
289 {
290   struct init{};
291   constexpr explicit nullopt_t(init){}
292 };
293 constexpr nullopt_t nullopt{nullopt_t::init()};
294
295
296 // 20.5.8, class bad_optional_access
297 class bad_optional_access : public std::logic_error {
298 public:
299   explicit bad_optional_access(const std::string& what_arg) : std::logic_error{what_arg} {}
300   explicit bad_optional_access(const char* what_arg) : std::logic_error{what_arg} {}
301 };
302
303
304 template <class T>
305 union storage_t
306 {
307   unsigned char dummy_;
308   T value_;
309
310   constexpr storage_t( trivial_init_t ) __NOEXCEPT : dummy_() {};
311
312   template <class... Args>
313   constexpr storage_t( Args&&... args ) : value_(detail_::constexpr_forward<Args>(args)...) {}
314
315   ~storage_t(){}
316 };
317
318
319 template <class T>
320 union constexpr_storage_t
321 {
322     unsigned char dummy_;
323     T value_;
324
325     constexpr constexpr_storage_t( trivial_init_t ) __NOEXCEPT : dummy_() {};
326
327     template <class... Args>
328     constexpr constexpr_storage_t( Args&&... args ) : value_(detail_::constexpr_forward<Args>(args)...) {}
329
330     ~constexpr_storage_t() = default;
331 };
332
333
334 template <class T>
335 struct optional_base
336 {
337     bool init_;
338     storage_t<T> storage_;
339
340     constexpr optional_base() __NOEXCEPT : init_(false), storage_(trivial_init) {};
341
342     explicit constexpr optional_base(const T& v) : init_(true), storage_(v) {}
343
344     explicit constexpr optional_base(T&& v) : init_(true), storage_(detail_::constexpr_move(v)) {}
345
346     template <class... Args> explicit optional_base(in_place_t, Args&&... args)
347         : init_(true), storage_(detail_::constexpr_forward<Args>(args)...) {}
348
349     template <class U, class... Args, TR2_OPTIONAL_REQUIRES(std::is_constructible<T, std::initializer_list<U>>)>
350     explicit optional_base(in_place_t, std::initializer_list<U> il, Args&&... args)
351         : init_(true), storage_(il, std::forward<Args>(args)...) {}
352
353     ~optional_base() { if (init_) storage_.value_.T::~T(); }
354 };
355
356
357 template <class T>
358 struct constexpr_optional_base
359 {
360     bool init_;
361     constexpr_storage_t<T> storage_;
362
363     constexpr constexpr_optional_base() __NOEXCEPT : init_(false), storage_(trivial_init) {};
364
365     explicit constexpr constexpr_optional_base(const T& v) : init_(true), storage_(v) {}
366
367     explicit constexpr constexpr_optional_base(T&& v) : init_(true), storage_(detail_::constexpr_move(v)) {}
368
369     template <class... Args> explicit constexpr constexpr_optional_base(in_place_t, Args&&... args)
370       : init_(true), storage_(detail_::constexpr_forward<Args>(args)...) {}
371
372     template <class U, class... Args, TR2_OPTIONAL_REQUIRES(std::is_constructible<T, std::initializer_list<U>>)>
373     OPTIONAL_CONSTEXPR_INIT_LIST explicit constexpr_optional_base(in_place_t, std::initializer_list<U> il, Args&&... args)
374       : init_(true), storage_(il, std::forward<Args>(args)...) {}
375
376     ~constexpr_optional_base() = default;
377 };
378
379 template <class T>
380 using OptionalBase = typename std::conditional<
381     std::is_trivially_destructible<T>::value,                          // if possible
382     constexpr_optional_base<typename std::remove_const<T>::type>, // use base with trivial destructor
383     optional_base<typename std::remove_const<T>::type>
384 >::type;
385
386
387
388 template <class T>
389 class optional : private OptionalBase<T>
390 {
391   static_assert( !std::is_same<typename std::decay<T>::type, nullopt_t>::value, "bad T" );
392   static_assert( !std::is_same<typename std::decay<T>::type, in_place_t>::value, "bad T" );
393
394
395   constexpr bool initialized() const __NOEXCEPT { return OptionalBase<T>::init_; }
396   typename std::remove_const<T>::type* dataptr() {  return std::addressof(OptionalBase<T>::storage_.value_); }
397   constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase<T>::storage_.value_); }
398
399 # if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
400   constexpr const T& contained_val() const& { return OptionalBase<T>::storage_.value_; }
401   OPTIONAL_MUTABLE_CONSTEXPR T&& contained_val() && { return std::move(OptionalBase<T>::storage_.value_); }
402   OPTIONAL_MUTABLE_CONSTEXPR T& contained_val() & { return OptionalBase<T>::storage_.value_; }
403 # else
404   constexpr const T& contained_val() const { return OptionalBase<T>::storage_.value_; }
405   T& contained_val() { return OptionalBase<T>::storage_.value_; }
406 # endif
407
408   void clear() __NOEXCEPT {
409     if (initialized()) dataptr()->T::~T();
410     OptionalBase<T>::init_ = false;
411   }
412
413   template <class... Args>
414   void initialize(Args&&... args) __NOEXCEPT_(__NOEXCEPT_(T(std::forward<Args>(args)...)))
415   {
416     ASSERT(!OptionalBase<T>::init_);
417     ::new (static_cast<void*>(dataptr())) T(std::forward<Args>(args)...);
418     OptionalBase<T>::init_ = true;
419   }
420
421   template <class U, class... Args>
422   void initialize(std::initializer_list<U> il, Args&&... args) __NOEXCEPT_(__NOEXCEPT_(T(il, std::forward<Args>(args)...)))
423   {
424     ASSERT(!OptionalBase<T>::init_);
425     ::new (static_cast<void*>(dataptr())) T(il, std::forward<Args>(args)...);
426     OptionalBase<T>::init_ = true;
427   }
428
429 public:
430   typedef T value_type;
431
432   // 20.5.5.1, constructors
433   constexpr optional() __NOEXCEPT : OptionalBase<T>()  {};
434   constexpr optional(nullopt_t) __NOEXCEPT : OptionalBase<T>() {};
435
436   optional(const optional& rhs)
437   : OptionalBase<T>()
438   {
439     if (rhs.initialized()) {
440         ::new (static_cast<void*>(dataptr())) T(*rhs);
441         OptionalBase<T>::init_ = true;
442     }
443   }
444
445   optional(optional&& rhs) __NOEXCEPT_(detail_::is_nothrow_move_constructible<T>::value)
446   : OptionalBase<T>()
447   {
448     if (rhs.initialized()) {
449         ::new (static_cast<void*>(dataptr())) T(std::move(*rhs));
450         OptionalBase<T>::init_ = true;
451     }
452   }
453
454   constexpr optional(const T& v) : OptionalBase<T>(v) {}
455
456   constexpr optional(T&& v) : OptionalBase<T>(detail_::constexpr_move(v)) {}
457
458   template <class... Args>
459   explicit constexpr optional(in_place_t, Args&&... args)
460   : OptionalBase<T>(in_place_t{}, detail_::constexpr_forward<Args>(args)...) {}
461
462   template <class U, class... Args, TR2_OPTIONAL_REQUIRES(std::is_constructible<T, std::initializer_list<U>>)>
463   OPTIONAL_CONSTEXPR_INIT_LIST explicit optional(in_place_t, std::initializer_list<U> il, Args&&... args)
464   : OptionalBase<T>(in_place_t{}, il, detail_::constexpr_forward<Args>(args)...) {}
465
466   // 20.5.4.2, Destructor
467   ~optional() = default;
468
469   // 20.5.4.3, assignment
470   optional& operator=(nullopt_t) __NOEXCEPT
471   {
472     clear();
473     return *this;
474   }
475
476   optional& operator=(const optional& rhs)
477   {
478     if      (initialized() == true  && rhs.initialized() == false) clear();
479     else if (initialized() == false && rhs.initialized() == true)  initialize(*rhs);
480     else if (initialized() == true  && rhs.initialized() == true)  contained_val() = *rhs;
481     return *this;
482   }
483
484   optional& operator=(optional&& rhs)
485   __NOEXCEPT_(detail_::is_nothrow_move_assignable<T>::value && detail_::is_nothrow_move_constructible<T>::value)
486   {
487     if      (initialized() == true  && rhs.initialized() == false) clear();
488     else if (initialized() == false && rhs.initialized() == true)  initialize(std::move(*rhs));
489     else if (initialized() == true  && rhs.initialized() == true)  contained_val() = std::move(*rhs);
490     return *this;
491   }
492
493   template <class U>
494   auto operator=(U&& v)
495   -> typename std::enable_if
496   <
497     std::is_same<typename std::decay<U>::type, T>::value,
498     optional&
499   >::type
500   {
501     if (initialized()) { contained_val() = std::forward<U>(v); }
502     else               { initialize(std::forward<U>(v));  }
503     return *this;
504   }
505
506
507   template <class... Args>
508   void emplace(Args&&... args)
509   {
510     clear();
511     initialize(std::forward<Args>(args)...);
512   }
513
514   template <class U, class... Args>
515   void emplace(std::initializer_list<U> il, Args&&... args)
516   {
517     clear();
518     initialize<U, Args...>(il, std::forward<Args>(args)...);
519   }
520
521   // 20.5.4.4, Swap
522   void swap(optional<T>& rhs) __NOEXCEPT_(detail_::is_nothrow_move_constructible<T>::value && __NOEXCEPT_(swap(std::declval<T&>(), std::declval<T&>())))
523   {
524     if      (initialized() == true  && rhs.initialized() == false) { rhs.initialize(std::move(**this)); clear(); }
525     else if (initialized() == false && rhs.initialized() == true)  { initialize(std::move(*rhs)); rhs.clear(); }
526     else if (initialized() == true  && rhs.initialized() == true)  { using std::swap; swap(**this, *rhs); }
527   }
528
529   // 20.5.4.5, Observers
530
531   explicit constexpr operator bool() const __NOEXCEPT { return initialized(); }
532   constexpr bool has_value() const __NOEXCEPT { return initialized(); }
533
534   constexpr T const* operator ->() const {
535     return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), dataptr());
536   }
537
538   OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() {
539     // FIXME: We need to offer special assert function that can be used under the contexpr context.
540     // CONSTEXPR_ASSERT(initialized());
541     return dataptr();
542   }
543
544   constexpr T const& operator *() const& {
545     return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
546   }
547
548   OPTIONAL_MUTABLE_CONSTEXPR T& operator *() & {
549     // FIXME: We need to offer special assert function that can be used under the contexpr context.
550     // CONSTEXPR_ASSERT(initialized());
551     return contained_val();
552   }
553
554   OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && {
555     // FIXME: We need to offer special assert function that can be used under the contexpr context.
556     // CONSTEXPR_ASSERT(initialized());
557     return detail_::constexpr_move(contained_val());
558   }
559
560   constexpr T const& value() const& {
561     // FIXME: We need to offer special assert function that can be used under the contexpr context.
562     // return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
563     return contained_val();
564   }
565
566   OPTIONAL_MUTABLE_CONSTEXPR T& value() & {
567     // FIXME: We need to offer special assert function that can be used under the contexpr context.
568     // return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
569     return contained_val();
570   }
571
572   OPTIONAL_MUTABLE_CONSTEXPR T&& value() && {
573     // FIXME: We need to offer special assert function that can be used under the contexpr context.
574     // if (!initialized()) __THROW_EXCEPTION(bad_optional_access("bad optional access"));
575     return std::move(contained_val());
576   }
577
578 # if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
579
580   template <class V>
581   constexpr T value_or(V&& v) const&
582   {
583     return *this ? **this : detail_::convert<T>(detail_::constexpr_forward<V>(v));
584   }
585
586   template <class V>
587   OPTIONAL_MUTABLE_CONSTEXPR T value_or(V&& v) &&
588   {
589     return *this ? detail_::constexpr_move(const_cast<optional<T>&>(*this).contained_val()) : detail_::convert<T>(detail_::constexpr_forward<V>(v));
590   }
591
592 # else
593
594   template <class V>
595   constexpr T value_or(V&& v) const
596   {
597     return *this ? **this : detail_::convert<T>(detail_::constexpr_forward<V>(v));
598   }
599
600 # endif
601
602   // 20.6.3.6, modifiers
603   void reset() __NOEXCEPT { clear(); }
604 };
605
606
607 template <class T>
608 class optional<T&>
609 {
610   static_assert( !std::is_same<T, nullopt_t>::value, "bad T" );
611   static_assert( !std::is_same<T, in_place_t>::value, "bad T" );
612   T* ref;
613
614 public:
615
616   // 20.5.5.1, construction/destruction
617   constexpr optional() __NOEXCEPT : ref(nullptr) {}
618
619   constexpr optional(nullopt_t) __NOEXCEPT : ref(nullptr) {}
620
621   constexpr optional(T& v) __NOEXCEPT : ref(detail_::static_addressof(v)) {}
622
623   optional(T&&) = delete;
624
625   constexpr optional(const optional& rhs) __NOEXCEPT : ref(rhs.ref) {}
626
627   explicit constexpr optional(in_place_t, T& v) __NOEXCEPT : ref(detail_::static_addressof(v)) {}
628
629   explicit optional(in_place_t, T&&) = delete;
630
631   ~optional() = default;
632
633   // 20.5.5.2, mutation
634   optional& operator=(nullopt_t) __NOEXCEPT {
635     ref = nullptr;
636     return *this;
637   }
638
639   // optional& operator=(const optional& rhs) __NOEXCEPT {
640     // ref = rhs.ref;
641     // return *this;
642   // }
643
644   // optional& operator=(optional&& rhs) __NOEXCEPT {
645     // ref = rhs.ref;
646     // return *this;
647   // }
648
649   template <typename U>
650   auto operator=(U&& rhs) __NOEXCEPT
651   -> typename std::enable_if
652   <
653     std::is_same<typename std::decay<U>::type, optional<T&>>::value,
654     optional&
655   >::type
656   {
657     ref = rhs.ref;
658     return *this;
659   }
660
661   template <typename U>
662   auto operator=(U&& rhs) __NOEXCEPT
663   -> typename std::enable_if
664   <
665     !std::is_same<typename std::decay<U>::type, optional<T&>>::value,
666     optional&
667   >::type
668   = delete;
669
670   void emplace(T& v) __NOEXCEPT {
671     ref = detail_::static_addressof(v);
672   }
673
674   void emplace(T&&) = delete;
675
676
677   void swap(optional<T&>& rhs) __NOEXCEPT
678   {
679     std::swap(ref, rhs.ref);
680   }
681
682   // 20.5.5.3, observers
683   constexpr T* operator->() const {
684     return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref);
685   }
686
687   constexpr T& operator*() const {
688     return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref);
689   }
690
691   constexpr T& value() const {
692     // FIXME: We need to offer special assert function that can be used under the contexpr context.
693     // return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref);
694     return *ref;
695   }
696
697   explicit constexpr operator bool() const __NOEXCEPT {
698     return ref != nullptr;
699   }
700
701   constexpr bool has_value() const __NOEXCEPT {
702     return ref != nullptr;
703   }
704
705   template <class V>
706   constexpr typename std::decay<T>::type value_or(V&& v) const
707   {
708     return *this ? **this : detail_::convert<typename std::decay<T>::type>(detail_::constexpr_forward<V>(v));
709   }
710
711   // x.x.x.x, modifiers
712   void reset() __NOEXCEPT { ref = nullptr; }
713 };
714
715
716 template <class T>
717 class optional<T&&>
718 {
719   static_assert( sizeof(T) == 0, "optional rvalue references disallowed" );
720 };
721
722
723 // 20.5.8, Relational operators
724 template <class T> constexpr bool operator==(const optional<T>& x, const optional<T>& y)
725 {
726   return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y;
727 }
728
729 template <class T> constexpr bool operator!=(const optional<T>& x, const optional<T>& y)
730 {
731   return !(x == y);
732 }
733
734 template <class T> constexpr bool operator<(const optional<T>& x, const optional<T>& y)
735 {
736   return (!y) ? false : (!x) ? true : *x < *y;
737 }
738
739 template <class T> constexpr bool operator>(const optional<T>& x, const optional<T>& y)
740 {
741   return (y < x);
742 }
743
744 template <class T> constexpr bool operator<=(const optional<T>& x, const optional<T>& y)
745 {
746   return !(y < x);
747 }
748
749 template <class T> constexpr bool operator>=(const optional<T>& x, const optional<T>& y)
750 {
751   return !(x < y);
752 }
753
754
755 // 20.5.9, Comparison with nullopt
756 template <class T> constexpr bool operator==(const optional<T>& x, nullopt_t) __NOEXCEPT
757 {
758   return (!x);
759 }
760
761 template <class T> constexpr bool operator==(nullopt_t, const optional<T>& x) __NOEXCEPT
762 {
763   return (!x);
764 }
765
766 template <class T> constexpr bool operator!=(const optional<T>& x, nullopt_t) __NOEXCEPT
767 {
768   return bool(x);
769 }
770
771 template <class T> constexpr bool operator!=(nullopt_t, const optional<T>& x) __NOEXCEPT
772 {
773   return bool(x);
774 }
775
776 template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) __NOEXCEPT
777 {
778   return false;
779 }
780
781 template <class T> constexpr bool operator<(nullopt_t, const optional<T>& x) __NOEXCEPT
782 {
783   return bool(x);
784 }
785
786 template <class T> constexpr bool operator<=(const optional<T>& x, nullopt_t) __NOEXCEPT
787 {
788   return (!x);
789 }
790
791 template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) __NOEXCEPT
792 {
793   return true;
794 }
795
796 template <class T> constexpr bool operator>(const optional<T>& x, nullopt_t) __NOEXCEPT
797 {
798   return bool(x);
799 }
800
801 template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) __NOEXCEPT
802 {
803   return false;
804 }
805
806 template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) __NOEXCEPT
807 {
808   return true;
809 }
810
811 template <class T> constexpr bool operator>=(nullopt_t, const optional<T>& x) __NOEXCEPT
812 {
813   return (!x);
814 }
815
816
817
818 // 20.5.10, Comparison with T
819 template <class T> constexpr bool operator==(const optional<T>& x, const T& v)
820 {
821   return bool(x) ? *x == v : false;
822 }
823
824 template <class T> constexpr bool operator==(const T& v, const optional<T>& x)
825 {
826   return bool(x) ? v == *x : false;
827 }
828
829 template <class T> constexpr bool operator!=(const optional<T>& x, const T& v)
830 {
831   return bool(x) ? *x != v : true;
832 }
833
834 template <class T> constexpr bool operator!=(const T& v, const optional<T>& x)
835 {
836   return bool(x) ? v != *x : true;
837 }
838
839 template <class T> constexpr bool operator<(const optional<T>& x, const T& v)
840 {
841   return bool(x) ? *x < v : true;
842 }
843
844 template <class T> constexpr bool operator>(const T& v, const optional<T>& x)
845 {
846   return bool(x) ? v > *x : true;
847 }
848
849 template <class T> constexpr bool operator>(const optional<T>& x, const T& v)
850 {
851   return bool(x) ? *x > v : false;
852 }
853
854 template <class T> constexpr bool operator<(const T& v, const optional<T>& x)
855 {
856   return bool(x) ? v < *x : false;
857 }
858
859 template <class T> constexpr bool operator>=(const optional<T>& x, const T& v)
860 {
861   return bool(x) ? *x >= v : false;
862 }
863
864 template <class T> constexpr bool operator<=(const T& v, const optional<T>& x)
865 {
866   return bool(x) ? v <= *x : false;
867 }
868
869 template <class T> constexpr bool operator<=(const optional<T>& x, const T& v)
870 {
871   return bool(x) ? *x <= v : true;
872 }
873
874 template <class T> constexpr bool operator>=(const T& v, const optional<T>& x)
875 {
876   return bool(x) ? v >= *x : true;
877 }
878
879
880 // Comparison of optional<T&> with T
881 template <class T> constexpr bool operator==(const optional<T&>& x, const T& v)
882 {
883   return bool(x) ? *x == v : false;
884 }
885
886 template <class T> constexpr bool operator==(const T& v, const optional<T&>& x)
887 {
888   return bool(x) ? v == *x : false;
889 }
890
891 template <class T> constexpr bool operator!=(const optional<T&>& x, const T& v)
892 {
893   return bool(x) ? *x != v : true;
894 }
895
896 template <class T> constexpr bool operator!=(const T& v, const optional<T&>& x)
897 {
898   return bool(x) ? v != *x : true;
899 }
900
901 template <class T> constexpr bool operator<(const optional<T&>& x, const T& v)
902 {
903   return bool(x) ? *x < v : true;
904 }
905
906 template <class T> constexpr bool operator>(const T& v, const optional<T&>& x)
907 {
908   return bool(x) ? v > *x : true;
909 }
910
911 template <class T> constexpr bool operator>(const optional<T&>& x, const T& v)
912 {
913   return bool(x) ? *x > v : false;
914 }
915
916 template <class T> constexpr bool operator<(const T& v, const optional<T&>& x)
917 {
918   return bool(x) ? v < *x : false;
919 }
920
921 template <class T> constexpr bool operator>=(const optional<T&>& x, const T& v)
922 {
923   return bool(x) ? *x >= v : false;
924 }
925
926 template <class T> constexpr bool operator<=(const T& v, const optional<T&>& x)
927 {
928   return bool(x) ? v <= *x : false;
929 }
930
931 template <class T> constexpr bool operator<=(const optional<T&>& x, const T& v)
932 {
933   return bool(x) ? *x <= v : true;
934 }
935
936 template <class T> constexpr bool operator>=(const T& v, const optional<T&>& x)
937 {
938   return bool(x) ? v >= *x : true;
939 }
940
941 // Comparison of optional<T const&> with T
942 template <class T> constexpr bool operator==(const optional<const T&>& x, const T& v)
943 {
944   return bool(x) ? *x == v : false;
945 }
946
947 template <class T> constexpr bool operator==(const T& v, const optional<const T&>& x)
948 {
949   return bool(x) ? v == *x : false;
950 }
951
952 template <class T> constexpr bool operator!=(const optional<const T&>& x, const T& v)
953 {
954   return bool(x) ? *x != v : true;
955 }
956
957 template <class T> constexpr bool operator!=(const T& v, const optional<const T&>& x)
958 {
959   return bool(x) ? v != *x : true;
960 }
961
962 template <class T> constexpr bool operator<(const optional<const T&>& x, const T& v)
963 {
964   return bool(x) ? *x < v : true;
965 }
966
967 template <class T> constexpr bool operator>(const T& v, const optional<const T&>& x)
968 {
969   return bool(x) ? v > *x : true;
970 }
971
972 template <class T> constexpr bool operator>(const optional<const T&>& x, const T& v)
973 {
974   return bool(x) ? *x > v : false;
975 }
976
977 template <class T> constexpr bool operator<(const T& v, const optional<const T&>& x)
978 {
979   return bool(x) ? v < *x : false;
980 }
981
982 template <class T> constexpr bool operator>=(const optional<const T&>& x, const T& v)
983 {
984   return bool(x) ? *x >= v : false;
985 }
986
987 template <class T> constexpr bool operator<=(const T& v, const optional<const T&>& x)
988 {
989   return bool(x) ? v <= *x : false;
990 }
991
992 template <class T> constexpr bool operator<=(const optional<const T&>& x, const T& v)
993 {
994   return bool(x) ? *x <= v : true;
995 }
996
997 template <class T> constexpr bool operator>=(const T& v, const optional<const T&>& x)
998 {
999   return bool(x) ? v >= *x : true;
1000 }
1001
1002
1003 // 20.5.12, Specialized algorithms
1004 template <class T>
1005 void swap(optional<T>& x, optional<T>& y) __NOEXCEPT_(__NOEXCEPT_(x.swap(y)))
1006 {
1007   x.swap(y);
1008 }
1009
1010
1011 template <class T>
1012 constexpr optional<typename std::decay<T>::type> make_optional(T&& v)
1013 {
1014   return optional<typename std::decay<T>::type>(detail_::constexpr_forward<T>(v));
1015 }
1016
1017 template <class X>
1018 constexpr optional<X&> make_optional(std::reference_wrapper<X> v)
1019 {
1020   return optional<X&>(v.get());
1021 }
1022
1023 } // namespace std
1024
1025 namespace std
1026 {
1027   template <typename T>
1028   struct hash<std::optional<T>>
1029   {
1030     typedef typename hash<T>::result_type result_type;
1031     typedef std::optional<T> argument_type;
1032
1033     constexpr result_type operator()(argument_type const& arg) const {
1034       return arg ? std::hash<T>{}(*arg) : result_type{};
1035     }
1036   };
1037
1038   template <typename T>
1039   struct hash<std::optional<T&>>
1040   {
1041     typedef typename hash<T>::result_type result_type;
1042     typedef std::optional<T&> argument_type;
1043
1044     constexpr result_type operator()(argument_type const& arg) const {
1045       return arg ? std::hash<T>{}(*arg) : result_type{};
1046     }
1047   };
1048 }
1049
1050 # undef TR2_OPTIONAL_REQUIRES
1051 # undef TR2_OPTIONAL_ASSERTED_EXPRESSION
1052
1053 #endif // defined(__cpp_lib_optional)
1054
1055 namespace WTF {
1056
1057 // -- WebKit Additions --
1058 template <class OptionalType, class Callback>
1059 ALWAYS_INLINE
1060 auto valueOrCompute(OptionalType optional, Callback callback) -> typename OptionalType::value_type
1061 {
1062     if (optional)
1063         return *optional;
1064     return callback();
1065 }
1066
1067 } // namespace WTF
1068
1069 using WTF::valueOrCompute;