a605be01946a0ec9b0f5219fb0f0d0652f03fbba
[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 WTF {
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> 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> 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> 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
235 // static_addressof: a constexpr version of addressof
236 template <typename T>
237 struct has_overloaded_addressof
238 {
239   template <class X>
240   constexpr static bool has_overload(...) { return false; }
241
242   template <class X, size_t S = sizeof(std::declval<X&>().operator&()) >
243   constexpr static bool has_overload(bool) { return true; }
244
245   constexpr static bool value = has_overload<T>(true);
246 };
247
248 template <typename T, TR2_OPTIONAL_REQUIRES(!has_overloaded_addressof<T>)>
249 constexpr T* static_addressof(T& ref)
250 {
251   return &ref;
252 }
253
254 template <typename T, TR2_OPTIONAL_REQUIRES(has_overloaded_addressof<T>)>
255 T* static_addressof(T& ref)
256 {
257   return std::addressof(ref);
258 }
259
260
261 // 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
262 template <class U>
263 constexpr U convert(U v) { return v; }
264
265 } // namespace detail
266
267
268 constexpr struct trivial_init_t{} trivial_init{};
269
270
271 // 20.5.7, Disengaged state indicator
272 struct nullopt_t
273 {
274   struct init{};
275   constexpr explicit nullopt_t(init){}
276 };
277 constexpr nullopt_t nullopt{nullopt_t::init()};
278
279
280 template <class T>
281 union storage_t
282 {
283   unsigned char dummy_;
284   T value_;
285
286   constexpr storage_t( trivial_init_t ) __NOEXCEPT : dummy_() {};
287
288   template <class... Args>
289   constexpr storage_t( Args&&... args ) : value_(detail_::constexpr_forward<Args>(args)...) {}
290
291   ~storage_t(){}
292 };
293
294
295 template <class T>
296 union constexpr_storage_t
297 {
298     unsigned char dummy_;
299     T value_;
300
301     constexpr constexpr_storage_t( trivial_init_t ) __NOEXCEPT : dummy_() {};
302
303     template <class... Args>
304     constexpr constexpr_storage_t( Args&&... args ) : value_(detail_::constexpr_forward<Args>(args)...) {}
305
306     ~constexpr_storage_t() = default;
307 };
308
309
310 template <class T>
311 struct Optional_base
312 {
313     bool init_;
314     storage_t<T> storage_;
315
316     constexpr Optional_base() __NOEXCEPT : init_(false), storage_(trivial_init) {};
317
318     explicit constexpr Optional_base(const T& v) : init_(true), storage_(v) {}
319
320     explicit constexpr Optional_base(T&& v) : init_(true), storage_(detail_::constexpr_move(v)) {}
321
322     template <class... Args> explicit Optional_base(std::in_place_t, Args&&... args)
323         : init_(true), storage_(detail_::constexpr_forward<Args>(args)...) {}
324
325     template <class U, class... Args, TR2_OPTIONAL_REQUIRES(std::is_constructible<T, std::initializer_list<U>>)>
326     explicit Optional_base(std::in_place_t, std::initializer_list<U> il, Args&&... args)
327         : init_(true), storage_(il, std::forward<Args>(args)...) {}
328
329     ~Optional_base() { if (init_) storage_.value_.T::~T(); }
330 };
331
332
333 template <class T>
334 struct constexpr_Optional_base
335 {
336     bool init_;
337     constexpr_storage_t<T> storage_;
338
339     constexpr constexpr_Optional_base() __NOEXCEPT : init_(false), storage_(trivial_init) {};
340
341     explicit constexpr constexpr_Optional_base(const T& v) : init_(true), storage_(v) {}
342
343     explicit constexpr constexpr_Optional_base(T&& v) : init_(true), storage_(detail_::constexpr_move(v)) {}
344
345     template <class... Args> explicit constexpr constexpr_Optional_base(std::in_place_t, Args&&... args)
346       : init_(true), storage_(detail_::constexpr_forward<Args>(args)...) {}
347
348     template <class U, class... Args, TR2_OPTIONAL_REQUIRES(std::is_constructible<T, std::initializer_list<U>>)>
349     OPTIONAL_CONSTEXPR_INIT_LIST explicit constexpr_Optional_base(std::in_place_t, std::initializer_list<U> il, Args&&... args)
350       : init_(true), storage_(il, std::forward<Args>(args)...) {}
351
352     ~constexpr_Optional_base() = default;
353 };
354
355 template <class T>
356 using OptionalBase = typename std::conditional<
357     std::is_trivially_destructible<T>::value,                          // if possible
358     constexpr_Optional_base<typename std::remove_const<T>::type>, // use base with trivial destructor
359     Optional_base<typename std::remove_const<T>::type>
360 >::type;
361
362
363
364 template <class T>
365 class Optional : private OptionalBase<T>
366 {
367   static_assert( !std::is_same<typename std::decay<T>::type, nullopt_t>::value, "bad T" );
368   static_assert( !std::is_same<typename std::decay<T>::type, std::in_place_t>::value, "bad T" );
369
370
371   constexpr bool initialized() const __NOEXCEPT { return OptionalBase<T>::init_; }
372   typename std::remove_const<T>::type* dataptr() {  return std::addressof(OptionalBase<T>::storage_.value_); }
373   constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase<T>::storage_.value_); }
374
375 # if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
376   constexpr const T& contained_val() const& { return OptionalBase<T>::storage_.value_; }
377   OPTIONAL_MUTABLE_CONSTEXPR T&& contained_val() && { return std::move(OptionalBase<T>::storage_.value_); }
378   OPTIONAL_MUTABLE_CONSTEXPR T& contained_val() & { return OptionalBase<T>::storage_.value_; }
379 # else
380   constexpr const T& contained_val() const { return OptionalBase<T>::storage_.value_; }
381   T& contained_val() { return OptionalBase<T>::storage_.value_; }
382 # endif
383
384   void clear() __NOEXCEPT {
385     if (initialized()) dataptr()->T::~T();
386     OptionalBase<T>::init_ = false;
387   }
388
389   template <class... Args>
390   void initialize(Args&&... args) __NOEXCEPT_(__NOEXCEPT_(T(std::forward<Args>(args)...)))
391   {
392     ASSERT(!OptionalBase<T>::init_);
393     ::new (static_cast<void*>(dataptr())) T(std::forward<Args>(args)...);
394     OptionalBase<T>::init_ = true;
395   }
396
397   template <class U, class... Args>
398   void initialize(std::initializer_list<U> il, Args&&... args) __NOEXCEPT_(__NOEXCEPT_(T(il, std::forward<Args>(args)...)))
399   {
400     ASSERT(!OptionalBase<T>::init_);
401     ::new (static_cast<void*>(dataptr())) T(il, std::forward<Args>(args)...);
402     OptionalBase<T>::init_ = true;
403   }
404
405 public:
406   typedef T value_type;
407
408   // 20.5.5.1, constructors
409   constexpr Optional() __NOEXCEPT : OptionalBase<T>()  {};
410   constexpr Optional(nullopt_t) __NOEXCEPT : OptionalBase<T>() {};
411
412   Optional(const Optional& rhs)
413   : OptionalBase<T>()
414   {
415     if (rhs.initialized()) {
416         ::new (static_cast<void*>(dataptr())) T(*rhs);
417         OptionalBase<T>::init_ = true;
418     }
419   }
420
421   Optional(Optional&& rhs) __NOEXCEPT_(detail_::is_nothrow_move_constructible<T>::value)
422   : OptionalBase<T>()
423   {
424     if (rhs.initialized()) {
425         ::new (static_cast<void*>(dataptr())) T(std::move(*rhs));
426         OptionalBase<T>::init_ = true;
427         rhs.clear();
428     }
429   }
430
431   constexpr Optional(const T& v) : OptionalBase<T>(v) {}
432
433   constexpr Optional(T&& v) : OptionalBase<T>(detail_::constexpr_move(v)) {}
434
435   template <class... Args>
436   explicit constexpr Optional(std::in_place_t, Args&&... args)
437       : OptionalBase<T>(std::in_place_t{}, detail_::constexpr_forward<Args>(args)...) {}
438
439   template <class U, class... Args, TR2_OPTIONAL_REQUIRES(std::is_constructible<T, std::initializer_list<U>>)>
440   OPTIONAL_CONSTEXPR_INIT_LIST explicit Optional(std::in_place_t, std::initializer_list<U> il, Args&&... args)
441       : OptionalBase<T>(std::in_place_t{}, il, detail_::constexpr_forward<Args>(args)...) {}
442
443   // 20.5.4.2, Destructor
444   ~Optional() = default;
445
446   // 20.5.4.3, assignment
447   Optional& operator=(nullopt_t) __NOEXCEPT
448   {
449     clear();
450     return *this;
451   }
452
453   Optional& operator=(const Optional& rhs)
454   {
455     if      (initialized() == true  && rhs.initialized() == false) clear();
456     else if (initialized() == false && rhs.initialized() == true)  initialize(*rhs);
457     else if (initialized() == true  && rhs.initialized() == true)  contained_val() = *rhs;
458     return *this;
459   }
460
461   Optional& operator=(Optional&& rhs)
462   __NOEXCEPT_(detail_::is_nothrow_move_assignable<T>::value && detail_::is_nothrow_move_constructible<T>::value)
463   {
464     if      (initialized() == true  && rhs.initialized() == false) clear();
465     else if (initialized() == false && rhs.initialized() == true)  { initialize(std::move(*rhs)); rhs.clear(); }
466     else if (initialized() == true  && rhs.initialized() == true)  { contained_val() = std::move(*rhs); rhs.clear(); }
467     return *this;
468   }
469
470   template <class U>
471   auto operator=(U&& v)
472   -> typename std::enable_if
473   <
474     std::is_same<typename std::decay<U>::type, T>::value,
475     Optional&
476   >::type
477   {
478     if (initialized()) { contained_val() = std::forward<U>(v); }
479     else               { initialize(std::forward<U>(v));  }
480     return *this;
481   }
482
483
484   template <class... Args>
485   void emplace(Args&&... args)
486   {
487     clear();
488     initialize(std::forward<Args>(args)...);
489   }
490
491   template <class U, class... Args>
492   void emplace(std::initializer_list<U> il, Args&&... args)
493   {
494     clear();
495     initialize<U, Args...>(il, std::forward<Args>(args)...);
496   }
497
498   // 20.5.4.4, Swap
499   void swap(Optional<T>& rhs) __NOEXCEPT_(detail_::is_nothrow_move_constructible<T>::value && __NOEXCEPT_(swap(std::declval<T&>(), std::declval<T&>())))
500   {
501     if      (initialized() == true  && rhs.initialized() == false) { rhs.initialize(std::move(**this)); clear(); }
502     else if (initialized() == false && rhs.initialized() == true)  { initialize(std::move(*rhs)); rhs.clear(); }
503     else if (initialized() == true  && rhs.initialized() == true)  { using std::swap; swap(**this, *rhs); }
504   }
505
506   // 20.5.4.5, Observers
507
508   explicit constexpr operator bool() const __NOEXCEPT { return initialized(); }
509   constexpr bool has_value() const __NOEXCEPT { return initialized(); } // FIXME: Remove this.
510   constexpr bool hasValue() const __NOEXCEPT { return initialized(); }
511
512   constexpr T const* operator ->() const {
513     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
514     return dataptr();
515   }
516
517   OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() {
518     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
519     return dataptr();
520   }
521
522   constexpr T const& operator *() const& {
523     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
524     return contained_val();
525   }
526
527   OPTIONAL_MUTABLE_CONSTEXPR T& operator *() & {
528     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
529     return contained_val();
530   }
531
532   OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && {
533     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
534     return detail_::constexpr_move(contained_val());
535   }
536
537   constexpr T const& value() const& {
538     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
539     return contained_val();
540   }
541
542   OPTIONAL_MUTABLE_CONSTEXPR T& value() & {
543     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
544     return contained_val();
545   }
546
547   OPTIONAL_MUTABLE_CONSTEXPR T&& value() && {
548     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
549     return std::move(contained_val());
550   }
551
552 # if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
553
554   template <class V>
555   constexpr T valueOr(V&& v) const&
556   {
557     return *this ? **this : detail_::convert<T>(detail_::constexpr_forward<V>(v));
558   }
559
560   // FIXME: Remove this.
561   template <class V>
562   constexpr T value_or(V&& v) const&
563   {
564     return *this ? **this : detail_::convert<T>(detail_::constexpr_forward<V>(v));
565   }
566
567   template <class V>
568   OPTIONAL_MUTABLE_CONSTEXPR T valueOr(V&& v) &&
569   {
570     return *this ? detail_::constexpr_move(const_cast<Optional<T>&>(*this).contained_val()) : detail_::convert<T>(detail_::constexpr_forward<V>(v));
571   }
572
573   // FIXME: Remove this.
574   template <class V>
575   OPTIONAL_MUTABLE_CONSTEXPR T value_or(V&& v) &&
576   {
577     return *this ? detail_::constexpr_move(const_cast<Optional<T>&>(*this).contained_val()) : detail_::convert<T>(detail_::constexpr_forward<V>(v));
578   }
579
580 # else
581
582   template <class V>
583   constexpr T valueOr(V&& v) const
584   {
585     return *this ? **this : detail_::convert<T>(detail_::constexpr_forward<V>(v));
586   }
587
588   // FIXME: Remove this.
589   template <class V>
590   constexpr T value_or(V&& v) const
591   {
592     return *this ? **this : detail_::convert<T>(detail_::constexpr_forward<V>(v));
593   }
594
595 # endif
596
597   // 20.6.3.6, modifiers
598   void reset() __NOEXCEPT { clear(); }
599 };
600
601
602 template <class T>
603 class Optional<T&>
604 {
605   static_assert( !std::is_same<T, nullopt_t>::value, "bad T" );
606   static_assert( !std::is_same<T, std::in_place_t>::value, "bad T" );
607   T* ref;
608
609 public:
610
611   // 20.5.5.1, construction/destruction
612   constexpr Optional() __NOEXCEPT : ref(nullptr) {}
613
614   constexpr Optional(nullopt_t) __NOEXCEPT : ref(nullptr) {}
615
616   constexpr Optional(T& v) __NOEXCEPT : ref(detail_::static_addressof(v)) {}
617
618   Optional(T&&) = delete;
619
620   constexpr Optional(const Optional& rhs) __NOEXCEPT : ref(rhs.ref) {}
621
622   explicit constexpr Optional(std::in_place_t, T& v) __NOEXCEPT : ref(detail_::static_addressof(v)) {}
623
624   explicit Optional(std::in_place_t, T&&) = delete;
625
626   ~Optional() = default;
627
628   // 20.5.5.2, mutation
629   Optional& operator=(nullopt_t) __NOEXCEPT {
630     ref = nullptr;
631     return *this;
632   }
633
634   // Optional& operator=(const Optional& rhs) __NOEXCEPT {
635     // ref = rhs.ref;
636     // return *this;
637   // }
638
639   // Optional& operator=(Optional&& rhs) __NOEXCEPT {
640     // ref = rhs.ref;
641     // return *this;
642   // }
643
644   template <typename U>
645   auto operator=(U&& rhs) __NOEXCEPT
646   -> typename std::enable_if
647   <
648     std::is_same<typename std::decay<U>::type, Optional<T&>>::value,
649     Optional&
650   >::type
651   {
652     ref = rhs.ref;
653     return *this;
654   }
655
656   template <typename U>
657   auto operator=(U&& rhs) __NOEXCEPT
658   -> typename std::enable_if
659   <
660     !std::is_same<typename std::decay<U>::type, Optional<T&>>::value,
661     Optional&
662   >::type
663   = delete;
664
665   void emplace(T& v) __NOEXCEPT {
666     ref = detail_::static_addressof(v);
667   }
668
669   void emplace(T&&) = delete;
670
671
672   void swap(Optional<T&>& rhs) __NOEXCEPT
673   {
674     std::swap(ref, rhs.ref);
675   }
676
677   // 20.5.5.3, observers
678   constexpr T* operator->() const {
679     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(ref);
680     return ref;
681   }
682
683   constexpr T& operator*() const {
684     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(ref);
685     return *ref;
686   }
687
688   constexpr T& value() const {
689     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(ref());
690     return *ref;
691   }
692
693   explicit constexpr operator bool() const __NOEXCEPT {
694     return ref != nullptr;
695   }
696
697   constexpr bool has_value() const __NOEXCEPT {
698     return ref != nullptr;
699   }
700
701   template <class V>
702   constexpr typename std::decay<T>::type value_or(V&& v) const
703   {
704     return *this ? **this : detail_::convert<typename std::decay<T>::type>(detail_::constexpr_forward<V>(v));
705   }
706
707   // x.x.x.x, modifiers
708   void reset() __NOEXCEPT { ref = nullptr; }
709 };
710
711
712 template <class T>
713 class Optional<T&&>
714 {
715   static_assert( sizeof(T) == 0, "Optional rvalue references disallowed" );
716 };
717
718
719 // 20.5.8, Relational operators
720 template <class T> constexpr bool operator==(const Optional<T>& x, const Optional<T>& y)
721 {
722   return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y;
723 }
724
725 template <class T> constexpr bool operator!=(const Optional<T>& x, const Optional<T>& y)
726 {
727   return !(x == y);
728 }
729
730 template <class T> constexpr bool operator<(const Optional<T>& x, const Optional<T>& y)
731 {
732   return (!y) ? false : (!x) ? true : *x < *y;
733 }
734
735 template <class T> constexpr bool operator>(const Optional<T>& x, const Optional<T>& y)
736 {
737   return (y < x);
738 }
739
740 template <class T> constexpr bool operator<=(const Optional<T>& x, const Optional<T>& y)
741 {
742   return !(y < x);
743 }
744
745 template <class T> constexpr bool operator>=(const Optional<T>& x, const Optional<T>& y)
746 {
747   return !(x < y);
748 }
749
750
751 // 20.5.9, Comparison with nullopt
752 template <class T> constexpr bool operator==(const Optional<T>& x, nullopt_t) __NOEXCEPT
753 {
754   return (!x);
755 }
756
757 template <class T> constexpr bool operator==(nullopt_t, const Optional<T>& x) __NOEXCEPT
758 {
759   return (!x);
760 }
761
762 template <class T> constexpr bool operator!=(const Optional<T>& x, nullopt_t) __NOEXCEPT
763 {
764   return bool(x);
765 }
766
767 template <class T> constexpr bool operator!=(nullopt_t, const Optional<T>& x) __NOEXCEPT
768 {
769   return bool(x);
770 }
771
772 template <class T> constexpr bool operator<(const Optional<T>&, nullopt_t) __NOEXCEPT
773 {
774   return false;
775 }
776
777 template <class T> constexpr bool operator<(nullopt_t, const Optional<T>& x) __NOEXCEPT
778 {
779   return bool(x);
780 }
781
782 template <class T> constexpr bool operator<=(const Optional<T>& x, nullopt_t) __NOEXCEPT
783 {
784   return (!x);
785 }
786
787 template <class T> constexpr bool operator<=(nullopt_t, const Optional<T>&) __NOEXCEPT
788 {
789   return true;
790 }
791
792 template <class T> constexpr bool operator>(const Optional<T>& x, nullopt_t) __NOEXCEPT
793 {
794   return bool(x);
795 }
796
797 template <class T> constexpr bool operator>(nullopt_t, const Optional<T>&) __NOEXCEPT
798 {
799   return false;
800 }
801
802 template <class T> constexpr bool operator>=(const Optional<T>&, nullopt_t) __NOEXCEPT
803 {
804   return true;
805 }
806
807 template <class T> constexpr bool operator>=(nullopt_t, const Optional<T>& x) __NOEXCEPT
808 {
809   return (!x);
810 }
811
812
813
814 // 20.5.10, Comparison with T
815 template <class T> constexpr bool operator==(const Optional<T>& x, const T& v)
816 {
817   return bool(x) ? *x == v : false;
818 }
819
820 template <class T> constexpr bool operator==(const T& v, const Optional<T>& x)
821 {
822   return bool(x) ? v == *x : false;
823 }
824
825 template <class T> constexpr bool operator!=(const Optional<T>& x, const T& v)
826 {
827   return bool(x) ? *x != v : true;
828 }
829
830 template <class T> constexpr bool operator!=(const T& v, const Optional<T>& x)
831 {
832   return bool(x) ? v != *x : true;
833 }
834
835 template <class T> constexpr bool operator<(const Optional<T>& x, const T& v)
836 {
837   return bool(x) ? *x < v : true;
838 }
839
840 template <class T> constexpr bool operator>(const T& v, const Optional<T>& x)
841 {
842   return bool(x) ? v > *x : true;
843 }
844
845 template <class T> constexpr bool operator>(const Optional<T>& x, const T& v)
846 {
847   return bool(x) ? *x > v : false;
848 }
849
850 template <class T> constexpr bool operator<(const T& v, const Optional<T>& x)
851 {
852   return bool(x) ? v < *x : false;
853 }
854
855 template <class T> constexpr bool operator>=(const Optional<T>& x, const T& v)
856 {
857   return bool(x) ? *x >= v : false;
858 }
859
860 template <class T> constexpr bool operator<=(const T& v, const Optional<T>& x)
861 {
862   return bool(x) ? v <= *x : false;
863 }
864
865 template <class T> constexpr bool operator<=(const Optional<T>& x, const T& v)
866 {
867   return bool(x) ? *x <= v : true;
868 }
869
870 template <class T> constexpr bool operator>=(const T& v, const Optional<T>& x)
871 {
872   return bool(x) ? v >= *x : true;
873 }
874
875
876 // Comparison of Optional<T&> with T
877 template <class T> constexpr bool operator==(const Optional<T&>& x, const T& v)
878 {
879   return bool(x) ? *x == v : false;
880 }
881
882 template <class T> constexpr bool operator==(const T& v, const Optional<T&>& x)
883 {
884   return bool(x) ? v == *x : false;
885 }
886
887 template <class T> constexpr bool operator!=(const Optional<T&>& x, const T& v)
888 {
889   return bool(x) ? *x != v : true;
890 }
891
892 template <class T> constexpr bool operator!=(const T& v, const Optional<T&>& x)
893 {
894   return bool(x) ? v != *x : true;
895 }
896
897 template <class T> constexpr bool operator<(const Optional<T&>& x, const T& v)
898 {
899   return bool(x) ? *x < v : true;
900 }
901
902 template <class T> constexpr bool operator>(const T& v, const Optional<T&>& x)
903 {
904   return bool(x) ? v > *x : true;
905 }
906
907 template <class T> constexpr bool operator>(const Optional<T&>& x, const T& v)
908 {
909   return bool(x) ? *x > v : false;
910 }
911
912 template <class T> constexpr bool operator<(const T& v, const Optional<T&>& x)
913 {
914   return bool(x) ? v < *x : false;
915 }
916
917 template <class T> constexpr bool operator>=(const Optional<T&>& x, const T& v)
918 {
919   return bool(x) ? *x >= v : false;
920 }
921
922 template <class T> constexpr bool operator<=(const T& v, const Optional<T&>& x)
923 {
924   return bool(x) ? v <= *x : false;
925 }
926
927 template <class T> constexpr bool operator<=(const Optional<T&>& x, const T& v)
928 {
929   return bool(x) ? *x <= v : true;
930 }
931
932 template <class T> constexpr bool operator>=(const T& v, const Optional<T&>& x)
933 {
934   return bool(x) ? v >= *x : true;
935 }
936
937 // Comparison of Optional<T const&> with T
938 template <class T> constexpr bool operator==(const Optional<const T&>& x, const T& v)
939 {
940   return bool(x) ? *x == v : false;
941 }
942
943 template <class T> constexpr bool operator==(const T& v, const Optional<const T&>& x)
944 {
945   return bool(x) ? v == *x : false;
946 }
947
948 template <class T> constexpr bool operator!=(const Optional<const T&>& x, const T& v)
949 {
950   return bool(x) ? *x != v : true;
951 }
952
953 template <class T> constexpr bool operator!=(const T& v, const Optional<const T&>& x)
954 {
955   return bool(x) ? v != *x : true;
956 }
957
958 template <class T> constexpr bool operator<(const Optional<const T&>& x, const T& v)
959 {
960   return bool(x) ? *x < v : true;
961 }
962
963 template <class T> constexpr bool operator>(const T& v, const Optional<const T&>& x)
964 {
965   return bool(x) ? v > *x : true;
966 }
967
968 template <class T> constexpr bool operator>(const Optional<const T&>& x, const T& v)
969 {
970   return bool(x) ? *x > v : false;
971 }
972
973 template <class T> constexpr bool operator<(const T& v, const Optional<const T&>& x)
974 {
975   return bool(x) ? v < *x : false;
976 }
977
978 template <class T> constexpr bool operator>=(const Optional<const T&>& x, const T& v)
979 {
980   return bool(x) ? *x >= v : false;
981 }
982
983 template <class T> constexpr bool operator<=(const T& v, const Optional<const T&>& x)
984 {
985   return bool(x) ? v <= *x : false;
986 }
987
988 template <class T> constexpr bool operator<=(const Optional<const T&>& x, const T& v)
989 {
990   return bool(x) ? *x <= v : true;
991 }
992
993 template <class T> constexpr bool operator>=(const T& v, const Optional<const T&>& x)
994 {
995   return bool(x) ? v >= *x : true;
996 }
997
998
999 // 20.5.12, Specialized algorithms
1000 template <class T>
1001 void swap(Optional<T>& x, Optional<T>& y) __NOEXCEPT_(__NOEXCEPT_(x.swap(y)))
1002 {
1003   x.swap(y);
1004 }
1005
1006
1007 template <class T>
1008 constexpr Optional<typename std::decay<T>::type> makeOptional(T&& v)
1009 {
1010   return Optional<typename std::decay<T>::type>(detail_::constexpr_forward<T>(v));
1011 }
1012
1013 template <class X>
1014 constexpr Optional<X&> makeOptional(std::reference_wrapper<X> v)
1015 {
1016   return Optional<X&>(v.get());
1017 }
1018
1019 } // namespace WTF
1020
1021 namespace std
1022 {
1023   template <typename T>
1024   struct hash<WTF::Optional<T>>
1025   {
1026     typedef typename hash<T>::result_type result_type;
1027     typedef WTF::Optional<T> argument_type;
1028
1029     constexpr result_type operator()(argument_type const& arg) const {
1030       return arg ? std::hash<T>{}(*arg) : result_type{};
1031     }
1032   };
1033
1034   template <typename T>
1035   struct hash<WTF::Optional<T&>>
1036   {
1037     typedef typename hash<T>::result_type result_type;
1038     typedef WTF::Optional<T&> argument_type;
1039
1040     constexpr result_type operator()(argument_type const& arg) const {
1041       return arg ? std::hash<T>{}(*arg) : result_type{};
1042     }
1043   };
1044 }
1045
1046 # undef TR2_OPTIONAL_REQUIRES
1047
1048 namespace WTF {
1049
1050 // -- WebKit Additions --
1051 template <class OptionalType, class Callback>
1052 ALWAYS_INLINE
1053 auto valueOrCompute(OptionalType Optional, Callback callback) -> typename OptionalType::value_type
1054 {
1055     if (Optional)
1056         return *Optional;
1057     return callback();
1058 }
1059
1060 } // namespace WTF
1061
1062 using WTF::Optional;
1063 using WTF::makeOptional;
1064 using WTF::valueOrCompute;