NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
variant.hpp
Go to the documentation of this file.
1 // Copyright 2016-2018 by Martin Moene
2 //
3 // https://github.com/martinmoene/variant-lite
4 //
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 
8 #pragma once
9 
10 #ifndef NONSTD_VARIANT_LITE_HPP
11 #define NONSTD_VARIANT_LITE_HPP
12 
13 #define variant_lite_MAJOR 1
14 #define variant_lite_MINOR 1
15 #define variant_lite_PATCH 0
16 
17 #define variant_lite_VERSION variant_STRINGIFY(variant_lite_MAJOR) "." variant_STRINGIFY(variant_lite_MINOR) "." variant_STRINGIFY(variant_lite_PATCH)
18 
19 #define variant_STRINGIFY( x ) variant_STRINGIFY_( x )
20 #define variant_STRINGIFY_( x ) #x
21 
22 // variant-lite configuration:
23 
24 #define variant_VARIANT_DEFAULT 0
25 #define variant_VARIANT_NONSTD 1
26 #define variant_VARIANT_STD 2
27 
28 #if !defined( variant_CONFIG_SELECT_VARIANT )
29 # define variant_CONFIG_SELECT_VARIANT ( variant_HAVE_STD_VARIANT ? variant_VARIANT_STD : variant_VARIANT_NONSTD )
30 #endif
31 
32 #ifndef variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO
33 # define variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO 0
34 #endif
35 
36 #ifndef variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO
37 # define variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO 0
38 #endif
39 
40 // C++ language version detection (C++20 is speculative):
41 // Note: VC14.0/1900 (VS2015) lacks too much from C++14.
42 
43 #ifndef variant_CPLUSPLUS
44 # if defined(_MSVC_LANG ) && !defined(__clang__)
45 # define variant_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
46 # else
47 # define variant_CPLUSPLUS __cplusplus
48 # endif
49 #endif
50 
51 #define variant_CPP98_OR_GREATER ( variant_CPLUSPLUS >= 199711L )
52 #define variant_CPP11_OR_GREATER ( variant_CPLUSPLUS >= 201103L )
53 #define variant_CPP11_OR_GREATER_ ( variant_CPLUSPLUS >= 201103L )
54 #define variant_CPP14_OR_GREATER ( variant_CPLUSPLUS >= 201402L )
55 #define variant_CPP17_OR_GREATER ( variant_CPLUSPLUS >= 201703L )
56 #define variant_CPP20_OR_GREATER ( variant_CPLUSPLUS >= 202000L )
57 
58 // Use C++17 std::variant if available and requested:
59 
60 #if variant_CPP17_OR_GREATER && defined(__has_include )
61 # if __has_include( <variant> )
62 # define variant_HAVE_STD_VARIANT 1
63 # else
64 # define variant_HAVE_STD_VARIANT 0
65 # endif
66 #else
67 # define variant_HAVE_STD_VARIANT 0
68 #endif
69 
70 #define variant_USES_STD_VARIANT ( (variant_CONFIG_SELECT_VARIANT == variant_VARIANT_STD) || ((variant_CONFIG_SELECT_VARIANT == variant_VARIANT_DEFAULT) && variant_HAVE_STD_VARIANT) )
71 
72 //
73 // in_place: code duplicated in any-lite, expected-lite, optional-lite, value-ptr-lite, variant-lite:
74 //
75 
76 #ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
77 #define nonstd_lite_HAVE_IN_PLACE_TYPES 1
78 
79 // C++17 std::in_place in <utility>:
80 
81 #if variant_CPP17_OR_GREATER
82 
83 #include <utility>
84 
85 namespace nonstd {
86 
87 using std::in_place;
88 using std::in_place_type;
90 using std::in_place_t;
91 using std::in_place_type_t;
92 using std::in_place_index_t;
93 
94 #define nonstd_lite_in_place_t( T) std::in_place_t
95 #define nonstd_lite_in_place_type_t( T) std::in_place_type_t<T>
96 #define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
97 
98 #define nonstd_lite_in_place( T) std::in_place_t{}
99 #define nonstd_lite_in_place_type( T) std::in_place_type_t<T>{}
100 #define nonstd_lite_in_place_index(K) std::in_place_index_t<K>{}
101 
102 } // namespace nonstd
103 
104 #else // variant_CPP17_OR_GREATER
105 
106 #include <cstddef>
107 
108 namespace nonstd {
109 namespace detail {
110 
111 template< class T >
112 struct in_place_type_tag {};
113 
114 template< std::size_t K >
115 struct in_place_index_tag {};
116 
117 } // namespace detail
118 
119 struct in_place_t {};
120 
121 template< class T >
122 inline in_place_t in_place( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
123 {
124  return in_place_t();
125 }
126 
127 template< std::size_t K >
128 inline in_place_t in_place( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
129 {
130  return in_place_t();
131 }
132 
133 template< class T >
134 inline in_place_t in_place_type( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
135 {
136  return in_place_t();
137 }
138 
139 template< std::size_t K >
140 inline in_place_t in_place_index( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
141 {
142  return in_place_t();
143 }
144 
145 // mimic templated typedef:
146 
147 #define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
148 #define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
149 #define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> )
150 
151 #define nonstd_lite_in_place( T) nonstd::in_place_type<T>
152 #define nonstd_lite_in_place_type( T) nonstd::in_place_type<T>
153 #define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
154 
155 } // namespace nonstd
156 
157 #endif // variant_CPP17_OR_GREATER
158 #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
159 
160 //
161 // Use C++17 std::variant:
162 //
163 
164 #if variant_USES_STD_VARIANT
165 
166 #include <functional> // std::hash<>
167 #include <variant>
168 
169 #if ! variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO
170 # define variant_size_V(T) nonstd::variant_size<T>::value
171 #endif
172 
173 #if ! variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO
174 # define variant_alternative_T(K,T) typename nonstd::variant_alternative<K,T >::type
175 #endif
176 
177 namespace nonstd {
178 
179  using std::variant;
180  using std::monostate;
181  using std::bad_variant_access;
182  using std::variant_size;
183  using std::variant_size_v;
184  using std::variant_alternative;
185  using std::variant_alternative_t;
186  using std::hash;
187 
188  using std::visit;
190  using std::get;
191  using std::get_if;
192  using std::operator==;
193  using std::operator!=;
194  using std::operator<;
195  using std::operator<=;
196  using std::operator>;
197  using std::operator>=;
198  using std::swap;
199 
200  constexpr auto variant_npos = std::variant_npos;
201 }
202 
203 #else // variant_USES_STD_VARIANT
204 
205 #include <cstddef>
206 #include <limits>
207 #include <new>
208 #include <stdexcept>
209 #include <utility>
210 
211 // variant-lite alignment configuration:
212 
213 #ifndef variant_CONFIG_MAX_ALIGN_HACK
214 # define variant_CONFIG_MAX_ALIGN_HACK 0
215 #endif
216 
217 #ifndef variant_CONFIG_ALIGN_AS
218 // no default, used in #if defined()
219 #endif
220 
221 #ifndef variant_CONFIG_ALIGN_AS_FALLBACK
222 # define variant_CONFIG_ALIGN_AS_FALLBACK double
223 #endif
224 
225 // half-open range [lo..hi):
226 #define variant_BETWEEN( v, lo, hi ) ( lo <= v && v < hi )
227 
228 // Compiler versions:
229 //
230 // MSVC++ 6.0 _MSC_VER == 1200 (Visual Studio 6.0)
231 // MSVC++ 7.0 _MSC_VER == 1300 (Visual Studio .NET 2002)
232 // MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio .NET 2003)
233 // MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
234 // MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
235 // MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
236 // MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
237 // MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
238 // MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
239 // MSVC++ 14.1 _MSC_VER >= 1910 (Visual Studio 2017)
240 
241 #if defined(_MSC_VER ) && !defined(__clang__)
242 # define variant_COMPILER_MSVC_VER (_MSC_VER )
243 # define variant_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
244 #else
245 # define variant_COMPILER_MSVC_VER 0
246 # define variant_COMPILER_MSVC_VERSION 0
247 #endif
248 
249 #define variant_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) )
250 
251 #if defined(__clang__)
252 # define variant_COMPILER_CLANG_VERSION variant_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
253 #else
254 # define variant_COMPILER_CLANG_VERSION 0
255 #endif
256 
257 #if defined(__GNUC__) && !defined(__clang__)
258 # define variant_COMPILER_GNUC_VERSION variant_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
259 #else
260 # define variant_COMPILER_GNUC_VERSION 0
261 #endif
262 
263 #if variant_BETWEEN( variant_COMPILER_MSVC_VER, 1300, 1900 )
264 # pragma warning( push )
265 # pragma warning( disable: 4345 ) // initialization behavior changed
266 #endif
267 
268 // Presence of language and library features:
269 
270 #define variant_HAVE( feature ) ( variant_HAVE_##feature )
271 
272 #ifdef _HAS_CPP0X
273 # define variant_HAS_CPP0X _HAS_CPP0X
274 #else
275 # define variant_HAS_CPP0X 0
276 #endif
277 
278 // Unless defined otherwise below, consider VC14 as C++11 for variant-lite:
279 
280 #if variant_COMPILER_MSVC_VER >= 1900
281 # undef variant_CPP11_OR_GREATER
282 # define variant_CPP11_OR_GREATER 1
283 #endif
284 
285 #define variant_CPP11_90 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1500)
286 #define variant_CPP11_100 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1600)
287 #define variant_CPP11_110 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1700)
288 #define variant_CPP11_120 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1800)
289 #define variant_CPP11_140 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1900)
290 #define variant_CPP11_141 (variant_CPP11_OR_GREATER_ || variant_COMPILER_MSVC_VER >= 1910)
291 
292 #define variant_CPP14_000 (variant_CPP14_OR_GREATER)
293 #define variant_CPP17_000 (variant_CPP17_OR_GREATER)
294 
295 // Presence of C++11 language features:
296 
297 #define variant_HAVE_CONSTEXPR_11 variant_CPP11_140
298 #define variant_HAVE_INITIALIZER_LIST variant_CPP11_120
299 #define variant_HAVE_NOEXCEPT variant_CPP11_140
300 #define variant_HAVE_NULLPTR variant_CPP11_100
301 #define variant_HAVE_OVERRIDE variant_CPP11_140
302 
303 // Presence of C++14 language features:
304 
305 #define variant_HAVE_CONSTEXPR_14 variant_CPP14_000
306 
307 // Presence of C++17 language features:
308 
309 // no flag
310 
311 // Presence of C++ library features:
312 
313 #define variant_HAVE_TR1_TYPE_TRAITS (!! variant_COMPILER_GNUC_VERSION )
314 #define variant_HAVE_TR1_ADD_POINTER (!! variant_COMPILER_GNUC_VERSION )
315 
316 #define variant_HAVE_CONDITIONAL variant_CPP11_120
317 #define variant_HAVE_REMOVE_CV variant_CPP11_120
318 #define variant_HAVE_STD_ADD_POINTER variant_CPP11_90
319 #define variant_HAVE_TYPE_TRAITS variant_CPP11_90
320 
321 // C++ feature usage:
322 
323 #if variant_HAVE_CONSTEXPR_11
324 # define variant_constexpr constexpr
325 #else
326 # define variant_constexpr /*constexpr*/
327 #endif
328 
329 #if variant_HAVE_CONSTEXPR_14
330 # define variant_constexpr14 constexpr
331 #else
332 # define variant_constexpr14 /*constexpr*/
333 #endif
334 
335 #if variant_HAVE_NOEXCEPT
336 # define variant_noexcept noexcept
337 #else
338 # define variant_noexcept /*noexcept*/
339 #endif
340 
341 #if variant_HAVE_NULLPTR
342 # define variant_nullptr nullptr
343 #else
344 # define variant_nullptr NULL
345 #endif
346 
347 #if variant_HAVE_OVERRIDE
348 # define variant_override override
349 #else
350 # define variant_override /*override*/
351 #endif
352 
353 // additional includes:
354 
355 #if variant_CPP11_OR_GREATER
356 # include <functional> // std::hash
357 #endif
358 
359 #if variant_HAVE_INITIALIZER_LIST
360 # include <initializer_list>
361 #endif
362 
363 #if variant_HAVE_TYPE_TRAITS
364 # include <type_traits>
365 #elif variant_HAVE_TR1_TYPE_TRAITS
366 # include <tr1/type_traits>
367 #endif
368 
369 // Method enabling
370 
371 #if variant_CPP11_OR_GREATER
372 
373 # define variant_REQUIRES_T(...) \
374  , typename = typename std::enable_if<__VA_ARGS__>::type
375 
376 # define variant_REQUIRES_R(R, ...) \
377  typename std::enable_if<__VA_ARGS__, R>::type
378 
379 # define variant_REQUIRES_A(...) \
380  , typename std::enable_if<__VA_ARGS__, void*>::type = variant_nullptr
381 
382 #endif
383 
384 //
385 // variant:
386 //
387 
388 namespace nonstd { namespace variants {
389 
390 namespace detail {
391 
392 // C++11 emulation:
393 
394 #if variant_HAVE_STD_ADD_POINTER
395 
396 using std::add_pointer;
397 
398 #elif variant_HAVE_TR1_ADD_POINTER
399 
400 using std::tr1::add_pointer;
401 
402 #else
403 
404 template< class T > struct remove_reference { typedef T type; };
405 template< class T > struct remove_reference<T&> { typedef T type; };
406 
407 template< class T > struct add_pointer
408 {
409  typedef typename remove_reference<T>::type * type;
410 };
411 
412 #endif // variant_HAVE_STD_ADD_POINTER
413 
414 #if variant_HAVE_REMOVE_CV
415 
416 using std::remove_cv;
417 
418 #else
419 
420 template< class T > struct remove_const { typedef T type; };
421 template< class T > struct remove_const<const T> { typedef T type; };
422 
423 template< class T > struct remove_volatile { typedef T type; };
424 template< class T > struct remove_volatile<volatile T> { typedef T type; };
425 
426 template< class T >
427 struct remove_cv
428 {
430 };
431 
432 #endif // variant_HAVE_REMOVE_CV
433 
434 #if variant_HAVE_CONDITIONAL
435 
436 using std::conditional;
437 
438 #else
439 
440 template< bool Cond, class Then, class Else >
441 struct conditional;
442 
443 template< class Then, class Else >
444 struct conditional< true , Then, Else > { typedef Then type; };
445 
446 template< class Then, class Else >
447 struct conditional< false, Then, Else > { typedef Else type; };
448 
449 #endif // variant_HAVE_CONDITIONAL
450 
451 // typelist:
452 
453 #define variant_TL1( T1 ) detail::typelist< T1, detail::nulltype >
454 #define variant_TL2( T1, T2) detail::typelist< T1, variant_TL1( T2) >
455 #define variant_TL3( T1, T2, T3) detail::typelist< T1, variant_TL2( T2, T3) >
456 #define variant_TL4( T1, T2, T3, T4) detail::typelist< T1, variant_TL3( T2, T3, T4) >
457 #define variant_TL5( T1, T2, T3, T4, T5) detail::typelist< T1, variant_TL4( T2, T3, T4, T5) >
458 #define variant_TL6( T1, T2, T3, T4, T5, T6) detail::typelist< T1, variant_TL5( T2, T3, T4, T5, T6) >
459 #define variant_TL7( T1, T2, T3, T4, T5, T6, T7) detail::typelist< T1, variant_TL6( T2, T3, T4, T5, T6, T7) >
460 #define variant_TL8( T1, T2, T3, T4, T5, T6, T7, T8) detail::typelist< T1, variant_TL7( T2, T3, T4, T5, T6, T7, T8) >
461 #define variant_TL9( T1, T2, T3, T4, T5, T6, T7, T8, T9) detail::typelist< T1, variant_TL8( T2, T3, T4, T5, T6, T7, T8, T9) >
462 #define variant_TL10( T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) detail::typelist< T1, variant_TL9( T2, T3, T4, T5, T6, T7, T8, T9, T10) >
463 #define variant_TL11( T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) detail::typelist< T1, variant_TL10( T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) >
464 #define variant_TL12( T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) detail::typelist< T1, variant_TL11( T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) >
465 #define variant_TL13( T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) detail::typelist< T1, variant_TL12( T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) >
466 #define variant_TL14( T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) detail::typelist< T1, variant_TL13( T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) >
467 #define variant_TL15( T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) detail::typelist< T1, variant_TL14( T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) >
468 #define variant_TL16( T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) detail::typelist< T1, variant_TL15( T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) >
469 
470 
471 // variant parameter unused type tags:
472 
473 template< class T >
474 struct TX : T
475 {
476  inline TX<T> operator+ ( ) const { return TX<T>(); }
477  inline TX<T> operator- ( ) const { return TX<T>(); }
478 
479  inline TX<T> operator! ( ) const { return TX<T>(); }
480  inline TX<T> operator~ ( ) const { return TX<T>(); }
481 
482  inline TX<T>*operator& ( ) const { return variant_nullptr; }
483 
484  template< class U > inline TX<T> operator* ( U const & ) const { return TX<T>(); }
485  template< class U > inline TX<T> operator/ ( U const & ) const { return TX<T>(); }
486 
487  template< class U > inline TX<T> operator% ( U const & ) const { return TX<T>(); }
488  template< class U > inline TX<T> operator+ ( U const & ) const { return TX<T>(); }
489  template< class U > inline TX<T> operator- ( U const & ) const { return TX<T>(); }
490 
491  template< class U > inline TX<T> operator<<( U const & ) const { return TX<T>(); }
492  template< class U > inline TX<T> operator>>( U const & ) const { return TX<T>(); }
493 
494  inline bool operator==( T const & ) const { return false; }
495  inline bool operator< ( T const & ) const { return false; }
496 
497  template< class U > inline TX<T> operator& ( U const & ) const { return TX<T>(); }
498  template< class U > inline TX<T> operator| ( U const & ) const { return TX<T>(); }
499  template< class U > inline TX<T> operator^ ( U const & ) const { return TX<T>(); }
500 
501  template< class U > inline TX<T> operator&&( U const & ) const { return TX<T>(); }
502  template< class U > inline TX<T> operator||( U const & ) const { return TX<T>(); }
503 };
504 
505 struct S0{}; typedef TX<S0> T0;
506 struct S1{}; typedef TX<S1> T1;
507 struct S2{}; typedef TX<S2> T2;
508 struct S3{}; typedef TX<S3> T3;
509 struct S4{}; typedef TX<S4> T4;
510 struct S5{}; typedef TX<S5> T5;
511 struct S6{}; typedef TX<S6> T6;
512 struct S7{}; typedef TX<S7> T7;
513 struct S8{}; typedef TX<S8> T8;
514 struct S9{}; typedef TX<S9> T9;
515 struct S10{}; typedef TX<S10> T10;
516 struct S11{}; typedef TX<S11> T11;
517 struct S12{}; typedef TX<S12> T12;
518 struct S13{}; typedef TX<S13> T13;
519 struct S14{}; typedef TX<S14> T14;
520 struct S15{}; typedef TX<S15> T15;
521 
522 
523 struct nulltype{};
524 
525 template< class Head, class Tail >
526 struct typelist
527 {
528  typedef Head head;
529  typedef Tail tail;
530 };
531 
532 // typelist max element size:
533 
534 template< class List >
536 
537 template<>
539 {
540  enum V { value = 0 } ;
541  typedef void type;
542 };
543 
544 template< class Head, class Tail >
545 struct typelist_max< typelist<Head, Tail> >
546 {
547 private:
548  enum TV { tail_value = size_t( typelist_max<Tail>::value ) };
549 
550  typedef typename typelist_max<Tail>::type tail_type;
551 
552 public:
553  enum V { value = (sizeof( Head ) > tail_value) ? sizeof( Head ) : std::size_t( tail_value ) } ;
554 
555  typedef typename conditional< (sizeof( Head ) > tail_value), Head, tail_type>::type type;
556 };
557 
558 #if variant_CPP11_OR_GREATER
559 
560 // typelist max alignof element type:
561 
562 template< class List >
563 struct typelist_max_alignof;
564 
565 template<>
566 struct typelist_max_alignof< nulltype >
567 {
568  enum V { value = 0 } ;
569 };
570 
571 template< class Head, class Tail >
572 struct typelist_max_alignof< typelist<Head, Tail> >
573 {
574 private:
575  enum TV { tail_value = size_t( typelist_max_alignof<Tail>::value ) };
576 
577 public:
578  enum V { value = (alignof( Head ) > tail_value) ? alignof( Head ) : std::size_t( tail_value ) };
579 };
580 
581 #endif
582 
583 // typelist size (length):
584 
585 template< class List >
587 {
588  enum V { value = 1 };
589 };
590 
591 template<> struct typelist_size< T0 > { enum V { value = 0 }; };
592 template<> struct typelist_size< T1 > { enum V { value = 0 }; };
593 template<> struct typelist_size< T2 > { enum V { value = 0 }; };
594 template<> struct typelist_size< T3 > { enum V { value = 0 }; };
595 template<> struct typelist_size< T4 > { enum V { value = 0 }; };
596 template<> struct typelist_size< T5 > { enum V { value = 0 }; };
597 template<> struct typelist_size< T6 > { enum V { value = 0 }; };
598 template<> struct typelist_size< T7 > { enum V { value = 0 }; };
599 template<> struct typelist_size< T8 > { enum V { value = 0 }; };
600 template<> struct typelist_size< T9 > { enum V { value = 0 }; };
601 template<> struct typelist_size< T10 > { enum V { value = 0 }; };
602 template<> struct typelist_size< T11 > { enum V { value = 0 }; };
603 template<> struct typelist_size< T12 > { enum V { value = 0 }; };
604 template<> struct typelist_size< T13 > { enum V { value = 0 }; };
605 template<> struct typelist_size< T14 > { enum V { value = 0 }; };
606 template<> struct typelist_size< T15 > { enum V { value = 0 }; };
607 
608 
609 template<> struct typelist_size< nulltype > { enum V { value = 0 } ; };
610 
611 template< class Head, class Tail >
612 struct typelist_size< typelist<Head, Tail> >
613 {
615 };
616 
617 // typelist index of type:
618 
619 template< class List, class T >
621 
622 template< class T >
624 {
625  enum V { value = -1 };
626 };
627 
628 template< class Tail, class T >
629 struct typelist_index_of< typelist<T, Tail>, T >
630 {
631  enum V { value = 0 };
632 };
633 
634 template< class Head, class Tail, class T >
635 struct typelist_index_of< typelist<Head, Tail>, T >
636 {
637 private:
638  enum TV { nextVal = typelist_index_of<Tail, T>::value };
639 
640 public:
641  enum V { value = nextVal == -1 ? -1 : 1 + nextVal } ;
642 };
643 
644 // typelist type at index:
645 
646 template< class List, std::size_t i>
648 
649 template< class Head, class Tail >
650 struct typelist_type_at< typelist<Head, Tail>, 0 >
651 {
652  typedef Head type;
653 };
654 
655 template< class Head, class Tail, std::size_t i >
656 struct typelist_type_at< typelist<Head, Tail>, i >
657 {
658  typedef typename typelist_type_at<Tail, i - 1>::type type;
659 };
660 
661 #if variant_CONFIG_MAX_ALIGN_HACK
662 
663 // Max align, use most restricted type for alignment:
664 
665 #define variant_UNIQUE( name ) variant_UNIQUE2( name, __LINE__ )
666 #define variant_UNIQUE2( name, line ) variant_UNIQUE3( name, line )
667 #define variant_UNIQUE3( name, line ) name ## line
668 
669 #define variant_ALIGN_TYPE( type ) \
670  type variant_UNIQUE( _t ); struct_t< type > variant_UNIQUE( _st )
671 
672 template< class T >
673 struct struct_t { T _; };
674 
675 union max_align_t
676 {
677  variant_ALIGN_TYPE( char );
678  variant_ALIGN_TYPE( short int );
679  variant_ALIGN_TYPE( int );
680  variant_ALIGN_TYPE( long int );
681  variant_ALIGN_TYPE( float );
682  variant_ALIGN_TYPE( double );
683  variant_ALIGN_TYPE( long double );
684  variant_ALIGN_TYPE( char * );
685  variant_ALIGN_TYPE( short int * );
686  variant_ALIGN_TYPE( int * );
687  variant_ALIGN_TYPE( long int * );
688  variant_ALIGN_TYPE( float * );
689  variant_ALIGN_TYPE( double * );
690  variant_ALIGN_TYPE( long double * );
691  variant_ALIGN_TYPE( void * );
692 
693 #ifdef HAVE_LONG_LONG
694  variant_ALIGN_TYPE( long long );
695 #endif
696 
697  struct Unknown;
698 
699  Unknown ( * variant_UNIQUE(_) )( Unknown );
700  Unknown * Unknown::* variant_UNIQUE(_);
701  Unknown ( Unknown::* variant_UNIQUE(_) )( Unknown );
702 
703  struct_t< Unknown ( * )( Unknown) > variant_UNIQUE(_);
704  struct_t< Unknown * Unknown::* > variant_UNIQUE(_);
705  struct_t< Unknown ( Unknown::* )(Unknown) > variant_UNIQUE(_);
706 };
707 
708 #undef variant_UNIQUE
709 #undef variant_UNIQUE2
710 #undef variant_UNIQUE3
711 
712 #undef variant_ALIGN_TYPE
713 
714 #elif defined( variant_CONFIG_ALIGN_AS ) // variant_CONFIG_MAX_ALIGN_HACK
715 
716 // Use user-specified type for alignment:
717 
718 #define variant_ALIGN_AS( unused ) \
719  variant_CONFIG_ALIGN_AS
720 
721 #else // variant_CONFIG_MAX_ALIGN_HACK
722 
723 // Determine POD type to use for alignment:
724 
725 #define variant_ALIGN_AS( to_align ) \
726  typename detail::type_of_size< detail::alignment_types, detail::alignment_of< to_align >::value >::type
727 
728 template< typename T >
730 
731 template< typename T >
733 {
734  char c;
735  T t;
737 };
738 
739 template< size_t A, size_t S >
741 {
742  enum V { value = A < S ? A : S };
743 };
744 
745 template< typename T >
746 struct alignment_of
747 {
749  sizeof( alignment_of_hack<T> ) - sizeof(T), sizeof(T) >::value, };
750 };
751 
752 template< typename List, size_t N >
754 {
755  typedef typename conditional<
756  N == sizeof( typename List::head ),
757  typename List::head,
759 };
760 
761 template< size_t N >
762 struct type_of_size< nulltype, N >
763 {
765 };
766 
767 template< typename T>
768 struct struct_t { T _; };
769 
770 #define variant_ALIGN_TYPE( type ) \
771  typelist< type , typelist< struct_t< type >
772 
773 struct Unknown;
774 
775 typedef
776  variant_ALIGN_TYPE( char ),
777  variant_ALIGN_TYPE( short ),
778  variant_ALIGN_TYPE( int ),
779  variant_ALIGN_TYPE( long ),
780  variant_ALIGN_TYPE( float ),
781  variant_ALIGN_TYPE( double ),
782  variant_ALIGN_TYPE( long double ),
783 
784  variant_ALIGN_TYPE( char *),
785  variant_ALIGN_TYPE( short * ),
786  variant_ALIGN_TYPE( int * ),
787  variant_ALIGN_TYPE( long * ),
788  variant_ALIGN_TYPE( float * ),
789  variant_ALIGN_TYPE( double * ),
790  variant_ALIGN_TYPE( long double * ),
791 
792  variant_ALIGN_TYPE( Unknown ( * )( Unknown ) ),
793  variant_ALIGN_TYPE( Unknown * Unknown::* ),
794  variant_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ),
795 
796  nulltype
797  > > > > > > > > > > > > > >
798  > > > > > > > > > > > > > >
799  > > > > > >
801 
802 #undef variant_ALIGN_TYPE
803 
804 #endif // variant_CONFIG_MAX_ALIGN_HACK
805 
806 template< typename T>
807 inline std::size_t hash( T const & v )
808 {
809  // primes:
810  unsigned const int a = 54059;
811  unsigned const int b = 76963;
812  unsigned const int h0 = 37;
813 
814  unsigned int h = h0;
815  unsigned char const * s = reinterpret_cast<unsigned char const *>( &v );
816 
817  for ( std::size_t i = 0; i < sizeof(v); ++i, ++s )
818  {
819  h = (h * a) ^ (*s * b);
820  }
821  return h;
822 }
823 
824 
825 
826 
827 
828 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
829 struct helper
830 {
831  typedef signed char type_index_t;
832  typedef variant_TL16( T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 ) variant_types;
833 
834  template< class U >
835  static U * as( void * data )
836  {
837  return reinterpret_cast<U*>( data );
838  }
839 
840  template< class U >
841  static U const * as( void const * data )
842  {
843  return reinterpret_cast<const U*>( data );
844  }
845 
846  static type_index_t to_index_t( std::size_t index )
847  {
848  return static_cast<type_index_t>( index );
849  }
850 
851  static void destroy( type_index_t index, void * data )
852  {
853  switch ( index )
854  {
855  case 0: as<T0>( data )->~T0(); break;
856  case 1: as<T1>( data )->~T1(); break;
857  case 2: as<T2>( data )->~T2(); break;
858  case 3: as<T3>( data )->~T3(); break;
859  case 4: as<T4>( data )->~T4(); break;
860  case 5: as<T5>( data )->~T5(); break;
861  case 6: as<T6>( data )->~T6(); break;
862  case 7: as<T7>( data )->~T7(); break;
863  case 8: as<T8>( data )->~T8(); break;
864  case 9: as<T9>( data )->~T9(); break;
865  case 10: as<T10>( data )->~T10(); break;
866  case 11: as<T11>( data )->~T11(); break;
867  case 12: as<T12>( data )->~T12(); break;
868  case 13: as<T13>( data )->~T13(); break;
869  case 14: as<T14>( data )->~T14(); break;
870  case 15: as<T15>( data )->~T15(); break;
871 
872  }
873  }
874 
875 #if variant_CPP11_OR_GREATER
876  template< class T, class... Args >
877  static type_index_t construct_t( void * data, Args&&... args )
878  {
879  new( data ) T( std::forward<Args>(args)... );
880 
882  }
883 
884  template< std::size_t K, class... Args >
885  static type_index_t construct_i( void * data, Args&&... args )
886  {
888 
889  construct_t< type >( data, std::forward<Args>(args)... );
890 
891  return to_index_t( K );
892  }
893 
894  static type_index_t move( type_index_t const from_index, void * from_value, void * to_value )
895  {
896  switch ( from_index )
897  {
898  case 0: new( to_value ) T0( std::forward<T0>( *as<T0>( from_value ) ) ); break;
899  case 1: new( to_value ) T1( std::forward<T1>( *as<T1>( from_value ) ) ); break;
900  case 2: new( to_value ) T2( std::forward<T2>( *as<T2>( from_value ) ) ); break;
901  case 3: new( to_value ) T3( std::forward<T3>( *as<T3>( from_value ) ) ); break;
902  case 4: new( to_value ) T4( std::forward<T4>( *as<T4>( from_value ) ) ); break;
903  case 5: new( to_value ) T5( std::forward<T5>( *as<T5>( from_value ) ) ); break;
904  case 6: new( to_value ) T6( std::forward<T6>( *as<T6>( from_value ) ) ); break;
905  case 7: new( to_value ) T7( std::forward<T7>( *as<T7>( from_value ) ) ); break;
906  case 8: new( to_value ) T8( std::forward<T8>( *as<T8>( from_value ) ) ); break;
907  case 9: new( to_value ) T9( std::forward<T9>( *as<T9>( from_value ) ) ); break;
908  case 10: new( to_value ) T10( std::forward<T10>( *as<T10>( from_value ) ) ); break;
909  case 11: new( to_value ) T11( std::forward<T11>( *as<T11>( from_value ) ) ); break;
910  case 12: new( to_value ) T12( std::forward<T12>( *as<T12>( from_value ) ) ); break;
911  case 13: new( to_value ) T13( std::forward<T13>( *as<T13>( from_value ) ) ); break;
912  case 14: new( to_value ) T14( std::forward<T14>( *as<T14>( from_value ) ) ); break;
913  case 15: new( to_value ) T15( std::forward<T15>( *as<T15>( from_value ) ) ); break;
914 
915  }
916  return from_index;
917  }
918 #endif
919 
920  static type_index_t copy( type_index_t const from_index, const void * from_value, void * to_value )
921  {
922  switch ( from_index )
923  {
924  case 0: new( to_value ) T0( *as<T0>( from_value ) ); break;
925  case 1: new( to_value ) T1( *as<T1>( from_value ) ); break;
926  case 2: new( to_value ) T2( *as<T2>( from_value ) ); break;
927  case 3: new( to_value ) T3( *as<T3>( from_value ) ); break;
928  case 4: new( to_value ) T4( *as<T4>( from_value ) ); break;
929  case 5: new( to_value ) T5( *as<T5>( from_value ) ); break;
930  case 6: new( to_value ) T6( *as<T6>( from_value ) ); break;
931  case 7: new( to_value ) T7( *as<T7>( from_value ) ); break;
932  case 8: new( to_value ) T8( *as<T8>( from_value ) ); break;
933  case 9: new( to_value ) T9( *as<T9>( from_value ) ); break;
934  case 10: new( to_value ) T10( *as<T10>( from_value ) ); break;
935  case 11: new( to_value ) T11( *as<T11>( from_value ) ); break;
936  case 12: new( to_value ) T12( *as<T12>( from_value ) ); break;
937  case 13: new( to_value ) T13( *as<T13>( from_value ) ); break;
938  case 14: new( to_value ) T14( *as<T14>( from_value ) ); break;
939  case 15: new( to_value ) T15( *as<T15>( from_value ) ); break;
940 
941  }
942  return from_index;
943  }
944 };
945 
946 } // namespace detail
947 
948 //
949 // Variant:
950 //
951 
952 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
953 class variant;
954 
955 class monostate{};
956 
963 
964 // obtain the size of the variant's list of alternatives at compile time
965 
966 template< class T >
967 struct variant_size; /* undefined */
968 
969 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
970 struct variant_size< variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> >
971 {
972  enum _ { value = detail::typelist_size< variant_TL16(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) >::value };
973 };
974 
975 #if variant_CPP14_OR_GREATER
976 template< class T >
977 constexpr std::size_t variant_size_v = variant_size<T>::value;
978 #endif
979 
980 #if ! variant_CONFIG_OMIT_VARIANT_SIZE_V_MACRO
981 # define variant_size_V(T) nonstd::variant_size<T>::value
982 #endif
983 
984 // obtain the type of the alternative specified by its index, at compile time:
985 
986 template< std::size_t K, class T >
987 struct variant_alternative; /* undefined */
988 
989 template< std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
990 struct variant_alternative< K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> >
991 {
992  typedef typename detail::typelist_type_at<variant_TL16(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15), K>::type type;
993 };
994 
995 #if variant_CPP11_OR_GREATER
996 template< std::size_t K, class T >
997 using variant_alternative_t = typename variant_alternative<K, T>::type;
998 #endif
999 
1000 #if ! variant_CONFIG_OMIT_VARIANT_ALTERNATIVE_T_MACRO
1001 # define variant_alternative_T(K,T) typename nonstd::variant_alternative<K,T >::type
1002 #endif
1003 
1004 // NTS:implement specializes the std::uses_allocator type trait
1005 // std::uses_allocator<nonstd::variant>
1006 
1007 // index of the variant in the invalid state (constant)
1008 
1009 #if variant_CPP11_OR_GREATER
1010 variant_constexpr std::size_t variant_npos = static_cast<std::size_t>( -1 );
1011 #else
1012 static const std::size_t variant_npos = static_cast<std::size_t>( -1 );
1013 #endif
1014 
1015 class bad_variant_access : public std::exception
1016 {
1017 public:
1018 #if variant_CPP11_OR_GREATER
1019  virtual const char* what() const variant_noexcept variant_override
1020 #else
1021  virtual const char* what() const throw()
1022 #endif
1023  {
1024  return "bad variant access";
1025  }
1026 };
1027 
1028 template<
1029  class T0,
1030  class T1 = detail::T1,
1031  class T2 = detail::T2,
1032  class T3 = detail::T3,
1033  class T4 = detail::T4,
1034  class T5 = detail::T5,
1035  class T6 = detail::T6,
1036  class T7 = detail::T7,
1037  class T8 = detail::T8,
1038  class T9 = detail::T9,
1039  class T10 = detail::T10,
1040  class T11 = detail::T11,
1041  class T12 = detail::T12,
1042  class T13 = detail::T13,
1043  class T14 = detail::T14,
1044  class T15 = detail::T15
1045  >
1046 class variant
1047 {
1048  typedef detail::helper< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 > helper_type;
1049  typedef variant_TL16( T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 ) variant_types;
1050 
1051 public:
1052  variant() : type_index( 0 ) { new( ptr() ) T0(); }
1053 
1054  variant( T0 const & t0 ) : type_index( 0 ) { new( ptr() ) T0( t0 ); }
1055  variant( T1 const & t1 ) : type_index( 1 ) { new( ptr() ) T1( t1 ); }
1056  variant( T2 const & t2 ) : type_index( 2 ) { new( ptr() ) T2( t2 ); }
1057  variant( T3 const & t3 ) : type_index( 3 ) { new( ptr() ) T3( t3 ); }
1058  variant( T4 const & t4 ) : type_index( 4 ) { new( ptr() ) T4( t4 ); }
1059  variant( T5 const & t5 ) : type_index( 5 ) { new( ptr() ) T5( t5 ); }
1060  variant( T6 const & t6 ) : type_index( 6 ) { new( ptr() ) T6( t6 ); }
1061  variant( T7 const & t7 ) : type_index( 7 ) { new( ptr() ) T7( t7 ); }
1062  variant( T8 const & t8 ) : type_index( 8 ) { new( ptr() ) T8( t8 ); }
1063  variant( T9 const & t9 ) : type_index( 9 ) { new( ptr() ) T9( t9 ); }
1064  variant( T10 const & t10 ) : type_index( 10 ) { new( ptr() ) T10( t10 ); }
1065  variant( T11 const & t11 ) : type_index( 11 ) { new( ptr() ) T11( t11 ); }
1066  variant( T12 const & t12 ) : type_index( 12 ) { new( ptr() ) T12( t12 ); }
1067  variant( T13 const & t13 ) : type_index( 13 ) { new( ptr() ) T13( t13 ); }
1068  variant( T14 const & t14 ) : type_index( 14 ) { new( ptr() ) T14( t14 ); }
1069  variant( T15 const & t15 ) : type_index( 15 ) { new( ptr() ) T15( t15 ); }
1070 
1071 
1072 #if variant_CPP11_OR_GREATER
1073  variant( T0 && t0 ) : type_index( 0 ) { new( ptr() ) T0( std::move(t0) ); }
1074  variant( T1 && t1 ) : type_index( 1 ) { new( ptr() ) T1( std::move(t1) ); }
1075  variant( T2 && t2 ) : type_index( 2 ) { new( ptr() ) T2( std::move(t2) ); }
1076  variant( T3 && t3 ) : type_index( 3 ) { new( ptr() ) T3( std::move(t3) ); }
1077  variant( T4 && t4 ) : type_index( 4 ) { new( ptr() ) T4( std::move(t4) ); }
1078  variant( T5 && t5 ) : type_index( 5 ) { new( ptr() ) T5( std::move(t5) ); }
1079  variant( T6 && t6 ) : type_index( 6 ) { new( ptr() ) T6( std::move(t6) ); }
1080  variant( T7 && t7 ) : type_index( 7 ) { new( ptr() ) T7( std::move(t7) ); }
1081  variant( T8 && t8 ) : type_index( 8 ) { new( ptr() ) T8( std::move(t8) ); }
1082  variant( T9 && t9 ) : type_index( 9 ) { new( ptr() ) T9( std::move(t9) ); }
1083  variant( T10 && t10 ) : type_index( 10 ) { new( ptr() ) T10( std::move(t10) ); }
1084  variant( T11 && t11 ) : type_index( 11 ) { new( ptr() ) T11( std::move(t11) ); }
1085  variant( T12 && t12 ) : type_index( 12 ) { new( ptr() ) T12( std::move(t12) ); }
1086  variant( T13 && t13 ) : type_index( 13 ) { new( ptr() ) T13( std::move(t13) ); }
1087  variant( T14 && t14 ) : type_index( 14 ) { new( ptr() ) T14( std::move(t14) ); }
1088  variant( T15 && t15 ) : type_index( 15 ) { new( ptr() ) T15( std::move(t15) ); }
1089 
1090 #endif
1091 
1092  variant(variant const & other)
1093  : type_index( other.type_index )
1094  {
1095  (void) helper_type::copy( other.type_index, other.ptr(), ptr() );
1096  }
1097 
1098 #if variant_CPP11_OR_GREATER
1099 
1100  variant( variant && other ) noexcept(
1101  std::is_nothrow_move_constructible<T0>::value &&
1102  std::is_nothrow_move_constructible<T1>::value &&
1103  std::is_nothrow_move_constructible<T2>::value &&
1104  std::is_nothrow_move_constructible<T3>::value &&
1105  std::is_nothrow_move_constructible<T4>::value &&
1106  std::is_nothrow_move_constructible<T5>::value &&
1107  std::is_nothrow_move_constructible<T6>::value &&
1108  std::is_nothrow_move_constructible<T7>::value &&
1109  std::is_nothrow_move_constructible<T8>::value &&
1110  std::is_nothrow_move_constructible<T9>::value &&
1111  std::is_nothrow_move_constructible<T10>::value &&
1112  std::is_nothrow_move_constructible<T11>::value &&
1113  std::is_nothrow_move_constructible<T12>::value &&
1114  std::is_nothrow_move_constructible<T13>::value &&
1115  std::is_nothrow_move_constructible<T14>::value &&
1116  std::is_nothrow_move_constructible<T15>::value)
1117  : type_index( other.type_index )
1118  {
1119  (void) helper_type::move( other.type_index, other.ptr(), ptr() );
1120  }
1121 
1122  template< std::size_t K >
1123  using type_at_t = typename detail::typelist_type_at< variant_types, K >::type;
1124 
1125  template< class T, class... Args
1126  variant_REQUIRES_T( std::is_constructible< T, Args...>::value )
1127  >
1128  explicit variant( nonstd_lite_in_place_type_t(T), Args&&... args)
1129  {
1130  type_index = variant_npos_internal();
1131  type_index = helper_type::template construct_t<T>( ptr(), std::forward<Args>(args)... );
1132  }
1133 
1134  template< class T, class U, class... Args
1135  variant_REQUIRES_T( std::is_constructible< T, std::initializer_list<U>&, Args...>::value )
1136  >
1137  explicit variant( nonstd_lite_in_place_type_t(T), std::initializer_list<U> il, Args&&... args )
1138  {
1139  type_index = variant_npos_internal();
1140  type_index = helper_type::template construct_t<T>( ptr(), il, std::forward<Args>(args)... );
1141  }
1142 
1143  template< std::size_t K, class... Args
1144  variant_REQUIRES_T( std::is_constructible< type_at_t<K>, Args...>::value )
1145  >
1146  explicit variant( nonstd_lite_in_place_index_t(K), Args&&... args )
1147  {
1148  type_index = variant_npos_internal();
1149  type_index = helper_type::template construct_i<K>( ptr(), std::forward<Args>(args)... );
1150  }
1151 
1152  template< size_t K, class U, class... Args
1153  variant_REQUIRES_T( std::is_constructible< type_at_t<K>, std::initializer_list<U>&, Args...>::value )
1154  >
1155  explicit variant( nonstd_lite_in_place_index_t(K), std::initializer_list<U> il, Args&&... args )
1156  {
1157  type_index = variant_npos_internal();
1158  type_index = helper_type::template construct_i<K>( ptr(), il, std::forward<Args>(args)... );
1159  }
1160 
1161 #endif // variant_CPP11_OR_GREATER
1162 
1164  {
1165  helper_type::destroy( type_index, ptr() );
1166  }
1167 
1168  variant & operator=( variant const & other )
1169  {
1170  return copy_assign( other );
1171  }
1172 
1173 #if variant_CPP11_OR_GREATER
1174 
1175  variant & operator=( variant && other ) noexcept(
1176  std::is_nothrow_move_assignable<T0>::value &&
1177  std::is_nothrow_move_assignable<T1>::value &&
1178  std::is_nothrow_move_assignable<T2>::value &&
1179  std::is_nothrow_move_assignable<T3>::value &&
1180  std::is_nothrow_move_assignable<T4>::value &&
1181  std::is_nothrow_move_assignable<T5>::value &&
1182  std::is_nothrow_move_assignable<T6>::value &&
1183  std::is_nothrow_move_assignable<T7>::value &&
1184  std::is_nothrow_move_assignable<T8>::value &&
1185  std::is_nothrow_move_assignable<T9>::value &&
1186  std::is_nothrow_move_assignable<T10>::value &&
1187  std::is_nothrow_move_assignable<T11>::value &&
1188  std::is_nothrow_move_assignable<T12>::value &&
1189  std::is_nothrow_move_assignable<T13>::value &&
1190  std::is_nothrow_move_assignable<T14>::value &&
1191  std::is_nothrow_move_assignable<T15>::value)
1192  {
1193  return move_assign( std::forward<variant>( other ) );
1194  }
1195 
1196  variant & operator=( T0 && t0 ) { return move_assign_value<T0,0>( std::forward<T0>( t0 ) ); }
1197  variant & operator=( T1 && t1 ) { return move_assign_value<T1,1>( std::forward<T1>( t1 ) ); }
1198  variant & operator=( T2 && t2 ) { return move_assign_value<T2,2>( std::forward<T2>( t2 ) ); }
1199  variant & operator=( T3 && t3 ) { return move_assign_value<T3,3>( std::forward<T3>( t3 ) ); }
1200  variant & operator=( T4 && t4 ) { return move_assign_value<T4,4>( std::forward<T4>( t4 ) ); }
1201  variant & operator=( T5 && t5 ) { return move_assign_value<T5,5>( std::forward<T5>( t5 ) ); }
1202  variant & operator=( T6 && t6 ) { return move_assign_value<T6,6>( std::forward<T6>( t6 ) ); }
1203  variant & operator=( T7 && t7 ) { return move_assign_value<T7,7>( std::forward<T7>( t7 ) ); }
1204  variant & operator=( T8 && t8 ) { return move_assign_value<T8,8>( std::forward<T8>( t8 ) ); }
1205  variant & operator=( T9 && t9 ) { return move_assign_value<T9,9>( std::forward<T9>( t9 ) ); }
1206  variant & operator=( T10 && t10 ) { return move_assign_value<T10,10>( std::forward<T10>( t10 ) ); }
1207  variant & operator=( T11 && t11 ) { return move_assign_value<T11,11>( std::forward<T11>( t11 ) ); }
1208  variant & operator=( T12 && t12 ) { return move_assign_value<T12,12>( std::forward<T12>( t12 ) ); }
1209  variant & operator=( T13 && t13 ) { return move_assign_value<T13,13>( std::forward<T13>( t13 ) ); }
1210  variant & operator=( T14 && t14 ) { return move_assign_value<T14,14>( std::forward<T14>( t14 ) ); }
1211  variant & operator=( T15 && t15 ) { return move_assign_value<T15,15>( std::forward<T15>( t15 ) ); }
1212 
1213 #else
1214  variant & operator=( T0 const & t0 ) { return copy_assign_value<T0,0>( t0 ); }
1215  variant & operator=( T1 const & t1 ) { return copy_assign_value<T1,1>( t1 ); }
1216  variant & operator=( T2 const & t2 ) { return copy_assign_value<T2,2>( t2 ); }
1217  variant & operator=( T3 const & t3 ) { return copy_assign_value<T3,3>( t3 ); }
1218  variant & operator=( T4 const & t4 ) { return copy_assign_value<T4,4>( t4 ); }
1219  variant & operator=( T5 const & t5 ) { return copy_assign_value<T5,5>( t5 ); }
1220  variant & operator=( T6 const & t6 ) { return copy_assign_value<T6,6>( t6 ); }
1221  variant & operator=( T7 const & t7 ) { return copy_assign_value<T7,7>( t7 ); }
1222  variant & operator=( T8 const & t8 ) { return copy_assign_value<T8,8>( t8 ); }
1223  variant & operator=( T9 const & t9 ) { return copy_assign_value<T9,9>( t9 ); }
1224  variant & operator=( T10 const & t10 ) { return copy_assign_value<T10,10>( t10 ); }
1225  variant & operator=( T11 const & t11 ) { return copy_assign_value<T11,11>( t11 ); }
1226  variant & operator=( T12 const & t12 ) { return copy_assign_value<T12,12>( t12 ); }
1227  variant & operator=( T13 const & t13 ) { return copy_assign_value<T13,13>( t13 ); }
1228  variant & operator=( T14 const & t14 ) { return copy_assign_value<T14,14>( t14 ); }
1229  variant & operator=( T15 const & t15 ) { return copy_assign_value<T15,15>( t15 ); }
1230 
1231 #endif
1232 
1233  std::size_t index() const
1234  {
1235  return variant_npos_internal() == type_index ? variant_npos : static_cast<std::size_t>( type_index );
1236  }
1237 
1239  {
1240  return type_index == variant_npos_internal();
1241  }
1242 
1243 #if variant_CPP11_OR_GREATER
1244  template< class T, class... Args
1245  variant_REQUIRES_T( std::is_constructible< T, Args...>::value )
1246  >
1247  T& emplace( Args&&... args )
1248  {
1249  helper_type::destroy( type_index, ptr() );
1250  type_index = variant_npos_internal();
1251  type_index = helper_type::template construct_t<T>( ptr(), std::forward<Args>(args)... );
1252 
1253  return *as<T>();
1254  }
1255 
1256  template< class T, class U, class... Args
1257  variant_REQUIRES_T( std::is_constructible< T, std::initializer_list<U>&, Args...>::value )
1258  >
1259  T& emplace( std::initializer_list<U> il, Args&&... args )
1260  {
1261  helper_type::destroy( type_index, ptr() );
1262  type_index = variant_npos_internal();
1263  type_index = helper_type::template construct_t<T>( ptr(), il, std::forward<Args>(args)... );
1264 
1265  return *as<T>();
1266  }
1267 
1268  template< size_t K, class... Args
1269  variant_REQUIRES_T( std::is_constructible< type_at_t<K>, Args...>::value )
1270  >
1271  variant_alternative_t<K, variant> & emplace( Args&&... args )
1272  {
1273  return this->template emplace< type_at_t<K> >( std::forward<Args>(args)... );
1274  }
1275 
1276  template< size_t K, class U, class... Args
1277  variant_REQUIRES_T( std::is_constructible< type_at_t<K>, std::initializer_list<U>&, Args...>::value )
1278  >
1279  variant_alternative_t<K, variant> & emplace( std::initializer_list<U> il, Args&&... args )
1280  {
1281  return this->template emplace< type_at_t<K> >( il, std::forward<Args>(args)... );
1282  }
1283 
1284 #endif // variant_CPP11_OR_GREATER
1285 
1287  {
1288  if ( valueless_by_exception() && other.valueless_by_exception() )
1289  {
1290  // no effect
1291  }
1292  else if ( type_index == other.type_index )
1293  {
1294  this->swap_value( type_index, other );
1295  }
1296  else
1297  {
1298  variant tmp( *this );
1299  *this = other;
1300  other = tmp;
1301  }
1302  }
1303 
1304  //
1305  // non-standard:
1306  //
1307 
1308  template< class T >
1310  {
1311  return to_size_t( detail::typelist_index_of<variant_types, typename detail::remove_cv<T>::type >::value );
1312  }
1313 
1314  template< class T >
1315  T & get()
1316  {
1317  const std::size_t i = index_of<T>();
1318 
1319  if ( i != index() || i == max_index() )
1320  {
1321  throw bad_variant_access();
1322  }
1323 
1324  return *as<T>();
1325  }
1326 
1327  template< class T >
1328  T const & get() const
1329  {
1330  const std::size_t i = index_of<T>();
1331 
1332  if ( i != index() || i == max_index() )
1333  {
1334  throw bad_variant_access();
1335  }
1336 
1337  return *as<const T>();
1338  }
1339 
1340  template< std::size_t K >
1343  {
1344  return this->template get< typename detail::typelist_type_at< variant_types, K >::type >();
1345  }
1346 
1347  template< std::size_t K >
1349  get() const
1350  {
1351  return this->template get< typename detail::typelist_type_at< variant_types, K >::type >();
1352  }
1353 
1354 private:
1355  typedef typename helper_type::type_index_t type_index_t;
1356 
1357  void * ptr() variant_noexcept
1358  {
1359  return &data;
1360  }
1361 
1362  void const * ptr() const variant_noexcept
1363  {
1364  return &data;
1365  }
1366 
1367  template< class U >
1368  U * as()
1369  {
1370  return reinterpret_cast<U*>( ptr() );
1371  }
1372 
1373  template< class U >
1374  U const * as() const
1375  {
1376  return reinterpret_cast<U const *>( ptr() );
1377  }
1378 
1379  template< class U >
1380  static std::size_t to_size_t( U index )
1381  {
1382  return static_cast<std::size_t >( index );
1383  }
1384 
1385  variant_constexpr std::size_t max_index() const variant_noexcept
1386  {
1387  return data_size;
1388  }
1389 
1390  variant_constexpr type_index_t variant_npos_internal() const variant_noexcept
1391  {
1392  return static_cast<type_index_t>( -1 );
1393  }
1394 
1395  variant & copy_assign( variant const & other )
1396  {
1397  if ( valueless_by_exception() && other.valueless_by_exception() )
1398  {
1399  // no effect
1400  }
1401  else if ( ! valueless_by_exception() && other.valueless_by_exception() )
1402  {
1403  helper_type::destroy( type_index, ptr() );
1404  type_index = variant_npos_internal();
1405  }
1406  else if ( index() == other.index() )
1407  {
1408  type_index = helper_type::copy( other.type_index, other.ptr(), ptr() );
1409  }
1410  else
1411  {
1412  // alas exception safety with pre-C++11 needs an extra copy:
1413 
1414  variant tmp( other );
1415  helper_type::destroy( type_index, ptr() );
1416  type_index = variant_npos_internal();
1417 #if variant_CPP11_OR_GREATER
1418  type_index = helper_type::move( other.type_index, tmp.ptr(), ptr() );
1419 #else
1420  type_index = helper_type::copy( other.type_index, tmp.ptr(), ptr() );
1421 #endif
1422  }
1423  return *this;
1424  }
1425 
1426 #if variant_CPP11_OR_GREATER
1427 
1428  variant & move_assign( variant && other )
1429  {
1430  if ( valueless_by_exception() && other.valueless_by_exception() )
1431  {
1432  // no effect
1433  }
1434  else if ( ! valueless_by_exception() && other.valueless_by_exception() )
1435  {
1436  helper_type::destroy( type_index, ptr() );
1437  type_index = variant_npos_internal();
1438  }
1439  else if ( index() == other.index() )
1440  {
1441  type_index = helper_type::move( other.type_index, other.ptr(), ptr() );
1442  }
1443  else
1444  {
1445  helper_type::destroy( type_index, ptr() );
1446  type_index = variant_npos_internal();
1447  type_index = helper_type::move( other.type_index, other.ptr(), ptr() );
1448  }
1449  return *this;
1450  }
1451 
1452  template< class T, std::size_t K >
1453  variant & move_assign_value( T && value )
1454  {
1455  if( index() == K )
1456  {
1457  *as<T>() = std::forward<T>( value );
1458  }
1459  else
1460  {
1461  helper_type::destroy( type_index, ptr() );
1462  type_index = variant_npos_internal();
1463  new( ptr() ) T( std::forward<T>( value ) );
1464  type_index = K;
1465  }
1466  return *this;
1467  }
1468 #else
1469  template< class T, std::size_t K >
1470  variant & copy_assign_value( T const & value )
1471  {
1472  if( index() == K )
1473  {
1474  *as<T>() = value;
1475  }
1476  else
1477  {
1478  helper_type::destroy( type_index, ptr() );
1479  type_index = variant_npos_internal();
1480  new( ptr() ) T( value );
1481  type_index = K;
1482  }
1483  return *this;
1484  }
1485 
1486 #endif // variant_CPP11_OR_GREATER
1487 
1488  void swap_value( type_index_t index, variant & other )
1489  {
1490  using std::swap;
1491  switch( index )
1492  {
1493  case 0: swap( this->get<0>(), other.get<0>() ); break;
1494  case 1: swap( this->get<1>(), other.get<1>() ); break;
1495  case 2: swap( this->get<2>(), other.get<2>() ); break;
1496  case 3: swap( this->get<3>(), other.get<3>() ); break;
1497  case 4: swap( this->get<4>(), other.get<4>() ); break;
1498  case 5: swap( this->get<5>(), other.get<5>() ); break;
1499  case 6: swap( this->get<6>(), other.get<6>() ); break;
1500  case 7: swap( this->get<7>(), other.get<7>() ); break;
1501  case 8: swap( this->get<8>(), other.get<8>() ); break;
1502  case 9: swap( this->get<9>(), other.get<9>() ); break;
1503  case 10: swap( this->get<10>(), other.get<10>() ); break;
1504  case 11: swap( this->get<11>(), other.get<11>() ); break;
1505  case 12: swap( this->get<12>(), other.get<12>() ); break;
1506  case 13: swap( this->get<13>(), other.get<13>() ); break;
1507  case 14: swap( this->get<14>(), other.get<14>() ); break;
1508  case 15: swap( this->get<15>(), other.get<15>() ); break;
1509 
1510  }
1511  }
1512 
1513 private:
1514  enum { data_size = detail::typelist_max< variant_types >::value };
1515 
1516 #if variant_CPP11_OR_GREATER
1517 
1518  enum { data_align = detail::typelist_max_alignof< variant_types >::value };
1519 
1520  using aligned_storage_t = typename std::aligned_storage< data_size, data_align >::type;
1521  aligned_storage_t data;
1522 
1523 #elif variant_CONFIG_MAX_ALIGN_HACK
1524 
1525  typedef union { unsigned char data[ data_size ]; } aligned_storage_t;
1526 
1527  detail::max_align_t hack;
1528  aligned_storage_t data;
1529 
1530 #else
1531  typedef typename detail::typelist_max< variant_types >::type max_type;
1532 
1533  typedef variant_ALIGN_AS( max_type ) align_as_type;
1534 
1535  typedef union { align_as_type data[ 1 + ( data_size - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t;
1536  aligned_storage_t data;
1537 
1538 // # undef variant_ALIGN_AS
1539 
1540 #endif // variant_CONFIG_MAX_ALIGN_HACK
1541 
1542  type_index_t type_index;
1543 };
1544 
1545 template< class T, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
1547 {
1548  return v.index() == v.template index_of<T>();
1549 }
1550 
1551 template< class R, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
1553 {
1554  return v.template get<R>();
1555 }
1556 
1557 template< class R, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
1559 {
1560  return v.template get<R>();
1561 }
1562 
1563 template< std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
1566 {
1567  if ( K != v.index() )
1568  {
1569  throw bad_variant_access();
1570  }
1571 
1572  return v.template get<K>();
1573 }
1574 
1575 template< std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
1578 {
1579  if ( K != v.index() )
1580  {
1581  throw bad_variant_access();
1582  }
1583 
1584  return v.template get<K>();
1585 }
1586 
1587 #if variant_CPP11_OR_GREATER
1588 
1589 template< class R, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
1591 {
1592  return std::move(v.template get<R>());
1593 }
1594 
1595 template< class R, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
1596 inline R const && get( variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const && v, nonstd_lite_in_place_type_t(R) = nonstd_lite_in_place_type(R) )
1597 {
1598  return std::move(v.template get<R>());
1599 }
1600 
1601 template< std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
1602 inline typename variant_alternative< K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> >::type &&
1603 get( variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> && v, nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K) )
1604 {
1605  if ( K != v.index() )
1606  {
1607  throw bad_variant_access();
1608  }
1609 
1610  return std::move(v.template get<K>());
1611 }
1612 
1613 template< std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
1614 inline typename variant_alternative< K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> >::type const &&
1615 get( variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> const && v, nonstd_lite_in_place_index_t(K) = nonstd_lite_in_place_index(K) )
1616 {
1617  if ( K != v.index() )
1618  {
1619  throw bad_variant_access();
1620  }
1621 
1622  return std::move(v.template get<K>());
1623 }
1624 
1625 #endif // variant_CPP11_OR_GREATER
1626 
1627 template< class T, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
1628 inline typename detail::add_pointer<T>::type
1630 {
1631  return ( pv->index() == pv->template index_of<T>() ) ? &get<T>( *pv ) : variant_nullptr;
1632 }
1633 
1634 template< class T, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
1635 inline typename detail::add_pointer<const T>::type
1637 {
1638  return ( pv->index() == pv->template index_of<T>() ) ? &get<T>( *pv ) : variant_nullptr;
1639 }
1640 
1641 template< std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
1642 inline typename detail::add_pointer< typename variant_alternative<K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> >::type >::type
1644 {
1645  return ( pv->index() == K ) ? &get<K>( *pv ) : variant_nullptr;
1646 }
1647 
1648 template< std::size_t K, class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
1649 inline typename detail::add_pointer< const typename variant_alternative<K, variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> >::type >::type
1651 {
1652  return ( pv->index() == K ) ? &get<K>( *pv ) : variant_nullptr;
1653 }
1654 
1655 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
1656 inline void swap(
1659 {
1660  a.swap( b );
1661 }
1662 
1663 // Variant 'visitor' implementation
1664 
1665 namespace detail
1666 {
1667 
1668 template< typename R, typename VT >
1670 {
1671  template< typename Visitor, typename T >
1672  static R apply(Visitor const& v, T const& arg)
1673  {
1674  return v(arg);
1675  }
1676 };
1677 
1678 template< typename R, typename VT >
1679 struct VisitorApplicatorImpl<R, TX<VT> >
1680 {
1681  template< typename Visitor, typename T >
1682  static R apply(Visitor const&, T)
1683  {
1684  return R();
1685  }
1686 };
1687 
1688 template<typename R>
1690 
1691 template< typename R, typename Visitor, typename V1 >
1693 
1694 #if variant_CPP11_OR_GREATER
1695 template< size_t NumVars, typename R, typename Visitor, typename ... T >
1696 #else
1697 template< size_t NumVars, typename R, typename Visitor, typename T1, typename T2 = S0, typename T3 = S0, typename T4 = S0, typename T5 = S0 >
1698 #endif
1700 
1701 template< typename R, typename Visitor, typename T2 >
1702 struct TypedVisitorUnwrapper<2, R, Visitor, T2>
1703 {
1704  const Visitor& visitor;
1705  T2 const& val2;
1706 
1707  TypedVisitorUnwrapper(const Visitor& visitor_, T2 const& val2_)
1708  : visitor(visitor_)
1709  , val2(val2_)
1710 
1711  {
1712  }
1713 
1714  template<typename T>
1715  R operator()(const T& val1) const
1716  {
1717  return visitor(val1, val2);
1718  }
1719 };
1720 
1721 template< typename R, typename Visitor, typename T2, typename T3 >
1722 struct TypedVisitorUnwrapper<3, R, Visitor, T2, T3>
1723 {
1724  const Visitor& visitor;
1725  T2 const& val2;
1726  T3 const& val3;
1727 
1728  TypedVisitorUnwrapper(const Visitor& visitor_, T2 const& val2_, T3 const& val3_)
1729  : visitor(visitor_)
1730  , val2(val2_)
1731  , val3(val3_)
1732 
1733  {
1734  }
1735 
1736  template<typename T>
1737  R operator()(const T& val1) const
1738  {
1739  return visitor(val1, val2, val3);
1740  }
1741 };
1742 
1743 template< typename R, typename Visitor, typename T2, typename T3, typename T4 >
1744 struct TypedVisitorUnwrapper<4, R, Visitor, T2, T3, T4>
1745 {
1746  const Visitor& visitor;
1747  T2 const& val2;
1748  T3 const& val3;
1749  T4 const& val4;
1750 
1751  TypedVisitorUnwrapper(const Visitor& visitor_, T2 const& val2_, T3 const& val3_, T4 const& val4_)
1752  : visitor(visitor_)
1753  , val2(val2_)
1754  , val3(val3_)
1755  , val4(val4_)
1756 
1757  {
1758  }
1759 
1760  template<typename T>
1761  R operator()(const T& val1) const
1762  {
1763  return visitor(val1, val2, val3, val4);
1764  }
1765 };
1766 
1767 template< typename R, typename Visitor, typename T2, typename T3, typename T4, typename T5 >
1768 struct TypedVisitorUnwrapper<5, R, Visitor, T2, T3, T4, T5>
1769 {
1770  const Visitor& visitor;
1771  T2 const& val2;
1772  T3 const& val3;
1773  T4 const& val4;
1774  T5 const& val5;
1775 
1776  TypedVisitorUnwrapper(const Visitor& visitor_, T2 const& val2_, T3 const& val3_, T4 const& val4_, T5 const& val5_)
1777  : visitor(visitor_)
1778  , val2(val2_)
1779  , val3(val3_)
1780  , val4(val4_)
1781  , val5(val5_)
1782 
1783  {
1784  }
1785 
1786  template<typename T>
1787  R operator()(const T& val1) const
1788  {
1789  return visitor(val1, val2, val3, val4, val5);
1790  }
1791 };
1792 
1793 
1794 
1795 template<typename R, typename Visitor, typename V2>
1796 struct VisitorUnwrapper
1797 {
1798  const Visitor& visitor;
1799  const V2& r;
1800 
1801  VisitorUnwrapper(const Visitor& visitor_, const V2& r_)
1802  : visitor(visitor_)
1803  , r(r_)
1804  {
1805  }
1806 
1807 
1808  template< typename T1 >
1809  R operator()(T1 const& val1) const
1810  {
1811  typedef TypedVisitorUnwrapper<2, R, Visitor, T1> visitor_type;
1812  return VisitorApplicator<R>::apply(visitor_type(visitor, val1), r);
1813  }
1814 
1815  template< typename T1, typename T2 >
1816  R operator()(T1 const& val1, T2 const& val2) const
1817  {
1818  typedef TypedVisitorUnwrapper<3, R, Visitor, T1, T2> visitor_type;
1819  return VisitorApplicator<R>::apply(visitor_type(visitor, val1, val2), r);
1820  }
1821 
1822  template< typename T1, typename T2, typename T3 >
1823  R operator()(T1 const& val1, T2 const& val2, T3 const& val3) const
1824  {
1826  return VisitorApplicator<R>::apply(visitor_type(visitor, val1, val2, val3), r);
1827  }
1828 
1829  template< typename T1, typename T2, typename T3, typename T4 >
1830  R operator()(T1 const& val1, T2 const& val2, T3 const& val3, T4 const& val4) const
1831  {
1833  return VisitorApplicator<R>::apply(visitor_type(visitor, val1, val2, val3, val4), r);
1834  }
1835 
1836  template< typename T1, typename T2, typename T3, typename T4, typename T5 >
1837  R operator()(T1 const& val1, T2 const& val2, T3 const& val3, T4 const& val4, T5 const& val5) const
1838  {
1840  return VisitorApplicator<R>::apply(visitor_type(visitor, val1, val2, val3, val4, val5), r);
1841  }
1842 
1843 };
1844 
1845 
1846 template<typename R>
1847 struct VisitorApplicator
1848 {
1849  template<typename Visitor, typename V1>
1850  static R apply(const Visitor& v, const V1& arg)
1851  {
1852  switch( arg.index() )
1853  {
1854  case 0: return apply_visitor<0>(v, arg);
1855  case 1: return apply_visitor<1>(v, arg);
1856  case 2: return apply_visitor<2>(v, arg);
1857  case 3: return apply_visitor<3>(v, arg);
1858  case 4: return apply_visitor<4>(v, arg);
1859  case 5: return apply_visitor<5>(v, arg);
1860  case 6: return apply_visitor<6>(v, arg);
1861  case 7: return apply_visitor<7>(v, arg);
1862  case 8: return apply_visitor<8>(v, arg);
1863  case 9: return apply_visitor<9>(v, arg);
1864  case 10: return apply_visitor<10>(v, arg);
1865  case 11: return apply_visitor<11>(v, arg);
1866  case 12: return apply_visitor<12>(v, arg);
1867  case 13: return apply_visitor<13>(v, arg);
1868  case 14: return apply_visitor<14>(v, arg);
1869  case 15: return apply_visitor<15>(v, arg);
1870 
1871  default: return R();
1872  }
1873  }
1874 
1875  template<size_t Idx, typename Visitor, typename V1>
1876  static R apply_visitor(const Visitor& v, const V1& arg)
1877  {
1878 
1879 #if variant_CPP11_OR_GREATER
1880  typedef typename variant_alternative<Idx, typename std::decay<V1>::type>::type value_type;
1881 #else
1882  typedef typename variant_alternative<Idx, V1>::type value_type;
1883 #endif
1884  return VisitorApplicatorImpl<R, value_type>::apply(v, get<Idx>(arg));
1885  }
1886 
1887 #if variant_CPP11_OR_GREATER
1888  template<typename Visitor, typename V1, typename V2, typename ... V>
1889  static R apply(const Visitor& v, const V1& arg1, const V2& arg2, const V ... args)
1890  {
1891  typedef VisitorUnwrapper<R, Visitor, V1> Unwrapper;
1892  Unwrapper unwrapper(v, arg1);
1893  return apply(unwrapper, arg2, args ...);
1894  }
1895 #else
1896 
1897  template< typename Visitor, typename V1, typename V2 >
1898  static R apply(const Visitor& v, V1 const& arg1, V2 const& arg2)
1899  {
1900  typedef VisitorUnwrapper<R, Visitor, V1> Unwrapper;
1901  Unwrapper unwrapper(v, arg1);
1902  return apply(unwrapper, arg2);
1903  }
1904 
1905  template< typename Visitor, typename V1, typename V2, typename V3 >
1906  static R apply(const Visitor& v, V1 const& arg1, V2 const& arg2, V3 const& arg3)
1907  {
1908  typedef VisitorUnwrapper<R, Visitor, V1> Unwrapper;
1909  Unwrapper unwrapper(v, arg1);
1910  return apply(unwrapper, arg2, arg3);
1911  }
1912 
1913  template< typename Visitor, typename V1, typename V2, typename V3, typename V4 >
1914  static R apply(const Visitor& v, V1 const& arg1, V2 const& arg2, V3 const& arg3, V4 const& arg4)
1915  {
1916  typedef VisitorUnwrapper<R, Visitor, V1> Unwrapper;
1917  Unwrapper unwrapper(v, arg1);
1918  return apply(unwrapper, arg2, arg3, arg4);
1919  }
1920 
1921  template< typename Visitor, typename V1, typename V2, typename V3, typename V4, typename V5 >
1922  static R apply(const Visitor& v, V1 const& arg1, V2 const& arg2, V3 const& arg3, V4 const& arg4, V5 const& arg5)
1923  {
1924  typedef VisitorUnwrapper<R, Visitor, V1> Unwrapper;
1925  Unwrapper unwrapper(v, arg1);
1926  return apply(unwrapper, arg2, arg3, arg4, arg5);
1927  }
1928 
1929 #endif
1930 };
1931 
1932 #if variant_CPP11_OR_GREATER
1933 template< size_t NumVars, typename Visitor, typename ... V >
1934 struct VisitorImpl
1935 {
1936  typedef decltype(std::declval<Visitor>()(get<0>(static_cast<const V&>(std::declval<V>()))...)) result_type;
1937  typedef VisitorApplicator<result_type> applicator_type;
1938 };
1939 #endif
1940 } // detail
1941 
1942 #if variant_CPP11_OR_GREATER
1943 // No perfect forwarding here in order to simplify code
1944 template< typename Visitor, typename ... V >
1945 inline auto visit(Visitor const& v, V const& ... vars) -> typename detail::VisitorImpl<sizeof ... (V), Visitor, V... > ::result_type
1946 {
1947  typedef detail::VisitorImpl<sizeof ... (V), Visitor, V... > impl_type;
1948  return impl_type::applicator_type::apply(v, vars...);
1949 }
1950 #else
1951 
1952 template< typename R, typename Visitor, typename V1 >
1953 inline R visit(const Visitor& v, V1 const& arg1)
1954 {
1955  return detail::VisitorApplicator<R>::apply(v, arg1);
1956 }
1957 
1958 template< typename R, typename Visitor, typename V1, typename V2 >
1959 inline R visit(const Visitor& v, V1 const& arg1, V2 const& arg2)
1960 {
1961  return detail::VisitorApplicator<R>::apply(v, arg1, arg2);
1962 }
1963 
1964 template< typename R, typename Visitor, typename V1, typename V2, typename V3 >
1965 inline R visit(const Visitor& v, V1 const& arg1, V2 const& arg2, V3 const& arg3)
1966 {
1967  return detail::VisitorApplicator<R>::apply(v, arg1, arg2, arg3);
1968 }
1969 
1970 template< typename R, typename Visitor, typename V1, typename V2, typename V3, typename V4 >
1971 inline R visit(const Visitor& v, V1 const& arg1, V2 const& arg2, V3 const& arg3, V4 const& arg4)
1972 {
1973  return detail::VisitorApplicator<R>::apply(v, arg1, arg2, arg3, arg4);
1974 }
1975 
1976 template< typename R, typename Visitor, typename V1, typename V2, typename V3, typename V4, typename V5 >
1977 inline R visit(const Visitor& v, V1 const& arg1, V2 const& arg2, V3 const& arg3, V4 const& arg4, V5 const& arg5)
1978 {
1979  return detail::VisitorApplicator<R>::apply(v, arg1, arg2, arg3, arg4, arg5);
1980 }
1981 
1982 #endif
1983 
1984 
1985 namespace detail {
1986 
1987 template< class Variant >
1989 {
1990  static inline bool equal( Variant const & v, Variant const & w )
1991  {
1992  switch( v.index() )
1993  {
1994  case 0: return get<0>( v ) == get<0>( w );
1995  case 1: return get<1>( v ) == get<1>( w );
1996  case 2: return get<2>( v ) == get<2>( w );
1997  case 3: return get<3>( v ) == get<3>( w );
1998  case 4: return get<4>( v ) == get<4>( w );
1999  case 5: return get<5>( v ) == get<5>( w );
2000  case 6: return get<6>( v ) == get<6>( w );
2001  case 7: return get<7>( v ) == get<7>( w );
2002  case 8: return get<8>( v ) == get<8>( w );
2003  case 9: return get<9>( v ) == get<9>( w );
2004  case 10: return get<10>( v ) == get<10>( w );
2005  case 11: return get<11>( v ) == get<11>( w );
2006  case 12: return get<12>( v ) == get<12>( w );
2007  case 13: return get<13>( v ) == get<13>( w );
2008  case 14: return get<14>( v ) == get<14>( w );
2009  case 15: return get<15>( v ) == get<15>( w );
2010 
2011  default: return false;
2012  }
2013  }
2014 
2015  static inline bool less_than( Variant const & v, Variant const & w )
2016  {
2017  switch( v.index() )
2018  {
2019  case 0: return get<0>( v ) < get<0>( w );
2020  case 1: return get<1>( v ) < get<1>( w );
2021  case 2: return get<2>( v ) < get<2>( w );
2022  case 3: return get<3>( v ) < get<3>( w );
2023  case 4: return get<4>( v ) < get<4>( w );
2024  case 5: return get<5>( v ) < get<5>( w );
2025  case 6: return get<6>( v ) < get<6>( w );
2026  case 7: return get<7>( v ) < get<7>( w );
2027  case 8: return get<8>( v ) < get<8>( w );
2028  case 9: return get<9>( v ) < get<9>( w );
2029  case 10: return get<10>( v ) < get<10>( w );
2030  case 11: return get<11>( v ) < get<11>( w );
2031  case 12: return get<12>( v ) < get<12>( w );
2032  case 13: return get<13>( v ) < get<13>( w );
2033  case 14: return get<14>( v ) < get<14>( w );
2034  case 15: return get<15>( v ) < get<15>( w );
2035 
2036  default: return false;
2037  }
2038  }
2039 };
2040 
2041 } //namespace detail
2042 
2043 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
2044 inline bool operator==(
2047 {
2048  if ( v.index() != w.index() ) return false;
2049  else if ( v.valueless_by_exception() ) return true;
2051 }
2052 
2053 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
2054 inline bool operator!=(
2057 {
2058  return ! ( v == w );
2059 }
2060 
2061 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
2062 inline bool operator<(
2065 {
2066  if ( w.valueless_by_exception() ) return false;
2067  else if ( v.valueless_by_exception() ) return true;
2068  else if ( v.index() < w.index() ) return true;
2069  else if ( v.index() > w.index() ) return false;
2071 }
2072 
2073 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
2074 inline bool operator>(
2077 {
2078  return w < v;
2079 }
2080 
2081 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
2082 inline bool operator<=(
2085 {
2086  return ! ( v > w );
2087 }
2088 
2089 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
2090 inline bool operator>=(
2093 {
2094  return ! ( v < w );
2095 }
2096 
2097 } // namespace variants
2098 
2099 using namespace variants;
2100 
2101 } // namespace nonstd
2102 
2103 #if variant_CPP11_OR_GREATER
2104 
2105 // specialize the std::hash algorithm:
2106 
2107 namespace std {
2108 
2109 template<>
2110 struct hash< nonstd::monostate >
2111 {
2112  std::size_t operator()( nonstd::monostate ) const variant_noexcept
2113  {
2114  return 42;
2115  }
2116 };
2117 
2118 template< class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15 >
2119 struct hash< nonstd::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> >
2120 {
2122  {
2123  return nonstd::variants::detail::hash( v );
2124  }
2125 };
2126 
2127 } //namespace std
2128 
2129 #endif // variant_CPP11_OR_GREATER
2130 
2131 #if variant_BETWEEN( variant_COMPILER_MSVC_VER, 1300, 1900 )
2132 # pragma warning( pop )
2133 #endif
2134 
2135 #endif // variant_USES_STD_VARIANT
2136 
2137 #endif // NONSTD_VARIANT_LITE_HPP
TX< T > operator-() const
Definition: variant.hpp:477
TypedVisitorUnwrapper(const Visitor &visitor_, T2 const &val2_)
Definition: variant.hpp:1707
bool operator<(T const &) const
Definition: variant.hpp:495
variant & operator=(T2 const &t2)
Definition: variant.hpp:1216
static R apply(Visitor const &v, T const &arg)
Definition: variant.hpp:1672
std::size_t index() const
Definition: variant.hpp:1233
conditional<(sizeof(Head) > tail_value), Head, tail_type >::type type
Definition: variant.hpp:555
static R apply(const Visitor &v, V1 const &arg1, V2 const &arg2, V3 const &arg3, V4 const &arg4, V5 const &arg5)
Definition: variant.hpp:1922
static R apply(const Visitor &v, V1 const &arg1, V2 const &arg2, V3 const &arg3)
Definition: variant.hpp:1906
static bool equal(Variant const &v, Variant const &w)
Definition: variant.hpp:1990
static R apply_visitor(const Visitor &v, const V1 &arg)
Definition: variant.hpp:1876
variant(variant const &other)
Definition: variant.hpp:1092
variant(T11 const &t11)
Definition: variant.hpp:1065
variant_constexpr bool operator>=(monostate, monostate) variant_noexcept
Definition: variant.hpp:960
TypedVisitorUnwrapper(const Visitor &visitor_, T2 const &val2_, T3 const &val3_)
Definition: variant.hpp:1728
R operator()(T1 const &val1, T2 const &val2, T3 const &val3) const
Definition: variant.hpp:1823
detail::typelist_type_at< variant_TL16(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15), K >::type type
Definition: variant.hpp:992
VisitorUnwrapper(const Visitor &visitor_, const V2 &r_)
Definition: variant.hpp:1801
static R apply(const Visitor &v, V1 const &arg1, V2 const &arg2)
Definition: variant.hpp:1898
typedef variant_ALIGN_TYPE(char)
R & get(variant< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 > &v, nonstd_lite_in_place_type_t(R)=nonstd_lite_in_place_type(R))
Definition: variant.hpp:1552
#define variant_TL16(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)
Definition: variant.hpp:468
TX< T > operator &&(U const &) const
Definition: variant.hpp:501
bool valueless_by_exception() const
Definition: variant.hpp:1238
variant & operator=(variant const &other)
Definition: variant.hpp:1168
conditional< N==sizeof(typename List::head), typename List::head, typename type_of_size< typename List::tail, N >::type >::type type
Definition: variant.hpp:758
#define nonstd_lite_in_place_index(K)
Definition: variant.hpp:153
variant_constexpr bool operator<(monostate, monostate) variant_noexcept
Definition: variant.hpp:957
variant & operator=(T7 const &t7)
Definition: variant.hpp:1221
static const std::size_t variant_npos
Definition: variant.hpp:1012
R operator()(T1 const &val1, T2 const &val2, T3 const &val3, T4 const &val4, T5 const &val5) const
Definition: variant.hpp:1837
TX< T > operator *(U const &) const
Definition: variant.hpp:484
static R apply(const Visitor &v, V1 const &arg1, V2 const &arg2, V3 const &arg3, V4 const &arg4)
Definition: variant.hpp:1914
in_place_t in_place_index(detail::in_place_index_tag< K >=detail::in_place_index_tag< K >())
Definition: any.hpp:132
variant_constexpr std::size_t index_of() const variant_noexcept
Definition: variant.hpp:1309
TX< T > operator||(U const &) const
Definition: variant.hpp:502
std::size_t hash(T const &v)
Definition: variant.hpp:807
TX< T > operator/(U const &) const
Definition: variant.hpp:485
variant_constexpr bool operator>(monostate, monostate) variant_noexcept
Definition: variant.hpp:958
#define nonstd_lite_in_place_type(T)
Definition: variant.hpp:152
T const & get() const
Definition: variant.hpp:1328
variant(T14 const &t14)
Definition: variant.hpp:1068
R operator()(T1 const &val1, T2 const &val2) const
Definition: variant.hpp:1816
void swap(variant< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 > &a, variant< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 > &b) variant_noexcept
Definition: variant.hpp:1656
#define variant_constexpr
Definition: variant.hpp:326
void swap(variant &other) variant_noexcept
Definition: variant.hpp:1286
#define variant_override
Definition: variant.hpp:350
#define variant_CONFIG_ALIGN_AS_FALLBACK
Definition: variant.hpp:222
variant & operator=(T11 const &t11)
Definition: variant.hpp:1225
TX< T > operator<<(U const &) const
Definition: variant.hpp:491
TX< T > operator+() const
Definition: variant.hpp:476
variant & operator=(T3 const &t3)
Definition: variant.hpp:1217
#define variant_nullptr
Definition: variant.hpp:344
TX< T > operator>>(U const &) const
Definition: variant.hpp:492
variant & operator=(T9 const &t9)
Definition: variant.hpp:1223
static U const * as(void const *data)
Definition: variant.hpp:841
variant & operator=(T6 const &t6)
Definition: variant.hpp:1220
Definition: any.hpp:100
variant_constexpr bool operator<=(monostate, monostate) variant_noexcept
Definition: variant.hpp:959
#define nonstd_lite_in_place_index_t(K)
Definition: variant.hpp:149
TypedVisitorUnwrapper(const Visitor &visitor_, T2 const &val2_, T3 const &val3_, T4 const &val4_, T5 const &val5_)
Definition: variant.hpp:1776
variant_constexpr bool operator==(monostate, monostate) variant_noexcept
Definition: variant.hpp:961
detail::add_pointer< const typename variant_alternative< K, variant< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 > >::type >::type get_if(variant< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 > const *pv, nonstd_lite_in_place_index_t(K)=nonstd_lite_in_place_index(K))
Definition: variant.hpp:1650
TypedVisitorUnwrapper(const Visitor &visitor_, T2 const &val2_, T3 const &val3_, T4 const &val4_)
Definition: variant.hpp:1751
detail::add_pointer< T >::type get_if(variant< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 > *pv, nonstd_lite_in_place_type_t(T)=nonstd_lite_in_place_type(T))
Definition: variant.hpp:1629
variant & operator=(T8 const &t8)
Definition: variant.hpp:1222
variant_alternative< K, variant >::type & get()
Definition: variant.hpp:1342
TX< T > operator!() const
Definition: variant.hpp:479
variant & operator=(T0 const &t0)
Definition: variant.hpp:1214
static void destroy(type_index_t index, void *data)
Definition: variant.hpp:851
variant(T10 const &t10)
Definition: variant.hpp:1064
static type_index_t to_index_t(std::size_t index)
Definition: variant.hpp:846
static U * as(void *data)
Definition: variant.hpp:835
remove_reference< T >::type * type
Definition: variant.hpp:409
TX< T > operator|(U const &) const
Definition: variant.hpp:498
#define variant_noexcept
Definition: variant.hpp:338
variant & operator=(T5 const &t5)
Definition: variant.hpp:1219
static type_index_t copy(type_index_t const from_index, const void *from_value, void *to_value)
Definition: variant.hpp:920
variant(T13 const &t13)
Definition: variant.hpp:1067
in_place_t in_place_type(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())
Definition: any.hpp:126
variant_constexpr bool operator!=(monostate, monostate) variant_noexcept
Definition: variant.hpp:962
bool holds_alternative(variant< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 > const &v) variant_noexcept
Definition: variant.hpp:1546
variant(T12 const &t12)
Definition: variant.hpp:1066
R operator()(T1 const &val1, T2 const &val2, T3 const &val3, T4 const &val4) const
Definition: variant.hpp:1830
TX< T > operator^(U const &) const
Definition: variant.hpp:499
virtual const char * what() const
Definition: variant.hpp:1021
variant & operator=(T14 const &t14)
Definition: variant.hpp:1228
variant & operator=(T13 const &t13)
Definition: variant.hpp:1227
TX< T > * operator &() const
Definition: variant.hpp:482
variant & operator=(T1 const &t1)
Definition: variant.hpp:1215
variant & operator=(T12 const &t12)
Definition: variant.hpp:1226
TX< T > operator~() const
Definition: variant.hpp:480
variant_alternative< K, variant >::type const & get() const
Definition: variant.hpp:1349
remove_volatile< typename remove_const< T >::type >::type type
Definition: variant.hpp:429
variant_alternative< K, variant< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 > >::type const & get(variant< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 > const &v, nonstd_lite_in_place_index_t(K)=nonstd_lite_in_place_index(K))
Definition: variant.hpp:1577
static R apply(const Visitor &v, const V1 &arg)
Definition: variant.hpp:1850
variant & operator=(T15 const &t15)
Definition: variant.hpp:1229
TX< T > operator%(U const &) const
Definition: variant.hpp:487
bool operator==(T const &) const
Definition: variant.hpp:494
R visit(const Visitor &v, V1 const &arg1, V2 const &arg2, V3 const &arg3, V4 const &arg4, V5 const &arg5)
Definition: variant.hpp:1977
variant & operator=(T4 const &t4)
Definition: variant.hpp:1218
in_place_t in_place(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())
Definition: any.hpp:114
static bool less_than(Variant const &v, Variant const &w)
Definition: variant.hpp:2015
typedef variant_TL16(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) variant_types
#define nonstd_lite_in_place_type_t(T)
Definition: variant.hpp:148
variant & operator=(T10 const &t10)
Definition: variant.hpp:1224
R visit(const Visitor &v, V1 const &arg1)
Definition: variant.hpp:1953
variant(T15 const &t15)
Definition: variant.hpp:1069