Tests: Add test to check shared-memory FD leaks after relayd dies
[lttng-tools.git] / src / vendor / optional.hpp
CommitLineData
9dc3671c
SM
1//
2// Copyright (c) 2014-2021 Martin Moene
3//
4// https://github.com/martinmoene/optional-lite
5//
6// Distributed under the Boost Software License, Version 1.0.
7// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8
9#pragma once
10
11#ifndef NONSTD_OPTIONAL_LITE_HPP
12#define NONSTD_OPTIONAL_LITE_HPP
13
14#define optional_lite_MAJOR 3
15#define optional_lite_MINOR 5
16#define optional_lite_PATCH 0
17
18#define optional_lite_VERSION optional_STRINGIFY(optional_lite_MAJOR) "." optional_STRINGIFY(optional_lite_MINOR) "." optional_STRINGIFY(optional_lite_PATCH)
19
20#define optional_STRINGIFY( x ) optional_STRINGIFY_( x )
21#define optional_STRINGIFY_( x ) #x
22
23// optional-lite configuration:
24
25#define optional_OPTIONAL_DEFAULT 0
26#define optional_OPTIONAL_NONSTD 1
27#define optional_OPTIONAL_STD 2
28
29// tweak header support:
30
31#ifdef __has_include
32# if __has_include(<nonstd/optional.tweak.hpp>)
33# include <nonstd/optional.tweak.hpp>
34# endif
35#define optional_HAVE_TWEAK_HEADER 1
36#else
37#define optional_HAVE_TWEAK_HEADER 0
38//# pragma message("optional.hpp: Note: Tweak header not supported.")
39#endif
40
41// optional selection and configuration:
42
43#if !defined( optional_CONFIG_SELECT_OPTIONAL )
44# define optional_CONFIG_SELECT_OPTIONAL ( optional_HAVE_STD_OPTIONAL ? optional_OPTIONAL_STD : optional_OPTIONAL_NONSTD )
45#endif
46
47// Control presence of extensions:
48
49#ifndef optional_CONFIG_NO_EXTENSIONS
50#define optional_CONFIG_NO_EXTENSIONS 0
51#endif
52
53// Control presence of exception handling (try and auto discover):
54
55#ifndef optional_CONFIG_NO_EXCEPTIONS
56# if defined(_MSC_VER)
57# include <cstddef> // for _HAS_EXCEPTIONS
58# endif
59# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
60# define optional_CONFIG_NO_EXCEPTIONS 0
61# else
62# define optional_CONFIG_NO_EXCEPTIONS 1
63# endif
64#endif
65
66// C++ language version detection (C++20 is speculative):
67// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
68
69#ifndef optional_CPLUSPLUS
70# if defined(_MSVC_LANG ) && !defined(__clang__)
71# define optional_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
72# else
73# define optional_CPLUSPLUS __cplusplus
74# endif
75#endif
76
77#define optional_CPP98_OR_GREATER ( optional_CPLUSPLUS >= 199711L )
78#define optional_CPP11_OR_GREATER ( optional_CPLUSPLUS >= 201103L )
79#define optional_CPP11_OR_GREATER_ ( optional_CPLUSPLUS >= 201103L )
80#define optional_CPP14_OR_GREATER ( optional_CPLUSPLUS >= 201402L )
81#define optional_CPP17_OR_GREATER ( optional_CPLUSPLUS >= 201703L )
82#define optional_CPP20_OR_GREATER ( optional_CPLUSPLUS >= 202000L )
83
84// C++ language version (represent 98 as 3):
85
86#define optional_CPLUSPLUS_V ( optional_CPLUSPLUS / 100 - (optional_CPLUSPLUS > 200000 ? 2000 : 1994) )
87
88// Use C++17 std::optional if available and requested:
89
90#if optional_CPP17_OR_GREATER && defined(__has_include )
91# if __has_include( <optional> )
92# define optional_HAVE_STD_OPTIONAL 1
93# else
94# define optional_HAVE_STD_OPTIONAL 0
95# endif
96#else
97# define optional_HAVE_STD_OPTIONAL 0
98#endif
99
100#define optional_USES_STD_OPTIONAL ( (optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_STD) || ((optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_DEFAULT) && optional_HAVE_STD_OPTIONAL) )
101
102//
103// in_place: code duplicated in any-lite, expected-lite, optional-lite, value-ptr-lite, variant-lite:
104//
105
106#ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
107#define nonstd_lite_HAVE_IN_PLACE_TYPES 1
108
109// C++17 std::in_place in <utility>:
110
111#if optional_CPP17_OR_GREATER
112
113#include <utility>
114
115namespace nonstd {
116
117using std::in_place;
118using std::in_place_type;
119using std::in_place_index;
120using std::in_place_t;
121using std::in_place_type_t;
122using std::in_place_index_t;
123
124#define nonstd_lite_in_place_t( T) std::in_place_t
125#define nonstd_lite_in_place_type_t( T) std::in_place_type_t<T>
126#define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
127
128#define nonstd_lite_in_place( T) std::in_place_t{}
129#define nonstd_lite_in_place_type( T) std::in_place_type_t<T>{}
130#define nonstd_lite_in_place_index(K) std::in_place_index_t<K>{}
131
132} // namespace nonstd
133
134#else // optional_CPP17_OR_GREATER
135
136#include <cstddef>
137
138namespace nonstd {
139namespace detail {
140
141template< class T >
142struct in_place_type_tag {};
143
144template< std::size_t K >
145struct in_place_index_tag {};
146
147} // namespace detail
148
149struct in_place_t {};
150
151template< class T >
152inline in_place_t in_place( detail::in_place_type_tag<T> /*unused*/ = detail::in_place_type_tag<T>() )
153{
154 return in_place_t();
155}
156
157template< std::size_t K >
158inline in_place_t in_place( detail::in_place_index_tag<K> /*unused*/ = detail::in_place_index_tag<K>() )
159{
160 return in_place_t();
161}
162
163template< class T >
164inline in_place_t in_place_type( detail::in_place_type_tag<T> /*unused*/ = detail::in_place_type_tag<T>() )
165{
166 return in_place_t();
167}
168
169template< std::size_t K >
170inline in_place_t in_place_index( detail::in_place_index_tag<K> /*unused*/ = detail::in_place_index_tag<K>() )
171{
172 return in_place_t();
173}
174
175// mimic templated typedef:
176
177#define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
178#define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
179#define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> )
180
181#define nonstd_lite_in_place( T) nonstd::in_place_type<T>
182#define nonstd_lite_in_place_type( T) nonstd::in_place_type<T>
183#define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
184
185} // namespace nonstd
186
187#endif // optional_CPP17_OR_GREATER
188#endif // nonstd_lite_HAVE_IN_PLACE_TYPES
189
190//
191// Using std::optional:
192//
193
194#if optional_USES_STD_OPTIONAL
195
196#include <optional>
197
198namespace nonstd {
199
200 using std::optional;
201 using std::bad_optional_access;
202 using std::hash;
203
204 using std::nullopt;
205 using std::nullopt_t;
206
207 using std::operator==;
208 using std::operator!=;
209 using std::operator<;
210 using std::operator<=;
211 using std::operator>;
212 using std::operator>=;
213 using std::make_optional;
214 using std::swap;
215}
216
217#else // optional_USES_STD_OPTIONAL
218
219#include <cassert>
220#include <utility>
221
222// optional-lite alignment configuration:
223
224#ifndef optional_CONFIG_MAX_ALIGN_HACK
225# define optional_CONFIG_MAX_ALIGN_HACK 0
226#endif
227
228#ifndef optional_CONFIG_ALIGN_AS
229// no default, used in #if defined()
230#endif
231
232#ifndef optional_CONFIG_ALIGN_AS_FALLBACK
233# define optional_CONFIG_ALIGN_AS_FALLBACK double
234#endif
235
236// Compiler warning suppression:
237
238#if defined(__clang__)
239# pragma clang diagnostic push
240# pragma clang diagnostic ignored "-Wundef"
241#elif defined(__GNUC__)
242# pragma GCC diagnostic push
243# pragma GCC diagnostic ignored "-Wundef"
244#elif defined(_MSC_VER )
245# pragma warning( push )
246#endif
247
248// half-open range [lo..hi):
249#define optional_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
250
251// Compiler versions:
252//
253// MSVC++ 6.0 _MSC_VER == 1200 optional_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0)
254// MSVC++ 7.0 _MSC_VER == 1300 optional_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002)
255// MSVC++ 7.1 _MSC_VER == 1310 optional_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003)
256// MSVC++ 8.0 _MSC_VER == 1400 optional_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005)
257// MSVC++ 9.0 _MSC_VER == 1500 optional_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008)
258// MSVC++ 10.0 _MSC_VER == 1600 optional_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010)
259// MSVC++ 11.0 _MSC_VER == 1700 optional_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012)
260// MSVC++ 12.0 _MSC_VER == 1800 optional_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013)
261// MSVC++ 14.0 _MSC_VER == 1900 optional_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015)
262// MSVC++ 14.1 _MSC_VER >= 1910 optional_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017)
263// MSVC++ 14.2 _MSC_VER >= 1920 optional_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019)
264
265#if defined(_MSC_VER ) && !defined(__clang__)
266# define optional_COMPILER_MSVC_VER (_MSC_VER )
267# define optional_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
268#else
269# define optional_COMPILER_MSVC_VER 0
270# define optional_COMPILER_MSVC_VERSION 0
271#endif
272
273#define optional_COMPILER_VERSION( major, minor, patch ) ( 10 * (10 * (major) + (minor) ) + (patch) )
274
275#if defined(__GNUC__) && !defined(__clang__)
276# define optional_COMPILER_GNUC_VERSION optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
277#else
278# define optional_COMPILER_GNUC_VERSION 0
279#endif
280
281#if defined(__clang__)
282# define optional_COMPILER_CLANG_VERSION optional_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
283#else
284# define optional_COMPILER_CLANG_VERSION 0
285#endif
286
287#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 140 )
288# pragma warning( disable: 4345 ) // initialization behavior changed
289#endif
290
291#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 150 )
292# pragma warning( disable: 4814 ) // in C++14 'constexpr' will not imply 'const'
293#endif
294
295// Presence of language and library features:
296
297#define optional_HAVE(FEATURE) ( optional_HAVE_##FEATURE )
298
299#ifdef _HAS_CPP0X
300# define optional_HAS_CPP0X _HAS_CPP0X
301#else
302# define optional_HAS_CPP0X 0
303#endif
304
305// Unless defined otherwise below, consider VC14 as C++11 for optional-lite:
306
307#if optional_COMPILER_MSVC_VER >= 1900
308# undef optional_CPP11_OR_GREATER
309# define optional_CPP11_OR_GREATER 1
310#endif
311
312#define optional_CPP11_90 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1500)
313#define optional_CPP11_100 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1600)
314#define optional_CPP11_110 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1700)
315#define optional_CPP11_120 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1800)
316#define optional_CPP11_140 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1900)
317#define optional_CPP11_141 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1910)
318
319#define optional_CPP14_000 (optional_CPP14_OR_GREATER)
320#define optional_CPP17_000 (optional_CPP17_OR_GREATER)
321
322// clang >= 2.9, gcc >= 4.9, msvc >= vc14.0/1900 (vs15):
323#define optional_CPP11_140_C290_G490 ((optional_CPP11_OR_GREATER_ && (optional_COMPILER_CLANG_VERSION >= 290 || optional_COMPILER_GNUC_VERSION >= 490)) || (optional_COMPILER_MSVC_VER >= 1900))
324
325// clang >= 3.5, msvc >= vc11 (vs12):
326#define optional_CPP11_110_C350 ( optional_CPP11_110 && !optional_BETWEEN( optional_COMPILER_CLANG_VERSION, 1, 350 ) )
327
328// clang >= 3.5, gcc >= 5.0, msvc >= vc11 (vs12):
329#define optional_CPP11_110_C350_G500 \
330 ( optional_CPP11_110 && \
331 !( optional_BETWEEN( optional_COMPILER_CLANG_VERSION, 1, 350 ) \
332 || optional_BETWEEN( optional_COMPILER_GNUC_VERSION , 1, 500 ) ) )
333
334// Presence of C++11 language features:
335
336#define optional_HAVE_CONSTEXPR_11 optional_CPP11_140
337#define optional_HAVE_IS_DEFAULT optional_CPP11_140
338#define optional_HAVE_NOEXCEPT optional_CPP11_140
339#define optional_HAVE_NULLPTR optional_CPP11_100
340#define optional_HAVE_REF_QUALIFIER optional_CPP11_140_C290_G490
341#define optional_HAVE_STATIC_ASSERT optional_CPP11_110
342#define optional_HAVE_INITIALIZER_LIST optional_CPP11_140
343
344// Presence of C++14 language features:
345
346#define optional_HAVE_CONSTEXPR_14 optional_CPP14_000
347
348// Presence of C++17 language features:
349
350#define optional_HAVE_NODISCARD optional_CPP17_000
351
352// Presence of C++ library features:
353
354#define optional_HAVE_CONDITIONAL optional_CPP11_120
355#define optional_HAVE_REMOVE_CV optional_CPP11_120
356#define optional_HAVE_TYPE_TRAITS optional_CPP11_90
357
358#define optional_HAVE_TR1_TYPE_TRAITS (!! optional_COMPILER_GNUC_VERSION )
359#define optional_HAVE_TR1_ADD_POINTER (!! optional_COMPILER_GNUC_VERSION )
360
361#define optional_HAVE_IS_ASSIGNABLE optional_CPP11_110_C350
362#define optional_HAVE_IS_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350
363#define optional_HAVE_IS_NOTHROW_MOVE_ASSIGNABLE optional_CPP11_110_C350
364#define optional_HAVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350
365#define optional_HAVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE optional_CPP11_110_C350_G500
366#define optional_HAVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350_G500
367
368// C++ feature usage:
369
370#if optional_HAVE( CONSTEXPR_11 )
371# define optional_constexpr constexpr
372#else
373# define optional_constexpr /*constexpr*/
374#endif
375
376#if optional_HAVE( IS_DEFAULT )
377# define optional_is_default = default;
378#else
379# define optional_is_default {}
380#endif
381
382#if optional_HAVE( CONSTEXPR_14 )
383# define optional_constexpr14 constexpr
384#else
385# define optional_constexpr14 /*constexpr*/
386#endif
387
388#if optional_HAVE( NODISCARD )
389# define optional_nodiscard [[nodiscard]]
390#else
391# define optional_nodiscard /*[[nodiscard]]*/
392#endif
393
394#if optional_HAVE( NOEXCEPT )
395# define optional_noexcept noexcept
396#else
397# define optional_noexcept /*noexcept*/
398#endif
399
400#if optional_HAVE( NULLPTR )
401# define optional_nullptr nullptr
402#else
403# define optional_nullptr NULL
404#endif
405
406#if optional_HAVE( REF_QUALIFIER )
407// NOLINTNEXTLINE( bugprone-macro-parentheses )
408# define optional_ref_qual &
409# define optional_refref_qual &&
410#else
411# define optional_ref_qual /*&*/
412# define optional_refref_qual /*&&*/
413#endif
414
415#if optional_HAVE( STATIC_ASSERT )
416# define optional_static_assert(expr, text) static_assert(expr, text);
417#else
418# define optional_static_assert(expr, text) /*static_assert(expr, text);*/
419#endif
420
421// additional includes:
422
423#if optional_CONFIG_NO_EXCEPTIONS
424// already included: <cassert>
425#else
426# include <stdexcept>
427#endif
428
429#if optional_CPP11_OR_GREATER
430# include <functional>
431#endif
432
433#if optional_HAVE( INITIALIZER_LIST )
434# include <initializer_list>
435#endif
436
437#if optional_HAVE( TYPE_TRAITS )
438# include <type_traits>
439#elif optional_HAVE( TR1_TYPE_TRAITS )
440# include <tr1/type_traits>
441#endif
442
443// Method enabling
444
445#if optional_CPP11_OR_GREATER
446
447#define optional_REQUIRES_0(...) \
448 template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
449
450#define optional_REQUIRES_T(...) \
451 , typename std::enable_if< (__VA_ARGS__), int >::type = 0
452
453#define optional_REQUIRES_R(R, ...) \
454 typename std::enable_if< (__VA_ARGS__), R>::type
455
456#define optional_REQUIRES_A(...) \
457 , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr
458
459#endif
460
461//
462// optional:
463//
464
465namespace nonstd { namespace optional_lite {
466
467namespace std11 {
468
469template< class T, T v > struct integral_constant { enum { value = v }; };
470template< bool B > struct bool_constant : integral_constant<bool, B>{};
471
472typedef bool_constant< true > true_type;
473typedef bool_constant< false > false_type;
474
475#if optional_CPP11_OR_GREATER
476 using std::move;
477#else
478 template< typename T > T & move( T & t ) { return t; }
479#endif
480
481#if optional_HAVE( CONDITIONAL )
482 using std::conditional;
483#else
484 template< bool B, typename T, typename F > struct conditional { typedef T type; };
485 template< typename T, typename F > struct conditional<false, T, F> { typedef F type; };
486#endif // optional_HAVE_CONDITIONAL
487
488#if optional_HAVE( IS_ASSIGNABLE )
489 using std::is_assignable;
490#else
491 template< class T, class U > struct is_assignable : std11::true_type{};
492#endif
493
494#if optional_HAVE( IS_MOVE_CONSTRUCTIBLE )
495 using std::is_move_constructible;
496#else
497 template< class T > struct is_move_constructible : std11::true_type{};
498#endif
499
500#if optional_HAVE( IS_NOTHROW_MOVE_ASSIGNABLE )
501 using std::is_nothrow_move_assignable;
502#else
503 template< class T > struct is_nothrow_move_assignable : std11::true_type{};
504#endif
505
506#if optional_HAVE( IS_NOTHROW_MOVE_CONSTRUCTIBLE )
507 using std::is_nothrow_move_constructible;
508#else
509 template< class T > struct is_nothrow_move_constructible : std11::true_type{};
510#endif
511
512#if optional_HAVE( IS_TRIVIALLY_COPY_CONSTRUCTIBLE )
513 using std::is_trivially_copy_constructible;
514#else
515 template< class T > struct is_trivially_copy_constructible : std11::true_type{};
516#endif
517
518#if optional_HAVE( IS_TRIVIALLY_MOVE_CONSTRUCTIBLE )
519 using std::is_trivially_move_constructible;
520#else
521 template< class T > struct is_trivially_move_constructible : std11::true_type{};
522#endif
523
524} // namespace std11
525
526#if optional_CPP11_OR_GREATER
527
528/// type traits C++17:
529
530namespace std17 {
531
532#if optional_CPP17_OR_GREATER
533
534using std::is_swappable;
535using std::is_nothrow_swappable;
536
537#elif optional_CPP11_OR_GREATER
538
539namespace detail {
540
541using std::swap;
542
543struct is_swappable
544{
545 template< typename T, typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
546 static std11::true_type test( int /*unused*/ );
547
548 template< typename >
549 static std11::false_type test(...);
550};
551
552struct is_nothrow_swappable
553{
554 // wrap noexcept(expr) in separate function as work-around for VC140 (VS2015):
555
556 template< typename T >
557 static constexpr bool satisfies()
558 {
559 return noexcept( swap( std::declval<T&>(), std::declval<T&>() ) );
560 }
561
562 template< typename T >
563 static auto test( int /*unused*/ ) -> std11::integral_constant<bool, satisfies<T>()>{}
564
565 template< typename >
566 static auto test(...) -> std11::false_type;
567};
568
569} // namespace detail
570
571// is [nothow] swappable:
572
573template< typename T >
574struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
575
576template< typename T >
577struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
578
579#endif // optional_CPP17_OR_GREATER
580
581} // namespace std17
582
583/// type traits C++20:
584
585namespace std20 {
586
587template< typename T >
588struct remove_cvref
589{
590 typedef typename std::remove_cv< typename std::remove_reference<T>::type >::type type;
591};
592
593} // namespace std20
594
595#endif // optional_CPP11_OR_GREATER
596
597/// class optional
598
599template< typename T >
600class optional;
601
602namespace detail {
603
604// C++11 emulation:
605
606struct nulltype{};
607
608template< typename Head, typename Tail >
609struct typelist
610{
611 typedef Head head;
612 typedef Tail tail;
613};
614
615#if optional_CONFIG_MAX_ALIGN_HACK
616
617// Max align, use most restricted type for alignment:
618
619#define optional_UNIQUE( name ) optional_UNIQUE2( name, __LINE__ )
620#define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line )
621#define optional_UNIQUE3( name, line ) name ## line
622
623#define optional_ALIGN_TYPE( type ) \
624 type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st )
625
626template< typename T >
627struct struct_t { T _; };
628
629union max_align_t
630{
631 optional_ALIGN_TYPE( char );
632 optional_ALIGN_TYPE( short int );
633 optional_ALIGN_TYPE( int );
634 optional_ALIGN_TYPE( long int );
635 optional_ALIGN_TYPE( float );
636 optional_ALIGN_TYPE( double );
637 optional_ALIGN_TYPE( long double );
638 optional_ALIGN_TYPE( char * );
639 optional_ALIGN_TYPE( short int * );
640 optional_ALIGN_TYPE( int * );
641 optional_ALIGN_TYPE( long int * );
642 optional_ALIGN_TYPE( float * );
643 optional_ALIGN_TYPE( double * );
644 optional_ALIGN_TYPE( long double * );
645 optional_ALIGN_TYPE( void * );
646
647#ifdef HAVE_LONG_LONG
648 optional_ALIGN_TYPE( long long );
649#endif
650
651 struct Unknown;
652
653 Unknown ( * optional_UNIQUE(_) )( Unknown );
654 Unknown * Unknown::* optional_UNIQUE(_);
655 Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown );
656
657 struct_t< Unknown ( * )( Unknown) > optional_UNIQUE(_);
658 struct_t< Unknown * Unknown::* > optional_UNIQUE(_);
659 struct_t< Unknown ( Unknown::* )(Unknown) > optional_UNIQUE(_);
660};
661
662#undef optional_UNIQUE
663#undef optional_UNIQUE2
664#undef optional_UNIQUE3
665
666#undef optional_ALIGN_TYPE
667
668#elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK
669
670// Use user-specified type for alignment:
671
672#define optional_ALIGN_AS( unused ) \
673 optional_CONFIG_ALIGN_AS
674
675#else // optional_CONFIG_MAX_ALIGN_HACK
676
677// Determine POD type to use for alignment:
678
679#define optional_ALIGN_AS( to_align ) \
680 typename type_of_size< alignment_types, alignment_of< to_align >::value >::type
681
682template< typename T >
683struct alignment_of;
684
685template< typename T >
686struct alignment_of_hack
687{
688 char c;
689 T t;
690 alignment_of_hack();
691};
692
693template< size_t A, size_t S >
694struct alignment_logic
695{
696 enum { value = A < S ? A : S };
697};
698
699template< typename T >
700struct alignment_of
701{
702 enum { value = alignment_logic<
703 sizeof( alignment_of_hack<T> ) - sizeof(T), sizeof(T) >::value };
704};
705
706template< typename List, size_t N >
707struct type_of_size
708{
709 typedef typename std11::conditional<
710 N == sizeof( typename List::head ),
711 typename List::head,
712 typename type_of_size<typename List::tail, N >::type >::type type;
713};
714
715template< size_t N >
716struct type_of_size< nulltype, N >
717{
718 typedef optional_CONFIG_ALIGN_AS_FALLBACK type;
719};
720
721template< typename T>
722struct struct_t { T _; };
723
724#define optional_ALIGN_TYPE( type ) \
725 typelist< type , typelist< struct_t< type >
726
727struct Unknown;
728
729typedef
730 optional_ALIGN_TYPE( char ),
731 optional_ALIGN_TYPE( short ),
732 optional_ALIGN_TYPE( int ),
733 optional_ALIGN_TYPE( long ),
734 optional_ALIGN_TYPE( float ),
735 optional_ALIGN_TYPE( double ),
736 optional_ALIGN_TYPE( long double ),
737
738 optional_ALIGN_TYPE( char *),
739 optional_ALIGN_TYPE( short * ),
740 optional_ALIGN_TYPE( int * ),
741 optional_ALIGN_TYPE( long * ),
742 optional_ALIGN_TYPE( float * ),
743 optional_ALIGN_TYPE( double * ),
744 optional_ALIGN_TYPE( long double * ),
745
746 optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ),
747 optional_ALIGN_TYPE( Unknown * Unknown::* ),
748 optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ),
749
750 nulltype
751 > > > > > > > > > > > > > >
752 > > > > > > > > > > > > > >
753 > > > > > >
754 alignment_types;
755
756#undef optional_ALIGN_TYPE
757
758#endif // optional_CONFIG_MAX_ALIGN_HACK
759
760/// C++03 constructed union to hold value.
761
762template< typename T >
763union storage_t
764{
765//private:
766// template< typename > friend class optional;
767
768 typedef T value_type;
769
770 storage_t() optional_is_default
771
772 explicit storage_t( value_type const & v )
773 {
774 construct_value( v );
775 }
776
777 void construct_value( value_type const & v )
778 {
779 ::new( value_ptr() ) value_type( v );
780 }
781
782#if optional_CPP11_OR_GREATER
783
784 explicit storage_t( value_type && v )
785 {
786 construct_value( std::move( v ) );
787 }
788
789 void construct_value( value_type && v )
790 {
791 ::new( value_ptr() ) value_type( std::move( v ) );
792 }
793
794 template< class... Args >
795 storage_t( nonstd_lite_in_place_t(T), Args&&... args )
796 {
797 emplace( std::forward<Args>(args)... );
798 }
799
800 template< class... Args >
801 void emplace( Args&&... args )
802 {
803 ::new( value_ptr() ) value_type( std::forward<Args>(args)... );
804 }
805
806 template< class U, class... Args >
807 void emplace( std::initializer_list<U> il, Args&&... args )
808 {
809 ::new( value_ptr() ) value_type( il, std::forward<Args>(args)... );
810 }
811
812#endif
813
814 void destruct_value()
815 {
816 value_ptr()->~T();
817 }
818
819 optional_nodiscard value_type const * value_ptr() const
820 {
821 return as<value_type>();
822 }
823
824 value_type * value_ptr()
825 {
826 return as<value_type>();
827 }
828
829 optional_nodiscard value_type const & value() const optional_ref_qual
830 {
831 return * value_ptr();
832 }
833
834 value_type & value() optional_ref_qual
835 {
836 return * value_ptr();
837 }
838
839#if optional_HAVE( REF_QUALIFIER )
840
841 optional_nodiscard value_type const && value() const optional_refref_qual
842 {
843 return std::move( value() );
844 }
845
846 value_type && value() optional_refref_qual
847 {
848 return std::move( value() );
849 }
850
851#endif
852
853#if optional_CPP11_OR_GREATER
854
855 using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type;
856 aligned_storage_t data;
857
858#elif optional_CONFIG_MAX_ALIGN_HACK
859
860 typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t;
861
862 max_align_t hack;
863 aligned_storage_t data;
864
865#else
866 typedef optional_ALIGN_AS(value_type) align_as_type;
867
868 typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t;
869 aligned_storage_t data;
870
871# undef optional_ALIGN_AS
872
873#endif // optional_CONFIG_MAX_ALIGN_HACK
874
875 optional_nodiscard void * ptr() optional_noexcept
876 {
877 return &data;
878 }
879
880 optional_nodiscard void const * ptr() const optional_noexcept
881 {
882 return &data;
883 }
884
885 template <typename U>
886 optional_nodiscard U * as()
887 {
888 return reinterpret_cast<U*>( ptr() );
889 }
890
891 template <typename U>
892 optional_nodiscard U const * as() const
893 {
894 return reinterpret_cast<U const *>( ptr() );
895 }
896};
897
898} // namespace detail
899
900/// disengaged state tag
901
902struct nullopt_t
903{
904 struct init{};
905 explicit optional_constexpr nullopt_t( init /*unused*/ ) optional_noexcept {}
906};
907
908#if optional_HAVE( CONSTEXPR_11 )
909constexpr nullopt_t nullopt{ nullopt_t::init{} };
910#else
911// extra parenthesis to prevent the most vexing parse:
912const nullopt_t nullopt(( nullopt_t::init() ));
913#endif
914
915/// optional access error
916
917#if ! optional_CONFIG_NO_EXCEPTIONS
918
919class bad_optional_access : public std::logic_error
920{
921public:
922 explicit bad_optional_access()
923 : logic_error( "bad optional access" ) {}
924};
925
926#endif //optional_CONFIG_NO_EXCEPTIONS
927
928/// optional
929
930template< typename T>
931class optional
932{
933 optional_static_assert(( !std::is_same<typename std::remove_cv<T>::type, nullopt_t>::value ),
934 "T in optional<T> must not be of type 'nullopt_t'.")
935
936 optional_static_assert(( !std::is_same<typename std::remove_cv<T>::type, in_place_t>::value ),
937 "T in optional<T> must not be of type 'in_place_t'.")
938
939 optional_static_assert(( std::is_object<T>::value && std::is_destructible<T>::value && !std::is_array<T>::value ),
940 "T in optional<T> must meet the Cpp17Destructible requirements.")
941
942private:
943 template< typename > friend class optional;
944
945 typedef void (optional::*safe_bool)() const;
946
947public:
948 typedef T value_type;
949
950 // x.x.3.1, constructors
951
952 // 1a - default construct
953 optional_constexpr optional() optional_noexcept
954 : has_value_( false )
955 , contained()
956 {}
957
958 // 1b - construct explicitly empty
959 // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
960 optional_constexpr optional( nullopt_t /*unused*/ ) optional_noexcept
961 : has_value_( false )
962 , contained()
963 {}
964
965 // 2 - copy-construct
966#if optional_CPP11_OR_GREATER
967 // template< typename U = T
968 // optional_REQUIRES_T(
969 // std::is_copy_constructible<U>::value
970 // || std11::is_trivially_copy_constructible<U>::value
971 // )
972 // >
973#endif
974 optional_constexpr14 optional( optional const & other )
975 : has_value_( other.has_value() )
976 {
977 if ( other.has_value() )
978 {
979 contained.construct_value( other.contained.value() );
980 }
981 }
982
983#if optional_CPP11_OR_GREATER
984
985 // 3 (C++11) - move-construct from optional
986 template< typename U = T
987 optional_REQUIRES_T(
988 std11::is_move_constructible<U>::value
989 || std11::is_trivially_move_constructible<U>::value
990 )
991 >
992 optional_constexpr14 optional( optional && other )
993 // NOLINTNEXTLINE( performance-noexcept-move-constructor )
994 noexcept( std11::is_nothrow_move_constructible<T>::value )
995 : has_value_( other.has_value() )
996 {
997 if ( other.has_value() )
998 {
999 contained.construct_value( std::move( other.contained.value() ) );
1000 }
1001 }
1002
1003 // 4a (C++11) - explicit converting copy-construct from optional
1004 template< typename U
1005 optional_REQUIRES_T(
1006 std::is_constructible<T, U const &>::value
1007 && !std::is_constructible<T, optional<U> & >::value
1008 && !std::is_constructible<T, optional<U> && >::value
1009 && !std::is_constructible<T, optional<U> const & >::value
1010 && !std::is_constructible<T, optional<U> const && >::value
1011 && !std::is_convertible< optional<U> & , T>::value
1012 && !std::is_convertible< optional<U> && , T>::value
1013 && !std::is_convertible< optional<U> const & , T>::value
1014 && !std::is_convertible< optional<U> const &&, T>::value
1015 && !std::is_convertible< U const & , T>::value /*=> explicit */
1016 )
1017 >
1018 explicit optional( optional<U> const & other )
1019 : has_value_( other.has_value() )
1020 {
1021 if ( other.has_value() )
1022 {
1023 contained.construct_value( T{ other.contained.value() } );
1024 }
1025 }
1026#endif // optional_CPP11_OR_GREATER
1027
1028 // 4b (C++98 and later) - non-explicit converting copy-construct from optional
1029 template< typename U
1030#if optional_CPP11_OR_GREATER
1031 optional_REQUIRES_T(
1032 std::is_constructible<T, U const &>::value
1033 && !std::is_constructible<T, optional<U> & >::value
1034 && !std::is_constructible<T, optional<U> && >::value
1035 && !std::is_constructible<T, optional<U> const & >::value
1036 && !std::is_constructible<T, optional<U> const && >::value
1037 && !std::is_convertible< optional<U> & , T>::value
1038 && !std::is_convertible< optional<U> && , T>::value
1039 && !std::is_convertible< optional<U> const & , T>::value
1040 && !std::is_convertible< optional<U> const &&, T>::value
1041 && std::is_convertible< U const & , T>::value /*=> non-explicit */
1042 )
1043#endif // optional_CPP11_OR_GREATER
1044 >
1045 // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
1046 /*non-explicit*/ optional( optional<U> const & other )
1047 : has_value_( other.has_value() )
1048 {
1049 if ( other.has_value() )
1050 {
1051 contained.construct_value( other.contained.value() );
1052 }
1053 }
1054
1055#if optional_CPP11_OR_GREATER
1056
1057 // 5a (C++11) - explicit converting move-construct from optional
1058 template< typename U
1059 optional_REQUIRES_T(
1060 std::is_constructible<T, U &&>::value
1061 && !std::is_constructible<T, optional<U> & >::value
1062 && !std::is_constructible<T, optional<U> && >::value
1063 && !std::is_constructible<T, optional<U> const & >::value
1064 && !std::is_constructible<T, optional<U> const && >::value
1065 && !std::is_convertible< optional<U> & , T>::value
1066 && !std::is_convertible< optional<U> && , T>::value
1067 && !std::is_convertible< optional<U> const & , T>::value
1068 && !std::is_convertible< optional<U> const &&, T>::value
1069 && !std::is_convertible< U &&, T>::value /*=> explicit */
1070 )
1071 >
1072 explicit optional( optional<U> && other
1073 )
1074 : has_value_( other.has_value() )
1075 {
1076 if ( other.has_value() )
1077 {
1078 contained.construct_value( T{ std::move( other.contained.value() ) } );
1079 }
1080 }
1081
1082 // 5a (C++11) - non-explicit converting move-construct from optional
1083 template< typename U
1084 optional_REQUIRES_T(
1085 std::is_constructible<T, U &&>::value
1086 && !std::is_constructible<T, optional<U> & >::value
1087 && !std::is_constructible<T, optional<U> && >::value
1088 && !std::is_constructible<T, optional<U> const & >::value
1089 && !std::is_constructible<T, optional<U> const && >::value
1090 && !std::is_convertible< optional<U> & , T>::value
1091 && !std::is_convertible< optional<U> && , T>::value
1092 && !std::is_convertible< optional<U> const & , T>::value
1093 && !std::is_convertible< optional<U> const &&, T>::value
1094 && std::is_convertible< U &&, T>::value /*=> non-explicit */
1095 )
1096 >
1097 // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
1098 /*non-explicit*/ optional( optional<U> && other )
1099 : has_value_( other.has_value() )
1100 {
1101 if ( other.has_value() )
1102 {
1103 contained.construct_value( std::move( other.contained.value() ) );
1104 }
1105 }
1106
1107 // 6 (C++11) - in-place construct
1108 template< typename... Args
1109 optional_REQUIRES_T(
1110 std::is_constructible<T, Args&&...>::value
1111 )
1112 >
1113 optional_constexpr explicit optional( nonstd_lite_in_place_t(T), Args&&... args )
1114 : has_value_( true )
1115 , contained( in_place, std::forward<Args>(args)... )
1116 {}
1117
1118 // 7 (C++11) - in-place construct, initializer-list
1119 template< typename U, typename... Args
1120 optional_REQUIRES_T(
1121 std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value
1122 )
1123 >
1124 optional_constexpr explicit optional( nonstd_lite_in_place_t(T), std::initializer_list<U> il, Args&&... args )
1125 : has_value_( true )
1126 , contained( T( il, std::forward<Args>(args)...) )
1127 {}
1128
1129 // 8a (C++11) - explicit move construct from value
1130 template< typename U = T
1131 optional_REQUIRES_T(
1132 std::is_constructible<T, U&&>::value
1133 && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
1134 && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
1135 && !std::is_convertible<U&&, T>::value /*=> explicit */
1136 )
1137 >
1138 optional_constexpr explicit optional( U && value )
1139 : has_value_( true )
1140 , contained( nonstd_lite_in_place(T), std::forward<U>( value ) )
1141 {}
1142
1143 // 8b (C++11) - non-explicit move construct from value
1144 template< typename U = T
1145 optional_REQUIRES_T(
1146 std::is_constructible<T, U&&>::value
1147 && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
1148 && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
1149 && std::is_convertible<U&&, T>::value /*=> non-explicit */
1150 )
1151 >
1152 // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
1153 optional_constexpr /*non-explicit*/ optional( U && value )
1154 : has_value_( true )
1155 , contained( nonstd_lite_in_place(T), std::forward<U>( value ) )
1156 {}
1157
1158#else // optional_CPP11_OR_GREATER
1159
1160 // 8 (C++98)
1161 optional( value_type const & value )
1162 : has_value_( true )
1163 , contained( value )
1164 {}
1165
1166#endif // optional_CPP11_OR_GREATER
1167
1168 // x.x.3.2, destructor
1169
1170 ~optional()
1171 {
1172 if ( has_value() )
1173 {
1174 contained.destruct_value();
1175 }
1176 }
1177
1178 // x.x.3.3, assignment
1179
1180 // 1 (C++98and later) - assign explicitly empty
1181 optional & operator=( nullopt_t /*unused*/) optional_noexcept
1182 {
1183 reset();
1184 return *this;
1185 }
1186
1187 // 2 (C++98and later) - copy-assign from optional
1188#if optional_CPP11_OR_GREATER
1189 // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
1190 optional_REQUIRES_R(
1191 optional &,
1192 true
1193// std::is_copy_constructible<T>::value
1194// && std::is_copy_assignable<T>::value
1195 )
1196 operator=( optional const & other )
1197 noexcept(
1198 std11::is_nothrow_move_assignable<T>::value
1199 && std11::is_nothrow_move_constructible<T>::value
1200 )
1201#else
1202 optional & operator=( optional const & other )
1203#endif
1204 {
1205 if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); }
1206 else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( *other ); }
1207 else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = *other; }
1208 return *this;
1209 }
1210
1211#if optional_CPP11_OR_GREATER
1212
1213 // 3 (C++11) - move-assign from optional
1214 // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
1215 optional_REQUIRES_R(
1216 optional &,
1217 true
1218// std11::is_move_constructible<T>::value
1219// && std::is_move_assignable<T>::value
1220 )
1221 operator=( optional && other ) noexcept
1222 {
1223 if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); }
1224 else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std::move( *other ) ); }
1225 else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = std::move( *other ); }
1226 return *this;
1227 }
1228
1229 // 4 (C++11) - move-assign from value
1230 template< typename U = T >
1231 // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
1232 optional_REQUIRES_R(
1233 optional &,
1234 std::is_constructible<T , U>::value
1235 && std11::is_assignable<T&, U>::value
1236 && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
1237 && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
1238 && !(std::is_scalar<T>::value && std::is_same<T, typename std::decay<U>::type>::value)
1239 )
1240 operator=( U && value )
1241 {
1242 if ( has_value() )
1243 {
1244 contained.value() = std::forward<U>( value );
1245 }
1246 else
1247 {
1248 initialize( T( std::forward<U>( value ) ) );
1249 }
1250 return *this;
1251 }
1252
1253#else // optional_CPP11_OR_GREATER
1254
1255 // 4 (C++98) - copy-assign from value
1256 template< typename U /*= T*/ >
1257 optional & operator=( U const & value )
1258 {
1259 if ( has_value() ) contained.value() = value;
1260 else initialize( T( value ) );
1261 return *this;
1262 }
1263
1264#endif // optional_CPP11_OR_GREATER
1265
1266 // 5 (C++98 and later) - converting copy-assign from optional
1267 template< typename U >
1268#if optional_CPP11_OR_GREATER
1269 // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
1270 optional_REQUIRES_R(
1271 optional&,
1272 std::is_constructible< T , U const &>::value
1273 && std11::is_assignable< T&, U const &>::value
1274 && !std::is_constructible<T, optional<U> & >::value
1275 && !std::is_constructible<T, optional<U> && >::value
1276 && !std::is_constructible<T, optional<U> const & >::value
1277 && !std::is_constructible<T, optional<U> const && >::value
1278 && !std::is_convertible< optional<U> & , T>::value
1279 && !std::is_convertible< optional<U> && , T>::value
1280 && !std::is_convertible< optional<U> const & , T>::value
1281 && !std::is_convertible< optional<U> const &&, T>::value
1282 && !std11::is_assignable< T&, optional<U> & >::value
1283 && !std11::is_assignable< T&, optional<U> && >::value
1284 && !std11::is_assignable< T&, optional<U> const & >::value
1285 && !std11::is_assignable< T&, optional<U> const && >::value
1286 )
1287#else
1288 optional&
1289#endif // optional_CPP11_OR_GREATER
1290 operator=( optional<U> const & other )
1291 {
1292 return *this = optional( other );
1293 }
1294
1295#if optional_CPP11_OR_GREATER
1296
1297 // 6 (C++11) - converting move-assign from optional
1298 template< typename U >
1299 // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
1300 optional_REQUIRES_R(
1301 optional&,
1302 std::is_constructible< T , U>::value
1303 && std11::is_assignable< T&, U>::value
1304 && !std::is_constructible<T, optional<U> & >::value
1305 && !std::is_constructible<T, optional<U> && >::value
1306 && !std::is_constructible<T, optional<U> const & >::value
1307 && !std::is_constructible<T, optional<U> const && >::value
1308 && !std::is_convertible< optional<U> & , T>::value
1309 && !std::is_convertible< optional<U> && , T>::value
1310 && !std::is_convertible< optional<U> const & , T>::value
1311 && !std::is_convertible< optional<U> const &&, T>::value
1312 && !std11::is_assignable< T&, optional<U> & >::value
1313 && !std11::is_assignable< T&, optional<U> && >::value
1314 && !std11::is_assignable< T&, optional<U> const & >::value
1315 && !std11::is_assignable< T&, optional<U> const && >::value
1316 )
1317 operator=( optional<U> && other )
1318 {
1319 return *this = optional( std::move( other ) );
1320 }
1321
1322 // 7 (C++11) - emplace
1323 template< typename... Args
1324 optional_REQUIRES_T(
1325 std::is_constructible<T, Args&&...>::value
1326 )
1327 >
1328 T& emplace( Args&&... args )
1329 {
1330 *this = nullopt;
1331 contained.emplace( std::forward<Args>(args)... );
1332 has_value_ = true;
1333 return contained.value();
1334 }
1335
1336 // 8 (C++11) - emplace, initializer-list
1337 template< typename U, typename... Args
1338 optional_REQUIRES_T(
1339 std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value
1340 )
1341 >
1342 T& emplace( std::initializer_list<U> il, Args&&... args )
1343 {
1344 *this = nullopt;
1345 contained.emplace( il, std::forward<Args>(args)... );
1346 has_value_ = true;
1347 return contained.value();
1348 }
1349
1350#endif // optional_CPP11_OR_GREATER
1351
1352 // x.x.3.4, swap
1353
1354 void swap( optional & other )
1355#if optional_CPP11_OR_GREATER
1356 noexcept(
1357 std11::is_nothrow_move_constructible<T>::value
1358 && std17::is_nothrow_swappable<T>::value
1359 )
1360#endif
1361 {
1362 using std::swap;
1363 if ( (has_value() == true ) && (other.has_value() == true ) ) { swap( **this, *other ); }
1364 else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std11::move(*other) ); other.reset(); }
1365 else if ( (has_value() == true ) && (other.has_value() == false) ) { other.initialize( std11::move(**this) ); reset(); }
1366 }
1367
1368 // x.x.3.5, observers
1369
1370 optional_constexpr value_type const * operator ->() const
1371 {
1372 return assert( has_value() ),
1373 contained.value_ptr();
1374 }
1375
1376 optional_constexpr14 value_type * operator ->()
1377 {
1378 return assert( has_value() ),
1379 contained.value_ptr();
1380 }
1381
1382 optional_constexpr value_type const & operator *() const optional_ref_qual
1383 {
1384 return assert( has_value() ),
1385 contained.value();
1386 }
1387
1388 optional_constexpr14 value_type & operator *() optional_ref_qual
1389 {
1390 return assert( has_value() ),
1391 contained.value();
1392 }
1393
1394#if optional_HAVE( REF_QUALIFIER )
1395
1396 optional_constexpr value_type const && operator *() const optional_refref_qual
1397 {
1398 return std::move( **this );
1399 }
1400
1401 optional_constexpr14 value_type && operator *() optional_refref_qual
1402 {
1403 return std::move( **this );
1404 }
1405
1406#endif
1407
1408#if optional_CPP11_OR_GREATER
1409 optional_constexpr explicit operator bool() const optional_noexcept
1410 {
1411 return has_value();
1412 }
1413#else
1414 optional_constexpr operator safe_bool() const optional_noexcept
1415 {
1416 return has_value() ? &optional::this_type_does_not_support_comparisons : 0;
1417 }
1418#endif
1419
1420 // NOLINTNEXTLINE( modernize-use-nodiscard )
1421 /*optional_nodiscard*/ optional_constexpr bool has_value() const optional_noexcept
1422 {
1423 return has_value_;
1424 }
1425
1426 // NOLINTNEXTLINE( modernize-use-nodiscard )
1427 /*optional_nodiscard*/ optional_constexpr14 value_type const & value() const optional_ref_qual
1428 {
1429#if optional_CONFIG_NO_EXCEPTIONS
1430 assert( has_value() );
1431#else
1432 if ( ! has_value() )
1433 {
1434 throw bad_optional_access();
1435 }
1436#endif
1437 return contained.value();
1438 }
1439
1440 optional_constexpr14 value_type & value() optional_ref_qual
1441 {
1442#if optional_CONFIG_NO_EXCEPTIONS
1443 assert( has_value() );
1444#else
1445 if ( ! has_value() )
1446 {
1447 throw bad_optional_access();
1448 }
1449#endif
1450 return contained.value();
1451 }
1452
1453#if optional_HAVE( REF_QUALIFIER ) && ( !optional_COMPILER_GNUC_VERSION || optional_COMPILER_GNUC_VERSION >= 490 )
1454
1455 // NOLINTNEXTLINE( modernize-use-nodiscard )
1456 /*optional_nodiscard*/ optional_constexpr value_type const && value() const optional_refref_qual
1457 {
1458 return std::move( value() );
1459 }
1460
1461 optional_constexpr14 value_type && value() optional_refref_qual
1462 {
1463 return std::move( value() );
1464 }
1465
1466#endif
1467
1468#if optional_HAVE( REF_QUALIFIER )
1469
1470 template< typename U >
1471 optional_constexpr value_type value_or( U && v ) const optional_ref_qual
1472 {
1473 return has_value() ? contained.value() : static_cast<T>(std::forward<U>( v ) );
1474 }
1475
1476 template< typename U >
1477 optional_constexpr14 value_type value_or( U && v ) optional_refref_qual
1478 {
1479#if optional_COMPILER_CLANG_VERSION
1480 return has_value() ? /*std::move*/( contained.value() ) : static_cast<T>(std::forward<U>( v ) );
1481#else
1482 return has_value() ? std::move( contained.value() ) : static_cast<T>(std::forward<U>( v ) );
1483#endif
1484 }
1485
1486#else
1487
1488 template< typename U >
1489 optional_constexpr value_type value_or( U const & v ) const
1490 {
1491 return has_value() ? contained.value() : static_cast<value_type>( v );
1492 }
1493
1494#endif // optional_HAVE( REF_QUALIFIER )
1495
1496#if !optional_CONFIG_NO_EXTENSIONS
1497#if optional_HAVE( REF_QUALIFIER )
1498
1499 template< typename F >
1500 optional_constexpr value_type value_or_eval( F f ) const &
1501 {
1502 return has_value() ? contained.value() : f();
1503 }
1504
1505 template< typename F >
1506 optional_constexpr14 value_type value_or_eval( F f ) &&
1507 {
1508 if ( has_value() )
1509 {
1510 return std::move( contained.value() );
1511 }
1512 else
1513 {
1514 return f();
1515 }
1516 }
1517
1518#else
1519
1520 template< typename F >
1521 optional_constexpr value_type value_or_eval( F f ) const
1522 {
1523 return has_value() ? contained.value() : f();
1524 }
1525
1526#endif // optional_HAVE( REF_QUALIFIER )
1527#endif // !optional_CONFIG_NO_EXTENSIONS
1528
1529 // x.x.3.6, modifiers
1530
1531 void reset() optional_noexcept
1532 {
1533 if ( has_value() )
1534 {
1535 contained.destruct_value();
1536 }
1537
1538 has_value_ = false;
1539 }
1540
1541private:
1542 void this_type_does_not_support_comparisons() const {}
1543
1544 template< typename V >
1545 void initialize( V const & value )
1546 {
1547 assert( ! has_value() );
1548 contained.construct_value( value );
1549 has_value_ = true;
1550 }
1551
1552#if optional_CPP11_OR_GREATER
1553 template< typename V >
1554 void initialize( V && value )
1555 {
1556 assert( ! has_value() );
1557 contained.construct_value( std::move( value ) );
1558 has_value_ = true;
1559 }
1560
1561#endif
1562
1563private:
1564 bool has_value_;
1565 detail::storage_t< value_type > contained;
1566
1567};
1568
1569// Relational operators
1570
1571template< typename T, typename U >
1572optional_nodiscard optional_constexpr bool operator==( optional<T> const & x, optional<U> const & y )
1573{
1574 return bool(x) != bool(y) ? false : !bool( x ) ? true : *x == *y;
1575}
1576
1577template< typename T, typename U >
1578optional_nodiscard optional_constexpr bool operator!=( optional<T> const & x, optional<U> const & y )
1579{
1580 return !(x == y);
1581}
1582
1583template< typename T, typename U >
1584optional_nodiscard optional_constexpr bool operator<( optional<T> const & x, optional<U> const & y )
1585{
1586 return (!y) ? false : (!x) ? true : *x < *y;
1587}
1588
1589template< typename T, typename U >
1590optional_nodiscard optional_constexpr bool operator>( optional<T> const & x, optional<U> const & y )
1591{
1592 return (y < x);
1593}
1594
1595template< typename T, typename U >
1596optional_nodiscard optional_constexpr bool operator<=( optional<T> const & x, optional<U> const & y )
1597{
1598 return !(y < x);
1599}
1600
1601template< typename T, typename U >
1602optional_nodiscard optional_constexpr bool operator>=( optional<T> const & x, optional<U> const & y )
1603{
1604 return !(x < y);
1605}
1606
1607// Comparison with nullopt
1608
1609template< typename T >
1610optional_nodiscard optional_constexpr bool operator==( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
1611{
1612 return (!x);
1613}
1614
1615template< typename T >
1616optional_nodiscard optional_constexpr bool operator==( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
1617{
1618 return (!x);
1619}
1620
1621template< typename T >
1622optional_nodiscard optional_constexpr bool operator!=( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
1623{
1624 return bool(x);
1625}
1626
1627template< typename T >
1628optional_nodiscard optional_constexpr bool operator!=( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
1629{
1630 return bool(x);
1631}
1632
1633template< typename T >
1634optional_nodiscard optional_constexpr bool operator<( optional<T> const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept
1635{
1636 return false;
1637}
1638
1639template< typename T >
1640optional_nodiscard optional_constexpr bool operator<( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
1641{
1642 return bool(x);
1643}
1644
1645template< typename T >
1646optional_nodiscard optional_constexpr bool operator<=( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
1647{
1648 return (!x);
1649}
1650
1651template< typename T >
1652optional_nodiscard optional_constexpr bool operator<=( nullopt_t /*unused*/, optional<T> const & /*unused*/ ) optional_noexcept
1653{
1654 return true;
1655}
1656
1657template< typename T >
1658optional_nodiscard optional_constexpr bool operator>( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
1659{
1660 return bool(x);
1661}
1662
1663template< typename T >
1664optional_nodiscard optional_constexpr bool operator>( nullopt_t /*unused*/, optional<T> const & /*unused*/ ) optional_noexcept
1665{
1666 return false;
1667}
1668
1669template< typename T >
1670optional_nodiscard optional_constexpr bool operator>=( optional<T> const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept
1671{
1672 return true;
1673}
1674
1675template< typename T >
1676optional_nodiscard optional_constexpr bool operator>=( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
1677{
1678 return (!x);
1679}
1680
1681// Comparison with T
1682
1683template< typename T, typename U >
1684optional_nodiscard optional_constexpr bool operator==( optional<T> const & x, U const & v )
1685{
1686 return bool(x) ? *x == v : false;
1687}
1688
1689template< typename T, typename U >
1690optional_nodiscard optional_constexpr bool operator==( U const & v, optional<T> const & x )
1691{
1692 return bool(x) ? v == *x : false;
1693}
1694
1695template< typename T, typename U >
1696optional_nodiscard optional_constexpr bool operator!=( optional<T> const & x, U const & v )
1697{
1698 return bool(x) ? *x != v : true;
1699}
1700
1701template< typename T, typename U >
1702optional_nodiscard optional_constexpr bool operator!=( U const & v, optional<T> const & x )
1703{
1704 return bool(x) ? v != *x : true;
1705}
1706
1707template< typename T, typename U >
1708optional_nodiscard optional_constexpr bool operator<( optional<T> const & x, U const & v )
1709{
1710 return bool(x) ? *x < v : true;
1711}
1712
1713template< typename T, typename U >
1714optional_nodiscard optional_constexpr bool operator<( U const & v, optional<T> const & x )
1715{
1716 return bool(x) ? v < *x : false;
1717}
1718
1719template< typename T, typename U >
1720optional_nodiscard optional_constexpr bool operator<=( optional<T> const & x, U const & v )
1721{
1722 return bool(x) ? *x <= v : true;
1723}
1724
1725template< typename T, typename U >
1726optional_nodiscard optional_constexpr bool operator<=( U const & v, optional<T> const & x )
1727{
1728 return bool(x) ? v <= *x : false;
1729}
1730
1731template< typename T, typename U >
1732optional_nodiscard optional_constexpr bool operator>( optional<T> const & x, U const & v )
1733{
1734 return bool(x) ? *x > v : false;
1735}
1736
1737template< typename T, typename U >
1738optional_nodiscard optional_constexpr bool operator>( U const & v, optional<T> const & x )
1739{
1740 return bool(x) ? v > *x : true;
1741}
1742
1743template< typename T, typename U >
1744optional_nodiscard optional_constexpr bool operator>=( optional<T> const & x, U const & v )
1745{
1746 return bool(x) ? *x >= v : false;
1747}
1748
1749template< typename T, typename U >
1750optional_nodiscard optional_constexpr bool operator>=( U const & v, optional<T> const & x )
1751{
1752 return bool(x) ? v >= *x : true;
1753}
1754
1755// Specialized algorithms
1756
1757template< typename T
1758#if optional_CPP11_OR_GREATER
1759 optional_REQUIRES_T(
1760 std11::is_move_constructible<T>::value
1761 && std17::is_swappable<T>::value )
1762#endif
1763>
1764void swap( optional<T> & x, optional<T> & y )
1765#if optional_CPP11_OR_GREATER
1766 noexcept( noexcept( x.swap(y) ) )
1767#endif
1768{
1769 x.swap( y );
1770}
1771
1772#if optional_CPP11_OR_GREATER
1773
1774template< typename T >
1775optional_constexpr optional< typename std::decay<T>::type > make_optional( T && value )
1776{
1777 return optional< typename std::decay<T>::type >( std::forward<T>( value ) );
1778}
1779
1780template< typename T, typename...Args >
1781optional_constexpr optional<T> make_optional( Args&&... args )
1782{
1783 return optional<T>( nonstd_lite_in_place(T), std::forward<Args>(args)...);
1784}
1785
1786template< typename T, typename U, typename... Args >
1787optional_constexpr optional<T> make_optional( std::initializer_list<U> il, Args&&... args )
1788{
1789 return optional<T>( nonstd_lite_in_place(T), il, std::forward<Args>(args)...);
1790}
1791
1792#else
1793
1794template< typename T >
1795optional<T> make_optional( T const & value )
1796{
1797 return optional<T>( value );
1798}
1799
1800#endif // optional_CPP11_OR_GREATER
1801
1802} // namespace optional_lite
1803
1804using optional_lite::optional;
1805using optional_lite::nullopt_t;
1806using optional_lite::nullopt;
1807
1808#if ! optional_CONFIG_NO_EXCEPTIONS
1809using optional_lite::bad_optional_access;
1810#endif
1811
1812using optional_lite::make_optional;
1813
1814} // namespace nonstd
1815
1816#if optional_CPP11_OR_GREATER
1817
1818// specialize the std::hash algorithm:
1819
1820namespace std {
1821
1822template< class T >
1823struct hash< nonstd::optional<T> >
1824{
1825public:
1826 std::size_t operator()( nonstd::optional<T> const & v ) const optional_noexcept
1827 {
1828 return bool( v ) ? std::hash<T>{}( *v ) : 0;
1829 }
1830};
1831
1832} //namespace std
1833
1834#endif // optional_CPP11_OR_GREATER
1835
1836#if defined(__clang__)
1837# pragma clang diagnostic pop
1838#elif defined(__GNUC__)
1839# pragma GCC diagnostic pop
1840#elif defined(_MSC_VER )
1841# pragma warning( pop )
1842#endif
1843
1844#endif // optional_USES_STD_OPTIONAL
1845
1846#endif // NONSTD_OPTIONAL_LITE_HPP
This page took 0.09603 seconds and 4 git commands to generate.