Unreviewed, rolling out r231223 and r231288.
[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 # define TR2_OPTIONAL_REQUIRES(...) typename std::enable_if<__VA_ARGS__::value, bool>::type = false
51
52 # if defined __GNUC__ // NOTE: GNUC is also defined for Clang
53 #   if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
54 #     define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
55 #   elif (__GNUC__ > 4)
56 #     define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
57 #   endif
58 #
59 #   if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)
60 #     define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
61 #   elif (__GNUC__ > 4)
62 #     define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
63 #   endif
64 #
65 #   if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) && (__GNUC_PATCHLEVEL__ >= 1)
66 #     define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
67 #   elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)
68 #     define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
69 #   elif (__GNUC__ > 4)
70 #     define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
71 #   endif
72 # endif
73 #
74 # if defined __clang_major__
75 #   if (__clang_major__ == 3 && __clang_minor__ >= 5)
76 #     define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
77 #   elif (__clang_major__ > 3)
78 #     define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
79 #   endif
80 #   if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
81 #     define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
82 #   elif (__clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ >= 2)
83 #     define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
84 #   endif
85 # endif
86 #
87 # if defined _MSC_VER
88 #   if (_MSC_VER >= 1900)
89 #     define TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
90 #   endif
91 # endif
92
93 # if defined __clang__
94 #   if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9)
95 #     define OPTIONAL_HAS_THIS_RVALUE_REFS 1
96 #   else
97 #     define OPTIONAL_HAS_THIS_RVALUE_REFS 0
98 #   endif
99 # elif defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
100 #   define OPTIONAL_HAS_THIS_RVALUE_REFS 1
101 # elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
102 #   define OPTIONAL_HAS_THIS_RVALUE_REFS 1
103 # else
104 #   define OPTIONAL_HAS_THIS_RVALUE_REFS 0
105 # endif
106
107
108 # if defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
109 #   define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 1
110 #   define OPTIONAL_CONSTEXPR_INIT_LIST constexpr
111 # else
112 #   define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 0
113 #   define OPTIONAL_CONSTEXPR_INIT_LIST
114 # endif
115
116 # // In C++11 constexpr implies const, so we need to make non-const members also non-constexpr
117 # if (defined __cplusplus) && (__cplusplus == 201103L)
118 #   define OPTIONAL_MUTABLE_CONSTEXPR
119 # else
120 #   define OPTIONAL_MUTABLE_CONSTEXPR constexpr
121 # endif
122
123 #if COMPILER_SUPPORTS(EXCEPTIONS)
124 #define __THROW_EXCEPTION(__exception) throw __exception;
125 #define __NOEXCEPT noexcept
126 #define __NOEXCEPT_(__exception) noexcept(__exception)
127 #else
128 #define __THROW_EXCEPTION(__exception) do { (void)__exception; CRASH(); } while (0);
129 #define __NOEXCEPT
130 #define __NOEXCEPT_(...)
131 #endif
132
133 namespace std {
134 namespace detail_ {
135
136 // NOTE: All our target compilers support is_trivially_destructible.
137 // // BEGIN workaround for missing is_trivially_destructible
138 // # if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
139 //     // leave it: it is already there
140 // # elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
141 //     // leave it: it is already there
142 // # elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
143 //     // leave it: it is already there
144 // # elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
145 //     // leave it: the user doesn't want it
146 // # else
147 //     template <typename T>
148 //     using is_trivially_destructible = std::has_trivial_destructor<T>;
149 // # endif
150 // // END workaround for missing is_trivially_destructible
151
152 #if COMPILER_SUPPORTS(EXCEPTIONS)
153 # 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___)
154     // leave it; our metafunctions are already defined.
155     template <typename T>
156     using is_nothrow_move_constructible = std::is_nothrow_move_constructible<T>;
157     template <typename T>
158     using is_nothrow_move_assignable = std::is_nothrow_move_assignable<T>;
159 # elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
160     // leave it: the user doesn't want it
161 # else
162
163
164 // workaround for missing traits in GCC and CLANG
165 template <class T>
166 struct is_nothrow_move_constructible
167 {
168   constexpr static bool value = std::is_nothrow_constructible<T, T&&>::value;
169 };
170
171
172 template <class T, class U>
173 struct is_assignable
174 {
175   template <class X, class Y>
176   constexpr static bool has_assign(...) { return false; }
177
178   template <class X, class Y, size_t S = sizeof((std::declval<X>() = std::declval<Y>(), true)) >
179   // the comma operator is necessary for the cases where operator= returns void
180   constexpr static bool has_assign(bool) { return true; }
181
182   constexpr static bool value = has_assign<T, U>(true);
183 };
184
185
186 template <class T>
187 struct is_nothrow_move_assignable
188 {
189   template <class X, bool has_any_move_assign>
190   struct has_nothrow_move_assign {
191     constexpr static bool value = false;
192   };
193
194   template <class X>
195   struct has_nothrow_move_assign<X, true> {
196     constexpr static bool value = __NOEXCEPT_( std::declval<X&>() = std::declval<X&&>() );
197   };
198
199   constexpr static bool value = has_nothrow_move_assign<T, is_assignable<T&, T&&>::value>::value;
200 };
201 // end workaround
202
203
204 # endif
205 #endif
206
207 } // namespace detail_
208
209 // 20.5.4, optional for object types
210 template <class T> class optional;
211
212 // 20.5.5, optional for lvalue reference types
213 template <class T> class optional<T&>;
214
215 namespace detail_ {
216
217 // workaround: std utility functions aren't constexpr yet
218 template <class T> inline constexpr T&& constexpr_forward(typename std::remove_reference<T>::type& t) __NOEXCEPT
219 {
220   return static_cast<T&&>(t);
221 }
222
223 template <class T> inline constexpr T&& constexpr_forward(typename std::remove_reference<T>::type&& t) __NOEXCEPT
224 {
225     static_assert(!std::is_lvalue_reference<T>::value, "!!");
226     return static_cast<T&&>(t);
227 }
228
229 template <class T> inline constexpr typename std::remove_reference<T>::type&& constexpr_move(T&& t) __NOEXCEPT
230 {
231     return static_cast<typename std::remove_reference<T>::type&&>(t);
232 }
233
234 #if defined NDEBUG
235 # define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR)
236 #else
237 # define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) ((CHECK) ? (EXPR) : ([]{assert(!#CHECK);}(), (EXPR)))
238 #endif
239
240
241 // static_addressof: a constexpr version of addressof
242 template <typename T>
243 struct has_overloaded_addressof
244 {
245   template <class X>
246   constexpr static bool has_overload(...) { return false; }
247
248   template <class X, size_t S = sizeof(std::declval<X&>().operator&()) >
249   constexpr static bool has_overload(bool) { return true; }
250
251   constexpr static bool value = has_overload<T>(true);
252 };
253
254 template <typename T, TR2_OPTIONAL_REQUIRES(!has_overloaded_addressof<T>)>
255 constexpr T* static_addressof(T& ref)
256 {
257   return &ref;
258 }
259
260 template <typename T, TR2_OPTIONAL_REQUIRES(has_overloaded_addressof<T>)>
261 T* static_addressof(T& ref)
262 {
263   return std::addressof(ref);
264 }
265
266
267 // 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
268 template <class U>
269 constexpr U convert(U v) { return v; }
270
271 } // namespace detail
272
273
274 constexpr struct trivial_init_t{} trivial_init{};
275
276
277 // 20.5.7, Disengaged state indicator
278 struct nullopt_t
279 {
280   struct init{};
281   constexpr explicit nullopt_t(init){}
282 };
283 constexpr nullopt_t nullopt{nullopt_t::init()};
284
285
286 // 20.5.8, class bad_optional_access
287 class bad_optional_access : public std::logic_error {
288 public:
289   explicit bad_optional_access(const std::string& what_arg) : std::logic_error{what_arg} {}
290   explicit bad_optional_access(const char* what_arg) : std::logic_error{what_arg} {}
291 };
292
293
294 template <class T>
295 union storage_t
296 {
297   unsigned char dummy_;
298   T value_;
299
300   constexpr storage_t( trivial_init_t ) __NOEXCEPT : dummy_() {};
301
302   template <class... Args>
303   constexpr storage_t( Args&&... args ) : value_(detail_::constexpr_forward<Args>(args)...) {}
304
305   ~storage_t(){}
306 };
307
308
309 template <class T>
310 union constexpr_storage_t
311 {
312     unsigned char dummy_;
313     T value_;
314
315     constexpr constexpr_storage_t( trivial_init_t ) __NOEXCEPT : dummy_() {};
316
317     template <class... Args>
318     constexpr constexpr_storage_t( Args&&... args ) : value_(detail_::constexpr_forward<Args>(args)...) {}
319
320     ~constexpr_storage_t() = default;
321 };
322
323
324 template <class T>
325 struct optional_base
326 {
327     bool init_;
328     storage_t<T> storage_;
329
330     constexpr optional_base() __NOEXCEPT : init_(false), storage_(trivial_init) {};
331
332     explicit constexpr optional_base(const T& v) : init_(true), storage_(v) {}
333
334     explicit constexpr optional_base(T&& v) : init_(true), storage_(detail_::constexpr_move(v)) {}
335
336     template <class... Args> explicit optional_base(in_place_t, Args&&... args)
337         : init_(true), storage_(detail_::constexpr_forward<Args>(args)...) {}
338
339     template <class U, class... Args, TR2_OPTIONAL_REQUIRES(std::is_constructible<T, std::initializer_list<U>>)>
340     explicit optional_base(in_place_t, std::initializer_list<U> il, Args&&... args)
341         : init_(true), storage_(il, std::forward<Args>(args)...) {}
342
343     ~optional_base() { if (init_) storage_.value_.T::~T(); }
344 };
345
346
347 template <class T>
348 struct constexpr_optional_base
349 {
350     bool init_;
351     constexpr_storage_t<T> storage_;
352
353     constexpr constexpr_optional_base() __NOEXCEPT : init_(false), storage_(trivial_init) {};
354
355     explicit constexpr constexpr_optional_base(const T& v) : init_(true), storage_(v) {}
356
357     explicit constexpr constexpr_optional_base(T&& v) : init_(true), storage_(detail_::constexpr_move(v)) {}
358
359     template <class... Args> explicit constexpr constexpr_optional_base(in_place_t, Args&&... args)
360       : init_(true), storage_(detail_::constexpr_forward<Args>(args)...) {}
361
362     template <class U, class... Args, TR2_OPTIONAL_REQUIRES(std::is_constructible<T, std::initializer_list<U>>)>
363     OPTIONAL_CONSTEXPR_INIT_LIST explicit constexpr_optional_base(in_place_t, std::initializer_list<U> il, Args&&... args)
364       : init_(true), storage_(il, std::forward<Args>(args)...) {}
365
366     ~constexpr_optional_base() = default;
367 };
368
369 template <class T>
370 using OptionalBase = typename std::conditional<
371     std::is_trivially_destructible<T>::value,                          // if possible
372     constexpr_optional_base<typename std::remove_const<T>::type>, // use base with trivial destructor
373     optional_base<typename std::remove_const<T>::type>
374 >::type;
375
376
377
378 template <class T>
379 class optional : private OptionalBase<T>
380 {
381   static_assert( !std::is_same<typename std::decay<T>::type, nullopt_t>::value, "bad T" );
382   static_assert( !std::is_same<typename std::decay<T>::type, in_place_t>::value, "bad T" );
383
384
385   constexpr bool initialized() const __NOEXCEPT { return OptionalBase<T>::init_; }
386   typename std::remove_const<T>::type* dataptr() {  return std::addressof(OptionalBase<T>::storage_.value_); }
387   constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase<T>::storage_.value_); }
388
389 # if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
390   constexpr const T& contained_val() const& { return OptionalBase<T>::storage_.value_; }
391   OPTIONAL_MUTABLE_CONSTEXPR T&& contained_val() && { return std::move(OptionalBase<T>::storage_.value_); }
392   OPTIONAL_MUTABLE_CONSTEXPR T& contained_val() & { return OptionalBase<T>::storage_.value_; }
393 # else
394   constexpr const T& contained_val() const { return OptionalBase<T>::storage_.value_; }
395   T& contained_val() { return OptionalBase<T>::storage_.value_; }
396 # endif
397
398   void clear() __NOEXCEPT {
399     if (initialized()) dataptr()->T::~T();
400     OptionalBase<T>::init_ = false;
401   }
402
403   template <class... Args>
404   void initialize(Args&&... args) __NOEXCEPT_(__NOEXCEPT_(T(std::forward<Args>(args)...)))
405   {
406     ASSERT(!OptionalBase<T>::init_);
407     ::new (static_cast<void*>(dataptr())) T(std::forward<Args>(args)...);
408     OptionalBase<T>::init_ = true;
409   }
410
411   template <class U, class... Args>
412   void initialize(std::initializer_list<U> il, Args&&... args) __NOEXCEPT_(__NOEXCEPT_(T(il, std::forward<Args>(args)...)))
413   {
414     ASSERT(!OptionalBase<T>::init_);
415     ::new (static_cast<void*>(dataptr())) T(il, std::forward<Args>(args)...);
416     OptionalBase<T>::init_ = true;
417   }
418
419 public:
420   typedef T value_type;
421
422   // 20.5.5.1, constructors
423   constexpr optional() __NOEXCEPT : OptionalBase<T>()  {};
424   constexpr optional(nullopt_t) __NOEXCEPT : OptionalBase<T>() {};
425
426   optional(const optional& rhs)
427   : OptionalBase<T>()
428   {
429     if (rhs.initialized()) {
430         ::new (static_cast<void*>(dataptr())) T(*rhs);
431         OptionalBase<T>::init_ = true;
432     }
433   }
434
435   optional(optional&& rhs) __NOEXCEPT_(detail_::is_nothrow_move_constructible<T>::value)
436   : OptionalBase<T>()
437   {
438     if (rhs.initialized()) {
439         ::new (static_cast<void*>(dataptr())) T(std::move(*rhs));
440         OptionalBase<T>::init_ = true;
441     }
442   }
443
444   constexpr optional(const T& v) : OptionalBase<T>(v) {}
445
446   constexpr optional(T&& v) : OptionalBase<T>(detail_::constexpr_move(v)) {}
447
448   template <class... Args>
449   explicit constexpr optional(in_place_t, Args&&... args)
450   : OptionalBase<T>(in_place_t{}, detail_::constexpr_forward<Args>(args)...) {}
451
452   template <class U, class... Args, TR2_OPTIONAL_REQUIRES(std::is_constructible<T, std::initializer_list<U>>)>
453   OPTIONAL_CONSTEXPR_INIT_LIST explicit optional(in_place_t, std::initializer_list<U> il, Args&&... args)
454   : OptionalBase<T>(in_place_t{}, il, detail_::constexpr_forward<Args>(args)...) {}
455
456   // 20.5.4.2, Destructor
457   ~optional() = default;
458
459   // 20.5.4.3, assignment
460   optional& operator=(nullopt_t) __NOEXCEPT
461   {
462     clear();
463     return *this;
464   }
465
466   optional& operator=(const optional& rhs)
467   {
468     if      (initialized() == true  && rhs.initialized() == false) clear();
469     else if (initialized() == false && rhs.initialized() == true)  initialize(*rhs);
470     else if (initialized() == true  && rhs.initialized() == true)  contained_val() = *rhs;
471     return *this;
472   }
473
474   optional& operator=(optional&& rhs)
475   __NOEXCEPT_(detail_::is_nothrow_move_assignable<T>::value && detail_::is_nothrow_move_constructible<T>::value)
476   {
477     if      (initialized() == true  && rhs.initialized() == false) clear();
478     else if (initialized() == false && rhs.initialized() == true)  initialize(std::move(*rhs));
479     else if (initialized() == true  && rhs.initialized() == true)  contained_val() = std::move(*rhs);
480     return *this;
481   }
482
483   template <class U>
484   auto operator=(U&& v)
485   -> typename std::enable_if
486   <
487     std::is_same<typename std::decay<U>::type, T>::value,
488     optional&
489   >::type
490   {
491     if (initialized()) { contained_val() = std::forward<U>(v); }
492     else               { initialize(std::forward<U>(v));  }
493     return *this;
494   }
495
496
497   template <class... Args>
498   void emplace(Args&&... args)
499   {
500     clear();
501     initialize(std::forward<Args>(args)...);
502   }
503
504   template <class U, class... Args>
505   void emplace(std::initializer_list<U> il, Args&&... args)
506   {
507     clear();
508     initialize<U, Args...>(il, std::forward<Args>(args)...);
509   }
510
511   // 20.5.4.4, Swap
512   void swap(optional<T>& rhs) __NOEXCEPT_(detail_::is_nothrow_move_constructible<T>::value && __NOEXCEPT_(swap(std::declval<T&>(), std::declval<T&>())))
513   {
514     if      (initialized() == true  && rhs.initialized() == false) { rhs.initialize(std::move(**this)); clear(); }
515     else if (initialized() == false && rhs.initialized() == true)  { initialize(std::move(*rhs)); rhs.clear(); }
516     else if (initialized() == true  && rhs.initialized() == true)  { using std::swap; swap(**this, *rhs); }
517   }
518
519   // 20.5.4.5, Observers
520
521   explicit constexpr operator bool() const __NOEXCEPT { return initialized(); }
522   constexpr bool has_value() const __NOEXCEPT { return initialized(); }
523
524   constexpr T const* operator ->() const {
525     return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), dataptr());
526   }
527
528   OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() {
529     // FIXME: We need to offer special assert function that can be used under the contexpr context.
530     // CONSTEXPR_ASSERT(initialized());
531     return dataptr();
532   }
533
534   constexpr T const& operator *() const& {
535     return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
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 contained_val();
542   }
543
544   OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && {
545     // FIXME: We need to offer special assert function that can be used under the contexpr context.
546     // CONSTEXPR_ASSERT(initialized());
547     return detail_::constexpr_move(contained_val());
548   }
549
550   constexpr T const& value() const& {
551     // FIXME: We need to offer special assert function that can be used under the contexpr context.
552     // return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
553     return contained_val();
554   }
555
556   OPTIONAL_MUTABLE_CONSTEXPR T& value() & {
557     // FIXME: We need to offer special assert function that can be used under the contexpr context.
558     // return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
559     return contained_val();
560   }
561
562   OPTIONAL_MUTABLE_CONSTEXPR T&& value() && {
563     // FIXME: We need to offer special assert function that can be used under the contexpr context.
564     // if (!initialized()) __THROW_EXCEPTION(bad_optional_access("bad optional access"));
565     return std::move(contained_val());
566   }
567
568 # if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
569
570   template <class V>
571   constexpr T value_or(V&& v) const&
572   {
573     return *this ? **this : detail_::convert<T>(detail_::constexpr_forward<V>(v));
574   }
575
576   template <class V>
577   OPTIONAL_MUTABLE_CONSTEXPR T value_or(V&& v) &&
578   {
579     return *this ? detail_::constexpr_move(const_cast<optional<T>&>(*this).contained_val()) : detail_::convert<T>(detail_::constexpr_forward<V>(v));
580   }
581
582 # else
583
584   template <class V>
585   constexpr T value_or(V&& v) const
586   {
587     return *this ? **this : detail_::convert<T>(detail_::constexpr_forward<V>(v));
588   }
589
590 # endif
591
592   // 20.6.3.6, modifiers
593   void reset() __NOEXCEPT { clear(); }
594 };
595
596
597 template <class T>
598 class optional<T&>
599 {
600   static_assert( !std::is_same<T, nullopt_t>::value, "bad T" );
601   static_assert( !std::is_same<T, in_place_t>::value, "bad T" );
602   T* ref;
603
604 public:
605
606   // 20.5.5.1, construction/destruction
607   constexpr optional() __NOEXCEPT : ref(nullptr) {}
608
609   constexpr optional(nullopt_t) __NOEXCEPT : ref(nullptr) {}
610
611   constexpr optional(T& v) __NOEXCEPT : ref(detail_::static_addressof(v)) {}
612
613   optional(T&&) = delete;
614
615   constexpr optional(const optional& rhs) __NOEXCEPT : ref(rhs.ref) {}
616
617   explicit constexpr optional(in_place_t, T& v) __NOEXCEPT : ref(detail_::static_addressof(v)) {}
618
619   explicit optional(in_place_t, T&&) = delete;
620
621   ~optional() = default;
622
623   // 20.5.5.2, mutation
624   optional& operator=(nullopt_t) __NOEXCEPT {
625     ref = nullptr;
626     return *this;
627   }
628
629   // optional& operator=(const optional& rhs) __NOEXCEPT {
630     // ref = rhs.ref;
631     // return *this;
632   // }
633
634   // optional& operator=(optional&& rhs) __NOEXCEPT {
635     // ref = rhs.ref;
636     // return *this;
637   // }
638
639   template <typename U>
640   auto operator=(U&& rhs) __NOEXCEPT
641   -> typename std::enable_if
642   <
643     std::is_same<typename std::decay<U>::type, optional<T&>>::value,
644     optional&
645   >::type
646   {
647     ref = rhs.ref;
648     return *this;
649   }
650
651   template <typename U>
652   auto operator=(U&& rhs) __NOEXCEPT
653   -> typename std::enable_if
654   <
655     !std::is_same<typename std::decay<U>::type, optional<T&>>::value,
656     optional&
657   >::type
658   = delete;
659
660   void emplace(T& v) __NOEXCEPT {
661     ref = detail_::static_addressof(v);
662   }
663
664   void emplace(T&&) = delete;
665
666
667   void swap(optional<T&>& rhs) __NOEXCEPT
668   {
669     std::swap(ref, rhs.ref);
670   }
671
672   // 20.5.5.3, observers
673   constexpr T* operator->() const {
674     return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref);
675   }
676
677   constexpr T& operator*() const {
678     return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref);
679   }
680
681   constexpr T& value() const {
682     // FIXME: We need to offer special assert function that can be used under the contexpr context.
683     // return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref);
684     return *ref;
685   }
686
687   explicit constexpr operator bool() const __NOEXCEPT {
688     return ref != nullptr;
689   }
690
691   constexpr bool has_value() const __NOEXCEPT {
692     return ref != nullptr;
693   }
694
695   template <class V>
696   constexpr typename std::decay<T>::type value_or(V&& v) const
697   {
698     return *this ? **this : detail_::convert<typename std::decay<T>::type>(detail_::constexpr_forward<V>(v));
699   }
700
701   // x.x.x.x, modifiers
702   void reset() __NOEXCEPT { ref = nullptr; }
703 };
704
705
706 template <class T>
707 class optional<T&&>
708 {
709   static_assert( sizeof(T) == 0, "optional rvalue references disallowed" );
710 };
711
712
713 // 20.5.8, Relational operators
714 template <class T> constexpr bool operator==(const optional<T>& x, const optional<T>& y)
715 {
716   return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y;
717 }
718
719 template <class T> constexpr bool operator!=(const optional<T>& x, const optional<T>& y)
720 {
721   return !(x == y);
722 }
723
724 template <class T> constexpr bool operator<(const optional<T>& x, const optional<T>& y)
725 {
726   return (!y) ? false : (!x) ? true : *x < *y;
727 }
728
729 template <class T> constexpr bool operator>(const optional<T>& x, const optional<T>& y)
730 {
731   return (y < x);
732 }
733
734 template <class T> constexpr bool operator<=(const optional<T>& x, const optional<T>& y)
735 {
736   return !(y < x);
737 }
738
739 template <class T> constexpr bool operator>=(const optional<T>& x, const optional<T>& y)
740 {
741   return !(x < y);
742 }
743
744
745 // 20.5.9, Comparison with nullopt
746 template <class T> constexpr bool operator==(const optional<T>& x, nullopt_t) __NOEXCEPT
747 {
748   return (!x);
749 }
750
751 template <class T> constexpr bool operator==(nullopt_t, const optional<T>& x) __NOEXCEPT
752 {
753   return (!x);
754 }
755
756 template <class T> constexpr bool operator!=(const optional<T>& x, nullopt_t) __NOEXCEPT
757 {
758   return bool(x);
759 }
760
761 template <class T> constexpr bool operator!=(nullopt_t, const optional<T>& x) __NOEXCEPT
762 {
763   return bool(x);
764 }
765
766 template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) __NOEXCEPT
767 {
768   return false;
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>& x, nullopt_t) __NOEXCEPT
777 {
778   return (!x);
779 }
780
781 template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) __NOEXCEPT
782 {
783   return true;
784 }
785
786 template <class T> constexpr bool operator>(const optional<T>& x, nullopt_t) __NOEXCEPT
787 {
788   return bool(x);
789 }
790
791 template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) __NOEXCEPT
792 {
793   return false;
794 }
795
796 template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) __NOEXCEPT
797 {
798   return true;
799 }
800
801 template <class T> constexpr bool operator>=(nullopt_t, const optional<T>& x) __NOEXCEPT
802 {
803   return (!x);
804 }
805
806
807
808 // 20.5.10, Comparison with T
809 template <class T> constexpr bool operator==(const optional<T>& x, const T& v)
810 {
811   return bool(x) ? *x == v : false;
812 }
813
814 template <class T> constexpr bool operator==(const T& v, const optional<T>& x)
815 {
816   return bool(x) ? v == *x : false;
817 }
818
819 template <class T> constexpr bool operator!=(const optional<T>& x, const T& v)
820 {
821   return bool(x) ? *x != v : true;
822 }
823
824 template <class T> constexpr bool operator!=(const T& v, const optional<T>& x)
825 {
826   return bool(x) ? v != *x : true;
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 : false;
842 }
843
844 template <class T> constexpr bool operator<(const T& v, const optional<T>& x)
845 {
846   return bool(x) ? v < *x : false;
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 : true;
862 }
863
864 template <class T> constexpr bool operator>=(const T& v, const optional<T>& x)
865 {
866   return bool(x) ? v >= *x : true;
867 }
868
869
870 // Comparison of optional<T&> with T
871 template <class T> constexpr bool operator==(const optional<T&>& x, const T& v)
872 {
873   return bool(x) ? *x == v : false;
874 }
875
876 template <class T> constexpr bool operator==(const T& v, const optional<T&>& x)
877 {
878   return bool(x) ? v == *x : false;
879 }
880
881 template <class T> constexpr bool operator!=(const optional<T&>& x, const T& v)
882 {
883   return bool(x) ? *x != v : true;
884 }
885
886 template <class T> constexpr bool operator!=(const T& v, const optional<T&>& x)
887 {
888   return bool(x) ? v != *x : true;
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 : false;
904 }
905
906 template <class T> constexpr bool operator<(const T& v, const optional<T&>& x)
907 {
908   return bool(x) ? v < *x : false;
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 : true;
924 }
925
926 template <class T> constexpr bool operator>=(const T& v, const optional<T&>& x)
927 {
928   return bool(x) ? v >= *x : true;
929 }
930
931 // Comparison of optional<T const&> with T
932 template <class T> constexpr bool operator==(const optional<const T&>& x, const T& v)
933 {
934   return bool(x) ? *x == v : false;
935 }
936
937 template <class T> constexpr bool operator==(const T& v, const optional<const T&>& x)
938 {
939   return bool(x) ? v == *x : false;
940 }
941
942 template <class T> constexpr bool operator!=(const optional<const T&>& x, const T& v)
943 {
944   return bool(x) ? *x != v : true;
945 }
946
947 template <class T> constexpr bool operator!=(const T& v, const optional<const T&>& x)
948 {
949   return bool(x) ? v != *x : true;
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 : false;
965 }
966
967 template <class T> constexpr bool operator<(const T& v, const optional<const T&>& x)
968 {
969   return bool(x) ? v < *x : false;
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 : true;
985 }
986
987 template <class T> constexpr bool operator>=(const T& v, const optional<const T&>& x)
988 {
989   return bool(x) ? v >= *x : true;
990 }
991
992
993 // 20.5.12, Specialized algorithms
994 template <class T>
995 void swap(optional<T>& x, optional<T>& y) __NOEXCEPT_(__NOEXCEPT_(x.swap(y)))
996 {
997   x.swap(y);
998 }
999
1000
1001 template <class T>
1002 constexpr optional<typename std::decay<T>::type> make_optional(T&& v)
1003 {
1004   return optional<typename std::decay<T>::type>(detail_::constexpr_forward<T>(v));
1005 }
1006
1007 template <class X>
1008 constexpr optional<X&> make_optional(std::reference_wrapper<X> v)
1009 {
1010   return optional<X&>(v.get());
1011 }
1012
1013 } // namespace std
1014
1015 namespace WTF {
1016
1017 // -- WebKit Additions --
1018 template <class OptionalType, class Callback>
1019 ALWAYS_INLINE
1020 auto valueOrCompute(OptionalType optional, Callback callback) -> typename OptionalType::value_type
1021 {
1022     if (optional)
1023         return *optional;
1024     return callback();
1025 }
1026
1027 } // namespace WTF
1028
1029 namespace std
1030 {
1031   template <typename T>
1032   struct hash<std::optional<T>>
1033   {
1034     typedef typename hash<T>::result_type result_type;
1035     typedef std::optional<T> argument_type;
1036
1037     constexpr result_type operator()(argument_type const& arg) const {
1038       return arg ? std::hash<T>{}(*arg) : result_type{};
1039     }
1040   };
1041
1042   template <typename T>
1043   struct hash<std::optional<T&>>
1044   {
1045     typedef typename hash<T>::result_type result_type;
1046     typedef std::optional<T&> argument_type;
1047
1048     constexpr result_type operator()(argument_type const& arg) const {
1049       return arg ? std::hash<T>{}(*arg) : result_type{};
1050     }
1051   };
1052 }
1053
1054 # undef TR2_OPTIONAL_REQUIRES
1055 # undef TR2_OPTIONAL_ASSERTED_EXPRESSION
1056
1057 using WTF::valueOrCompute;