Use Optional::hasValue() instead of Optional::has_value()
[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 hasValue() const __NOEXCEPT { return initialized(); }
510
511   constexpr T const* operator ->() const {
512     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
513     return dataptr();
514   }
515
516   OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() {
517     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
518     return dataptr();
519   }
520
521   constexpr T const& operator *() const& {
522     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
523     return contained_val();
524   }
525
526   OPTIONAL_MUTABLE_CONSTEXPR T& operator *() & {
527     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
528     return contained_val();
529   }
530
531   OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && {
532     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
533     return detail_::constexpr_move(contained_val());
534   }
535
536   constexpr T const& value() const& {
537     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
538     return contained_val();
539   }
540
541   OPTIONAL_MUTABLE_CONSTEXPR T& value() & {
542     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
543     return contained_val();
544   }
545
546   OPTIONAL_MUTABLE_CONSTEXPR T&& value() && {
547     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(initialized());
548     return std::move(contained_val());
549   }
550
551 # if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
552
553   template <class V>
554   constexpr T valueOr(V&& v) const&
555   {
556     return *this ? **this : detail_::convert<T>(detail_::constexpr_forward<V>(v));
557   }
558
559   template <class V>
560   OPTIONAL_MUTABLE_CONSTEXPR T valueOr(V&& v) &&
561   {
562     return *this ? detail_::constexpr_move(const_cast<Optional<T>&>(*this).contained_val()) : detail_::convert<T>(detail_::constexpr_forward<V>(v));
563   }
564
565 # else
566
567   template <class V>
568   constexpr T valueOr(V&& v) const
569   {
570     return *this ? **this : detail_::convert<T>(detail_::constexpr_forward<V>(v));
571   }
572
573 # endif
574
575   // 20.6.3.6, modifiers
576   void reset() __NOEXCEPT { clear(); }
577 };
578
579
580 template <class T>
581 class Optional<T&>
582 {
583   static_assert( !std::is_same<T, nullopt_t>::value, "bad T" );
584   static_assert( !std::is_same<T, std::in_place_t>::value, "bad T" );
585   T* ref;
586
587 public:
588
589   // 20.5.5.1, construction/destruction
590   constexpr Optional() __NOEXCEPT : ref(nullptr) {}
591
592   constexpr Optional(nullopt_t) __NOEXCEPT : ref(nullptr) {}
593
594   constexpr Optional(T& v) __NOEXCEPT : ref(detail_::static_addressof(v)) {}
595
596   Optional(T&&) = delete;
597
598   constexpr Optional(const Optional& rhs) __NOEXCEPT : ref(rhs.ref) {}
599
600   explicit constexpr Optional(std::in_place_t, T& v) __NOEXCEPT : ref(detail_::static_addressof(v)) {}
601
602   explicit Optional(std::in_place_t, T&&) = delete;
603
604   ~Optional() = default;
605
606   // 20.5.5.2, mutation
607   Optional& operator=(nullopt_t) __NOEXCEPT {
608     ref = nullptr;
609     return *this;
610   }
611
612   // Optional& operator=(const Optional& rhs) __NOEXCEPT {
613     // ref = rhs.ref;
614     // return *this;
615   // }
616
617   // Optional& operator=(Optional&& rhs) __NOEXCEPT {
618     // ref = rhs.ref;
619     // return *this;
620   // }
621
622   template <typename U>
623   auto operator=(U&& rhs) __NOEXCEPT
624   -> typename std::enable_if
625   <
626     std::is_same<typename std::decay<U>::type, Optional<T&>>::value,
627     Optional&
628   >::type
629   {
630     ref = rhs.ref;
631     return *this;
632   }
633
634   template <typename U>
635   auto operator=(U&& rhs) __NOEXCEPT
636   -> typename std::enable_if
637   <
638     !std::is_same<typename std::decay<U>::type, Optional<T&>>::value,
639     Optional&
640   >::type
641   = delete;
642
643   void emplace(T& v) __NOEXCEPT {
644     ref = detail_::static_addressof(v);
645   }
646
647   void emplace(T&&) = delete;
648
649
650   void swap(Optional<T&>& rhs) __NOEXCEPT
651   {
652     std::swap(ref, rhs.ref);
653   }
654
655   // 20.5.5.3, observers
656   constexpr T* operator->() const {
657     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(ref);
658     return ref;
659   }
660
661   constexpr T& operator*() const {
662     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(ref);
663     return *ref;
664   }
665
666   constexpr T& value() const {
667     RELEASE_ASSERT_UNDER_CONSTEXPR_CONTEXT(ref());
668     return *ref;
669   }
670
671   explicit constexpr operator bool() const __NOEXCEPT {
672     return ref != nullptr;
673   }
674
675   constexpr bool hasValue() const __NOEXCEPT {
676     return ref != nullptr;
677   }
678
679   template <class V>
680   constexpr typename std::decay<T>::type valueOr(V&& v) const
681   {
682     return *this ? **this : detail_::convert<typename std::decay<T>::type>(detail_::constexpr_forward<V>(v));
683   }
684
685   // x.x.x.x, modifiers
686   void reset() __NOEXCEPT { ref = nullptr; }
687 };
688
689
690 template <class T>
691 class Optional<T&&>
692 {
693   static_assert( sizeof(T) == 0, "Optional rvalue references disallowed" );
694 };
695
696
697 // 20.5.8, Relational operators
698 template <class T> constexpr bool operator==(const Optional<T>& x, const Optional<T>& y)
699 {
700   return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y;
701 }
702
703 template <class T> constexpr bool operator!=(const Optional<T>& x, const Optional<T>& y)
704 {
705   return !(x == y);
706 }
707
708 template <class T> constexpr bool operator<(const Optional<T>& x, const Optional<T>& y)
709 {
710   return (!y) ? false : (!x) ? true : *x < *y;
711 }
712
713 template <class T> constexpr bool operator>(const Optional<T>& x, const Optional<T>& y)
714 {
715   return (y < x);
716 }
717
718 template <class T> constexpr bool operator<=(const Optional<T>& x, const Optional<T>& y)
719 {
720   return !(y < x);
721 }
722
723 template <class T> constexpr bool operator>=(const Optional<T>& x, const Optional<T>& y)
724 {
725   return !(x < y);
726 }
727
728
729 // 20.5.9, Comparison with nullopt
730 template <class T> constexpr bool operator==(const Optional<T>& x, nullopt_t) __NOEXCEPT
731 {
732   return (!x);
733 }
734
735 template <class T> constexpr bool operator==(nullopt_t, const Optional<T>& x) __NOEXCEPT
736 {
737   return (!x);
738 }
739
740 template <class T> constexpr bool operator!=(const Optional<T>& x, nullopt_t) __NOEXCEPT
741 {
742   return bool(x);
743 }
744
745 template <class T> constexpr bool operator!=(nullopt_t, const Optional<T>& x) __NOEXCEPT
746 {
747   return bool(x);
748 }
749
750 template <class T> constexpr bool operator<(const Optional<T>&, nullopt_t) __NOEXCEPT
751 {
752   return false;
753 }
754
755 template <class T> constexpr bool operator<(nullopt_t, const Optional<T>& x) __NOEXCEPT
756 {
757   return bool(x);
758 }
759
760 template <class T> constexpr bool operator<=(const Optional<T>& x, nullopt_t) __NOEXCEPT
761 {
762   return (!x);
763 }
764
765 template <class T> constexpr bool operator<=(nullopt_t, const Optional<T>&) __NOEXCEPT
766 {
767   return true;
768 }
769
770 template <class T> constexpr bool operator>(const Optional<T>& x, nullopt_t) __NOEXCEPT
771 {
772   return bool(x);
773 }
774
775 template <class T> constexpr bool operator>(nullopt_t, const Optional<T>&) __NOEXCEPT
776 {
777   return false;
778 }
779
780 template <class T> constexpr bool operator>=(const Optional<T>&, nullopt_t) __NOEXCEPT
781 {
782   return true;
783 }
784
785 template <class T> constexpr bool operator>=(nullopt_t, const Optional<T>& x) __NOEXCEPT
786 {
787   return (!x);
788 }
789
790
791
792 // 20.5.10, Comparison with T
793 template <class T> constexpr bool operator==(const Optional<T>& x, const T& v)
794 {
795   return bool(x) ? *x == v : false;
796 }
797
798 template <class T> constexpr bool operator==(const T& v, const Optional<T>& x)
799 {
800   return bool(x) ? v == *x : false;
801 }
802
803 template <class T> constexpr bool operator!=(const Optional<T>& x, const T& v)
804 {
805   return bool(x) ? *x != v : true;
806 }
807
808 template <class T> constexpr bool operator!=(const T& v, const Optional<T>& x)
809 {
810   return bool(x) ? v != *x : true;
811 }
812
813 template <class T> constexpr bool operator<(const Optional<T>& x, const T& v)
814 {
815   return bool(x) ? *x < v : true;
816 }
817
818 template <class T> constexpr bool operator>(const T& v, const Optional<T>& x)
819 {
820   return bool(x) ? v > *x : true;
821 }
822
823 template <class T> constexpr bool operator>(const Optional<T>& x, const T& v)
824 {
825   return bool(x) ? *x > v : false;
826 }
827
828 template <class T> constexpr bool operator<(const T& v, const Optional<T>& x)
829 {
830   return bool(x) ? v < *x : false;
831 }
832
833 template <class T> constexpr bool operator>=(const Optional<T>& x, const T& v)
834 {
835   return bool(x) ? *x >= v : false;
836 }
837
838 template <class T> constexpr bool operator<=(const T& v, const Optional<T>& x)
839 {
840   return bool(x) ? v <= *x : false;
841 }
842
843 template <class T> constexpr bool operator<=(const Optional<T>& x, const T& v)
844 {
845   return bool(x) ? *x <= v : true;
846 }
847
848 template <class T> constexpr bool operator>=(const T& v, const Optional<T>& x)
849 {
850   return bool(x) ? v >= *x : true;
851 }
852
853
854 // Comparison of Optional<T&> with T
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 template <class T> constexpr bool operator<(const Optional<T&>& x, const T& v)
876 {
877   return bool(x) ? *x < v : true;
878 }
879
880 template <class T> constexpr bool operator>(const T& v, const Optional<T&>& x)
881 {
882   return bool(x) ? v > *x : true;
883 }
884
885 template <class T> constexpr bool operator>(const Optional<T&>& x, const T& v)
886 {
887   return bool(x) ? *x > v : false;
888 }
889
890 template <class T> constexpr bool operator<(const T& v, const Optional<T&>& x)
891 {
892   return bool(x) ? v < *x : false;
893 }
894
895 template <class T> constexpr bool operator>=(const Optional<T&>& x, const T& v)
896 {
897   return bool(x) ? *x >= v : false;
898 }
899
900 template <class T> constexpr bool operator<=(const T& v, const Optional<T&>& x)
901 {
902   return bool(x) ? v <= *x : false;
903 }
904
905 template <class T> constexpr bool operator<=(const Optional<T&>& x, const T& v)
906 {
907   return bool(x) ? *x <= v : true;
908 }
909
910 template <class T> constexpr bool operator>=(const T& v, const Optional<T&>& x)
911 {
912   return bool(x) ? v >= *x : true;
913 }
914
915 // Comparison of Optional<T const&> with T
916 template <class T> constexpr bool operator==(const Optional<const T&>& x, const T& v)
917 {
918   return bool(x) ? *x == v : false;
919 }
920
921 template <class T> constexpr bool operator==(const T& v, const Optional<const T&>& x)
922 {
923   return bool(x) ? v == *x : false;
924 }
925
926 template <class T> constexpr bool operator!=(const Optional<const T&>& x, const T& v)
927 {
928   return bool(x) ? *x != v : true;
929 }
930
931 template <class T> constexpr bool operator!=(const T& v, const Optional<const T&>& x)
932 {
933   return bool(x) ? v != *x : true;
934 }
935
936 template <class T> constexpr bool operator<(const Optional<const T&>& x, const T& v)
937 {
938   return bool(x) ? *x < v : true;
939 }
940
941 template <class T> constexpr bool operator>(const T& v, const Optional<const T&>& x)
942 {
943   return bool(x) ? v > *x : true;
944 }
945
946 template <class T> constexpr bool operator>(const Optional<const T&>& x, const T& v)
947 {
948   return bool(x) ? *x > v : false;
949 }
950
951 template <class T> constexpr bool operator<(const T& v, const Optional<const T&>& x)
952 {
953   return bool(x) ? v < *x : false;
954 }
955
956 template <class T> constexpr bool operator>=(const Optional<const T&>& x, const T& v)
957 {
958   return bool(x) ? *x >= v : false;
959 }
960
961 template <class T> constexpr bool operator<=(const T& v, const Optional<const T&>& x)
962 {
963   return bool(x) ? v <= *x : false;
964 }
965
966 template <class T> constexpr bool operator<=(const Optional<const T&>& x, const T& v)
967 {
968   return bool(x) ? *x <= v : true;
969 }
970
971 template <class T> constexpr bool operator>=(const T& v, const Optional<const T&>& x)
972 {
973   return bool(x) ? v >= *x : true;
974 }
975
976
977 // 20.5.12, Specialized algorithms
978 template <class T>
979 void swap(Optional<T>& x, Optional<T>& y) __NOEXCEPT_(__NOEXCEPT_(x.swap(y)))
980 {
981   x.swap(y);
982 }
983
984
985 template <class T>
986 constexpr Optional<typename std::decay<T>::type> makeOptional(T&& v)
987 {
988   return Optional<typename std::decay<T>::type>(detail_::constexpr_forward<T>(v));
989 }
990
991 template <class X>
992 constexpr Optional<X&> makeOptional(std::reference_wrapper<X> v)
993 {
994   return Optional<X&>(v.get());
995 }
996
997 } // namespace WTF
998
999 namespace std
1000 {
1001   template <typename T>
1002   struct hash<WTF::Optional<T>>
1003   {
1004     typedef typename hash<T>::result_type result_type;
1005     typedef WTF::Optional<T> argument_type;
1006
1007     constexpr result_type operator()(argument_type const& arg) const {
1008       return arg ? std::hash<T>{}(*arg) : result_type{};
1009     }
1010   };
1011
1012   template <typename T>
1013   struct hash<WTF::Optional<T&>>
1014   {
1015     typedef typename hash<T>::result_type result_type;
1016     typedef WTF::Optional<T&> argument_type;
1017
1018     constexpr result_type operator()(argument_type const& arg) const {
1019       return arg ? std::hash<T>{}(*arg) : result_type{};
1020     }
1021   };
1022 }
1023
1024 # undef TR2_OPTIONAL_REQUIRES
1025
1026 namespace WTF {
1027
1028 // -- WebKit Additions --
1029 template <class OptionalType, class Callback>
1030 ALWAYS_INLINE
1031 auto valueOrCompute(OptionalType Optional, Callback callback) -> typename OptionalType::value_type
1032 {
1033     if (Optional)
1034         return *Optional;
1035     return callback();
1036 }
1037
1038 } // namespace WTF
1039
1040 using WTF::Optional;
1041 using WTF::makeOptional;
1042 using WTF::valueOrCompute;