You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					1214 lines
				
				29 KiB
			
		
		
			
		
	
	
					1214 lines
				
				29 KiB
			| 
											7 years ago
										 | //
 | ||
|  | // Copyright (c) 2014-2018 Martin Moene
 | ||
|  | //
 | ||
|  | // https://github.com/martinmoene/optional-lite
 | ||
|  | //
 | ||
|  | // Distributed under the Boost Software License, Version 1.0. 
 | ||
|  | // (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | ||
|  | 
 | ||
|  | #pragma once
 | ||
|  | 
 | ||
|  | #ifndef NONSTD_OPTIONAL_LITE_HPP
 | ||
|  | #define NONSTD_OPTIONAL_LITE_HPP
 | ||
|  | 
 | ||
|  | #define  optional_lite_VERSION "3.0.0"
 | ||
|  | 
 | ||
|  | // Compiler detection (C++20 is speculative):
 | ||
|  | // Note: MSVC supports C++14 since it supports C++17.
 | ||
|  | 
 | ||
|  | #ifdef _MSVC_LANG
 | ||
|  | # define optional_MSVC_LANG  _MSVC_LANG
 | ||
|  | #else
 | ||
|  | # define optional_MSVC_LANG  0
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #define optional_CPP11             (__cplusplus == 201103L )
 | ||
|  | #define optional_CPP11_OR_GREATER  (__cplusplus >= 201103L || optional_MSVC_LANG >= 201103L )
 | ||
|  | #define optional_CPP14_OR_GREATER  (__cplusplus >= 201402L || optional_MSVC_LANG >= 201703L )
 | ||
|  | #define optional_CPP17_OR_GREATER  (__cplusplus >= 201703L || optional_MSVC_LANG >= 201703L )
 | ||
|  | #define optional_CPP20_OR_GREATER  (__cplusplus >= 202000L || optional_MSVC_LANG >= 202000L )
 | ||
|  | 
 | ||
|  | // use C++17 std::optional if available:
 | ||
|  | 
 | ||
|  | #if defined( __has_include )
 | ||
|  | # define optional_HAS_INCLUDE( arg )  __has_include( arg )
 | ||
|  | #else
 | ||
|  | # define optional_HAS_INCLUDE( arg )  0
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #define optional_HAVE_STD_OPTIONAL  ( optional_CPP17_OR_GREATER && optional_HAS_INCLUDE( <optional> ) )
 | ||
|  | 
 | ||
|  | #if optional_HAVE_STD_OPTIONAL
 | ||
|  | 
 | ||
|  | #include <optional>
 | ||
|  | 
 | ||
|  | namespace nonstd { | ||
|  | 
 | ||
|  |     using std::optional; | ||
|  |     using std::bad_optional_access; | ||
|  |     using std::hash; | ||
|  | 
 | ||
|  |     using std::nullopt; | ||
|  |     using std::nullopt_t; | ||
|  |     using std::in_place; | ||
|  |     using std::in_place_type; | ||
|  |     using std::in_place_index; | ||
|  |     using std::in_place_t; | ||
|  |     using std::in_place_type_t; | ||
|  |     using std::in_place_index_t; | ||
|  | 
 | ||
|  |     using std::operator==; | ||
|  |     using std::operator!=; | ||
|  |     using std::operator<; | ||
|  |     using std::operator<=; | ||
|  |     using std::operator>; | ||
|  |     using std::operator>=; | ||
|  |     using std::make_optional; | ||
|  |     using std::swap; | ||
|  | } | ||
|  | 
 | ||
|  | #else // C++17 std::optional
 | ||
|  | 
 | ||
|  | #include <cassert>
 | ||
|  | #include <stdexcept>
 | ||
|  | #include <utility>
 | ||
|  | 
 | ||
|  | // optional-lite alignment configuration:
 | ||
|  | 
 | ||
|  | #ifndef  optional_CONFIG_MAX_ALIGN_HACK
 | ||
|  | # define optional_CONFIG_MAX_ALIGN_HACK  0
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef  optional_CONFIG_ALIGN_AS
 | ||
|  | // no default, used in #if defined()
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #ifndef  optional_CONFIG_ALIGN_AS_FALLBACK
 | ||
|  | # define optional_CONFIG_ALIGN_AS_FALLBACK  double
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | // Compiler warning suppression:
 | ||
|  | 
 | ||
|  | #ifdef __clang__
 | ||
|  | # pragma clang diagnostic push
 | ||
|  | # pragma clang diagnostic ignored "-Wundef"
 | ||
|  | #elif defined __GNUC__
 | ||
|  | # pragma GCC   diagnostic push
 | ||
|  | # pragma GCC   diagnostic ignored "-Wundef"
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | // half-open range [lo..hi):
 | ||
|  | #define optional_BETWEEN( v, lo, hi ) ( lo <= v && v < hi )
 | ||
|  | 
 | ||
|  | #if defined(_MSC_VER) && !defined(__clang__)
 | ||
|  | # define optional_COMPILER_MSVC_VERSION   (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900)) )
 | ||
|  | #else
 | ||
|  | # define optional_COMPILER_MSVC_VERSION   0
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #define optional_COMPILER_VERSION( major, minor, patch )  ( 10 * (10 * major + minor ) + patch )
 | ||
|  | 
 | ||
|  | #if defined __GNUC__
 | ||
|  | # define optional_COMPILER_GNUC_VERSION   optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
 | ||
|  | #else
 | ||
|  | # define optional_COMPILER_GNUC_VERSION   0
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if defined __clang__
 | ||
|  | # define optional_COMPILER_CLANG_VERSION  optional_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
 | ||
|  | #else
 | ||
|  | # define optional_COMPILER_CLANG_VERSION  0
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 140 )
 | ||
|  | # pragma warning( push )
 | ||
|  | # pragma warning( disable: 4345 )   // initialization behavior changed
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 150 )
 | ||
|  | # pragma warning( push )
 | ||
|  | # pragma warning( disable: 4814 )   // in C++14 'constexpr' will not imply 'const'
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | // Presence of language and library features:
 | ||
|  | 
 | ||
|  | #define optional_HAVE(FEATURE) ( optional_HAVE_##FEATURE )
 | ||
|  | 
 | ||
|  | // Presence of C++11 language features:
 | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 100
 | ||
|  | # define optional_HAVE_AUTO  1
 | ||
|  | # define optional_HAVE_NULLPTR  1
 | ||
|  | # define optional_HAVE_STATIC_ASSERT  1
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 120
 | ||
|  | # define optional_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG  1
 | ||
|  | # define optional_HAVE_INITIALIZER_LIST  1
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 140
 | ||
|  | # define optional_HAVE_ALIAS_TEMPLATE  1
 | ||
|  | # define optional_HAVE_CONSTEXPR_11  1
 | ||
|  | # define optional_HAVE_ENUM_CLASS  1
 | ||
|  | # define optional_HAVE_EXPLICIT_CONVERSION  1
 | ||
|  | # define optional_HAVE_IS_DEFAULT  1
 | ||
|  | # define optional_HAVE_IS_DELETE  1
 | ||
|  | # define optional_HAVE_NOEXCEPT  1
 | ||
|  | # define optional_HAVE_REF_QUALIFIER  1
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | // Presence of C++14 language features:
 | ||
|  | 
 | ||
|  | #if optional_CPP14_OR_GREATER
 | ||
|  | # define optional_HAVE_CONSTEXPR_14  1
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | // Presence of C++17 language features:
 | ||
|  | 
 | ||
|  | #if optional_CPP17_OR_GREATER
 | ||
|  | # define optional_HAVE_ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE  1
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | // Presence of C++ library features:
 | ||
|  | 
 | ||
|  | #if optional_COMPILER_GNUC_VERSION
 | ||
|  | # define optional_HAVE_TR1_TYPE_TRAITS  1
 | ||
|  | # define optional_HAVE_TR1_ADD_POINTER  1
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 90
 | ||
|  | # define optional_HAVE_TYPE_TRAITS  1
 | ||
|  | # define optional_HAVE_STD_ADD_POINTER  1
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 110
 | ||
|  | # define optional_HAVE_ARRAY  1
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 120
 | ||
|  | # define optional_HAVE_CONDITIONAL  1
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 140 || (optional_COMPILER_MSVC_VERSION >= 90 && _HAS_CPP0X)
 | ||
|  | # define optional_HAVE_CONTAINER_DATA_METHOD  1
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 120
 | ||
|  | # define optional_HAVE_REMOVE_CV  1
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 140
 | ||
|  | # define optional_HAVE_SIZED_TYPES  1
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | // For the rest, consider VC14 as C++11 for optional-lite:
 | ||
|  | 
 | ||
|  | #if optional_COMPILER_MSVC_VERSION >= 140
 | ||
|  | # undef  optional_CPP11_OR_GREATER
 | ||
|  | # define optional_CPP11_OR_GREATER  1
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | // C++ feature usage:
 | ||
|  | 
 | ||
|  | #if optional_HAVE( CONSTEXPR_11 )
 | ||
|  | # define optional_constexpr  constexpr
 | ||
|  | #else
 | ||
|  | # define optional_constexpr  /*constexpr*/
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_HAVE( CONSTEXPR_14 )
 | ||
|  | # define optional_constexpr14  constexpr
 | ||
|  | #else
 | ||
|  | # define optional_constexpr14  /*constexpr*/
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_HAVE( NOEXCEPT )
 | ||
|  | # define optional_noexcept  noexcept
 | ||
|  | #else
 | ||
|  | # define optional_noexcept  /*noexcept*/
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_HAVE( NULLPTR )
 | ||
|  | # define optional_nullptr  nullptr
 | ||
|  | #else
 | ||
|  | # define optional_nullptr  NULL
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_HAVE( REF_QUALIFIER )
 | ||
|  | # define optional_ref_qual  &
 | ||
|  | # define optional_refref_qual  &&
 | ||
|  | #else
 | ||
|  | # define optional_ref_qual  /*&*/
 | ||
|  | # define optional_refref_qual  /*&&*/
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | // additional includes:
 | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  | # include <functional>
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_HAVE( INITIALIZER_LIST )
 | ||
|  | # include <initializer_list>
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_HAVE( TYPE_TRAITS )
 | ||
|  | # include <type_traits>
 | ||
|  | #elif optional_HAVE( TR1_TYPE_TRAITS )
 | ||
|  | # include <tr1/type_traits>
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | // type traits needed:
 | ||
|  | 
 | ||
|  | namespace nonstd { namespace optional_lite { namespace detail { | ||
|  | 
 | ||
|  | #if optional_HAVE( CONDITIONAL )
 | ||
|  |     using std::conditional; | ||
|  | #else
 | ||
|  |     template< bool B, typename T, typename F > struct conditional              { typedef T type; }; | ||
|  |     template<         typename T, typename F > struct conditional<false, T, F> { typedef F type; }; | ||
|  | #endif // optional_HAVE_CONDITIONAL
 | ||
|  | 
 | ||
|  | }}} | ||
|  | 
 | ||
|  | //
 | ||
|  | // in_place: code duplicated in any-lite, optional-lite, variant-lite:
 | ||
|  | //
 | ||
|  | 
 | ||
|  | #ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
 | ||
|  | 
 | ||
|  | namespace nonstd { | ||
|  | 
 | ||
|  | namespace detail { | ||
|  | 
 | ||
|  | template< class T > | ||
|  | struct in_place_type_tag {}; | ||
|  | 
 | ||
|  | template< std::size_t I > | ||
|  | struct in_place_index_tag {}; | ||
|  | 
 | ||
|  | } // namespace detail
 | ||
|  | 
 | ||
|  | struct in_place_t {}; | ||
|  | 
 | ||
|  | template< class T > | ||
|  | inline in_place_t in_place( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() ) | ||
|  | { | ||
|  |     return in_place_t(); | ||
|  | } | ||
|  | 
 | ||
|  | template< std::size_t I > | ||
|  | inline in_place_t in_place( detail::in_place_index_tag<I> = detail::in_place_index_tag<I>() ) | ||
|  | { | ||
|  |     return in_place_t(); | ||
|  | } | ||
|  | 
 | ||
|  | template< class T > | ||
|  | inline in_place_t in_place_type( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() ) | ||
|  | { | ||
|  |     return in_place_t(); | ||
|  | } | ||
|  | 
 | ||
|  | template< std::size_t I > | ||
|  | inline in_place_t in_place_index( detail::in_place_index_tag<I> = detail::in_place_index_tag<I>() ) | ||
|  | { | ||
|  |     return in_place_t(); | ||
|  | } | ||
|  | 
 | ||
|  | // mimic templated typedef:
 | ||
|  | 
 | ||
|  | #define nonstd_lite_in_place_type_t( T)  nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T>  )
 | ||
|  | #define nonstd_lite_in_place_index_t(T)  nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<I> )
 | ||
|  | 
 | ||
|  | #define nonstd_lite_HAVE_IN_PLACE_TYPES  1
 | ||
|  | 
 | ||
|  | } // namespace nonstd
 | ||
|  | 
 | ||
|  | #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
 | ||
|  | 
 | ||
|  | //
 | ||
|  | // optional:
 | ||
|  | //
 | ||
|  | 
 | ||
|  | namespace nonstd { namespace optional_lite { | ||
|  | 
 | ||
|  | /// class optional
 | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | class optional; | ||
|  | 
 | ||
|  | namespace detail { | ||
|  | 
 | ||
|  | // C++11 emulation:
 | ||
|  | 
 | ||
|  | struct nulltype{}; | ||
|  | 
 | ||
|  | template< typename Head, typename Tail > | ||
|  | struct typelist | ||
|  | { | ||
|  |     typedef Head head; | ||
|  |     typedef Tail tail; | ||
|  | }; | ||
|  | 
 | ||
|  | #if optional_CONFIG_MAX_ALIGN_HACK
 | ||
|  | 
 | ||
|  | // Max align, use most restricted type for alignment:
 | ||
|  | 
 | ||
|  | #define optional_UNIQUE(  name )       optional_UNIQUE2( name, __LINE__ )
 | ||
|  | #define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line )
 | ||
|  | #define optional_UNIQUE3( name, line ) name ## line
 | ||
|  | 
 | ||
|  | #define optional_ALIGN_TYPE( type ) \
 | ||
|  |     type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st ) | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | struct struct_t { T _; }; | ||
|  | 
 | ||
|  | union max_align_t | ||
|  | { | ||
|  |     optional_ALIGN_TYPE( char ); | ||
|  |     optional_ALIGN_TYPE( short int ); | ||
|  |     optional_ALIGN_TYPE( int ); | ||
|  |     optional_ALIGN_TYPE( long int  ); | ||
|  |     optional_ALIGN_TYPE( float  ); | ||
|  |     optional_ALIGN_TYPE( double ); | ||
|  |     optional_ALIGN_TYPE( long double ); | ||
|  |     optional_ALIGN_TYPE( char * ); | ||
|  |     optional_ALIGN_TYPE( short int * ); | ||
|  |     optional_ALIGN_TYPE( int *  ); | ||
|  |     optional_ALIGN_TYPE( long int * ); | ||
|  |     optional_ALIGN_TYPE( float * ); | ||
|  |     optional_ALIGN_TYPE( double * ); | ||
|  |     optional_ALIGN_TYPE( long double * ); | ||
|  |     optional_ALIGN_TYPE( void * ); | ||
|  | 
 | ||
|  | #ifdef HAVE_LONG_LONG
 | ||
|  |     optional_ALIGN_TYPE( long long ); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     struct Unknown; | ||
|  | 
 | ||
|  |     Unknown ( * optional_UNIQUE(_) )( Unknown ); | ||
|  |     Unknown * Unknown::* optional_UNIQUE(_); | ||
|  |     Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown ); | ||
|  | 
 | ||
|  |     struct_t< Unknown ( * )( Unknown)         > optional_UNIQUE(_); | ||
|  |     struct_t< Unknown * Unknown::*            > optional_UNIQUE(_); | ||
|  |     struct_t< Unknown ( Unknown::* )(Unknown) > optional_UNIQUE(_); | ||
|  | }; | ||
|  | 
 | ||
|  | #undef optional_UNIQUE
 | ||
|  | #undef optional_UNIQUE2
 | ||
|  | #undef optional_UNIQUE3
 | ||
|  | 
 | ||
|  | #undef optional_ALIGN_TYPE
 | ||
|  | 
 | ||
|  | #elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK
 | ||
|  | 
 | ||
|  | // Use user-specified type for alignment:
 | ||
|  | 
 | ||
|  | #define optional_ALIGN_AS( unused ) \
 | ||
|  |     optional_CONFIG_ALIGN_AS | ||
|  | 
 | ||
|  | #else // optional_CONFIG_MAX_ALIGN_HACK
 | ||
|  | 
 | ||
|  | // Determine POD type to use for alignment:
 | ||
|  | 
 | ||
|  | #define optional_ALIGN_AS( to_align ) \
 | ||
|  |     typename type_of_size< alignment_types, alignment_of< to_align >::value >::type | ||
|  | 
 | ||
|  | template <typename T> | ||
|  | struct alignment_of; | ||
|  | 
 | ||
|  | template <typename T> | ||
|  | struct alignment_of_hack | ||
|  | { | ||
|  |     char c; | ||
|  |     T t; | ||
|  |     alignment_of_hack(); | ||
|  | }; | ||
|  | 
 | ||
|  | template <unsigned A, unsigned S> | ||
|  | struct alignment_logic | ||
|  | { | ||
|  |     enum { value = A < S ? A : S }; | ||
|  | }; | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | struct alignment_of | ||
|  | { | ||
|  |     enum { value = alignment_logic< | ||
|  |         sizeof( alignment_of_hack<T> ) - sizeof(T), sizeof(T) >::value, }; | ||
|  | }; | ||
|  | 
 | ||
|  | template< typename List, size_t N > | ||
|  | struct type_of_size | ||
|  | { | ||
|  |     typedef typename conditional< | ||
|  |         N == sizeof( typename List::head ), | ||
|  |             typename List::head, | ||
|  |             typename type_of_size<typename List::tail, N >::type >::type type; | ||
|  | }; | ||
|  | 
 | ||
|  | template< size_t N > | ||
|  | struct type_of_size< nulltype, N > | ||
|  | { | ||
|  |     typedef optional_CONFIG_ALIGN_AS_FALLBACK type; | ||
|  | }; | ||
|  | 
 | ||
|  | template< typename T> | ||
|  | struct struct_t { T _; }; | ||
|  | 
 | ||
|  | #define optional_ALIGN_TYPE( type ) \
 | ||
|  |     typelist< type , typelist< struct_t< type > | ||
|  | 
 | ||
|  | struct Unknown; | ||
|  | 
 | ||
|  | typedef | ||
|  |     optional_ALIGN_TYPE( char ), | ||
|  |     optional_ALIGN_TYPE( short ), | ||
|  |     optional_ALIGN_TYPE( int ), | ||
|  |     optional_ALIGN_TYPE( long ), | ||
|  |     optional_ALIGN_TYPE( float ), | ||
|  |     optional_ALIGN_TYPE( double ), | ||
|  |     optional_ALIGN_TYPE( long double ), | ||
|  | 
 | ||
|  |     optional_ALIGN_TYPE( char *), | ||
|  |     optional_ALIGN_TYPE( short * ), | ||
|  |     optional_ALIGN_TYPE( int * ), | ||
|  |     optional_ALIGN_TYPE( long * ), | ||
|  |     optional_ALIGN_TYPE( float * ), | ||
|  |     optional_ALIGN_TYPE( double * ), | ||
|  |     optional_ALIGN_TYPE( long double * ), | ||
|  | 
 | ||
|  |     optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ), | ||
|  |     optional_ALIGN_TYPE( Unknown * Unknown::*     ), | ||
|  |     optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ), | ||
|  | 
 | ||
|  |     nulltype | ||
|  |     > > > > > > >    > > > > > > > | ||
|  |     > > > > > > >    > > > > > > > | ||
|  |     > > > > > > | ||
|  |     alignment_types; | ||
|  | 
 | ||
|  | #undef optional_ALIGN_TYPE
 | ||
|  | 
 | ||
|  | #endif // optional_CONFIG_MAX_ALIGN_HACK
 | ||
|  | 
 | ||
|  | /// C++03 constructed union to hold value.
 | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | union storage_t | ||
|  | { | ||
|  | private: | ||
|  |     friend class optional<T>; | ||
|  | 
 | ||
|  |     typedef T value_type; | ||
|  | 
 | ||
|  |     storage_t() {} | ||
|  | 
 | ||
|  |     storage_t( value_type const & v ) | ||
|  |     { | ||
|  |         construct_value( v ); | ||
|  |     } | ||
|  | 
 | ||
|  |     void construct_value( value_type const & v ) | ||
|  |     { | ||
|  |         ::new( value_ptr() ) value_type( v ); | ||
|  |     } | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  | 
 | ||
|  |     storage_t( value_type && v ) | ||
|  |     { | ||
|  |         construct_value( std::move( v ) ); | ||
|  |     } | ||
|  | 
 | ||
|  |     void construct_value( value_type && v ) | ||
|  |     { | ||
|  |         ::new( value_ptr() ) value_type( std::move( v ) ); | ||
|  |     } | ||
|  | 
 | ||
|  |     template< class... Args > | ||
|  |     void emplace( Args&&... args ) | ||
|  |     { | ||
|  |         ::new( value_ptr() ) value_type( std::forward<Args>(args)... ); | ||
|  |     } | ||
|  | 
 | ||
|  |     template< class U, class... Args > | ||
|  |     void emplace( std::initializer_list<U> il, Args&&... args ) | ||
|  |     { | ||
|  |         ::new( value_ptr() ) value_type( il, std::forward<Args>(args)... ); | ||
|  |     } | ||
|  | 
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     void destruct_value() | ||
|  |     { | ||
|  |         value_ptr()->~T(); | ||
|  |     } | ||
|  | 
 | ||
|  |     value_type const * value_ptr() const | ||
|  |     { | ||
|  |         return as<value_type>(); | ||
|  |     } | ||
|  | 
 | ||
|  |     value_type * value_ptr() | ||
|  |     { | ||
|  |         return as<value_type>(); | ||
|  |     } | ||
|  | 
 | ||
|  |     value_type const & value() const optional_ref_qual | ||
|  |     { | ||
|  |         return * value_ptr(); | ||
|  |     } | ||
|  | 
 | ||
|  |     value_type & value() optional_ref_qual | ||
|  |     { | ||
|  |         return * value_ptr(); | ||
|  |     } | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  | 
 | ||
|  |     value_type const && value() const optional_refref_qual | ||
|  |     { | ||
|  |         return * value_ptr(); | ||
|  |     } | ||
|  | 
 | ||
|  |     value_type && value() optional_refref_qual | ||
|  |     { | ||
|  |         return * value_ptr(); | ||
|  |     } | ||
|  | 
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  | 
 | ||
|  |     using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type; | ||
|  |     aligned_storage_t data; | ||
|  | 
 | ||
|  | #elif optional_CONFIG_MAX_ALIGN_HACK
 | ||
|  | 
 | ||
|  |     typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t; | ||
|  | 
 | ||
|  |     max_align_t hack; | ||
|  |     aligned_storage_t data; | ||
|  | 
 | ||
|  | #else
 | ||
|  |     typedef optional_ALIGN_AS(value_type) align_as_type; | ||
|  | 
 | ||
|  |     typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t; | ||
|  |     aligned_storage_t data; | ||
|  | 
 | ||
|  | #   undef optional_ALIGN_AS
 | ||
|  | 
 | ||
|  | #endif // optional_CONFIG_MAX_ALIGN_HACK
 | ||
|  | 
 | ||
|  |     void * ptr() optional_noexcept | ||
|  |     { | ||
|  |         return &data; | ||
|  |     } | ||
|  | 
 | ||
|  |     void const * ptr() const optional_noexcept | ||
|  |     { | ||
|  |         return &data; | ||
|  |     } | ||
|  | 
 | ||
|  |     template <typename U> | ||
|  |     U * as() | ||
|  |     { | ||
|  |         return reinterpret_cast<U*>( ptr() ); | ||
|  |     } | ||
|  | 
 | ||
|  |     template <typename U> | ||
|  |     U const * as() const | ||
|  |     { | ||
|  |         return reinterpret_cast<U const *>( ptr() ); | ||
|  |     } | ||
|  | }; | ||
|  | 
 | ||
|  | } // namespace detail
 | ||
|  | 
 | ||
|  | /// disengaged state tag
 | ||
|  | 
 | ||
|  | struct nullopt_t | ||
|  | { | ||
|  |     struct init{}; | ||
|  |     optional_constexpr nullopt_t( init ) {} | ||
|  | }; | ||
|  | 
 | ||
|  | #if optional_HAVE( CONSTEXPR_11 )
 | ||
|  | constexpr nullopt_t nullopt{ nullopt_t::init{} }; | ||
|  | #else
 | ||
|  | // extra parenthesis to prevent the most vexing parse:
 | ||
|  | const nullopt_t nullopt(( nullopt_t::init() )); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | /// optional access error
 | ||
|  | 
 | ||
|  | class bad_optional_access : public std::logic_error | ||
|  | { | ||
|  | public: | ||
|  |   explicit bad_optional_access() | ||
|  |   : logic_error( "bad optional access" ) {} | ||
|  | }; | ||
|  | 
 | ||
|  | /// optional
 | ||
|  | 
 | ||
|  | template< typename T> | ||
|  | class optional | ||
|  | { | ||
|  | private: | ||
|  |     typedef void (optional::*safe_bool)() const; | ||
|  | 
 | ||
|  | public: | ||
|  |     typedef T value_type; | ||
|  | 
 | ||
|  |     optional_constexpr optional() optional_noexcept | ||
|  |     : has_value_( false ) | ||
|  |     , contained() | ||
|  |     {} | ||
|  | 
 | ||
|  |     optional_constexpr optional( nullopt_t ) optional_noexcept | ||
|  |     : has_value_( false ) | ||
|  |     , contained() | ||
|  |     {} | ||
|  | 
 | ||
|  |     optional( optional const & rhs ) | ||
|  |     : has_value_( rhs.has_value() ) | ||
|  |     { | ||
|  |         if ( rhs.has_value() ) | ||
|  |             contained.construct_value( rhs.contained.value() ); | ||
|  |     } | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  |     optional_constexpr14 optional( optional && rhs ) noexcept( std::is_nothrow_move_constructible<T>::value ) | ||
|  |     : has_value_( rhs.has_value() ) | ||
|  |     { | ||
|  |         if ( rhs.has_value() ) | ||
|  |             contained.construct_value( std::move( rhs.contained.value() ) ); | ||
|  |     } | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     optional_constexpr optional( value_type const & value ) | ||
|  |     : has_value_( true ) | ||
|  |     , contained( value ) | ||
|  |     {} | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  | 
 | ||
|  |     optional_constexpr optional( value_type && value ) | ||
|  |     : has_value_( true ) | ||
|  |     , contained( std::move( value ) ) | ||
|  |     {} | ||
|  | 
 | ||
|  |     template< class... Args > | ||
|  |     optional_constexpr explicit optional( nonstd_lite_in_place_type_t(T), Args&&... args ) | ||
|  |     : has_value_( true ) | ||
|  |     , contained( T( std::forward<Args>(args)...) ) | ||
|  |     {} | ||
|  | 
 | ||
|  |     template< class U, class... Args > | ||
|  |     optional_constexpr explicit optional( nonstd_lite_in_place_type_t(T), std::initializer_list<U> il, Args&&... args ) | ||
|  |     : has_value_( true ) | ||
|  |     , contained( T( il, std::forward<Args>(args)...) ) | ||
|  |     {} | ||
|  | 
 | ||
|  | #endif // optional_CPP11_OR_GREATER
 | ||
|  | 
 | ||
|  |     ~optional() | ||
|  |     { | ||
|  |         if ( has_value() ) | ||
|  |             contained.destruct_value(); | ||
|  |     } | ||
|  | 
 | ||
|  |     // assignment
 | ||
|  | 
 | ||
|  |     optional & operator=( nullopt_t ) optional_noexcept | ||
|  |     { | ||
|  |         reset(); | ||
|  |         return *this; | ||
|  |     } | ||
|  | 
 | ||
|  |     optional & operator=( optional const & rhs ) | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  |         noexcept( std::is_nothrow_move_assignable<T>::value && std::is_nothrow_move_constructible<T>::value ) | ||
|  | #endif
 | ||
|  |     { | ||
|  |         if      ( has_value() == true  && rhs.has_value() == false ) reset(); | ||
|  |         else if ( has_value() == false && rhs.has_value() == true  ) initialize( *rhs ); | ||
|  |         else if ( has_value() == true  && rhs.has_value() == true  ) contained.value() = *rhs; | ||
|  |         return *this; | ||
|  |     } | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  | 
 | ||
|  |     optional & operator=( optional && rhs ) noexcept | ||
|  |     { | ||
|  |         if      ( has_value() == true  && rhs.has_value() == false ) reset(); | ||
|  |         else if ( has_value() == false && rhs.has_value() == true  ) initialize( std::move( *rhs ) ); | ||
|  |         else if ( has_value() == true  && rhs.has_value() == true  ) contained.value() = std::move( *rhs ); | ||
|  |         return *this; | ||
|  |     } | ||
|  | 
 | ||
|  |     template< class U, | ||
|  |         typename = typename std::enable_if< std::is_same< typename std::decay<U>::type, T>::value >::type > | ||
|  |     optional & operator=( U && v ) | ||
|  |     { | ||
|  |         if ( has_value() ) contained.value() = std::forward<U>( v ); | ||
|  |         else               initialize( T( std::forward<U>( v ) ) ); | ||
|  |         return *this; | ||
|  |     } | ||
|  | 
 | ||
|  |     template< class... Args > | ||
|  |     void emplace( Args&&... args ) | ||
|  |     { | ||
|  |         *this = nullopt; | ||
|  |         contained.emplace( std::forward<Args>(args)...  ); | ||
|  |         has_value_ = true; | ||
|  |     } | ||
|  | 
 | ||
|  | 
 | ||
|  |     template< class U, class... Args > | ||
|  |     void emplace( std::initializer_list<U> il, Args&&... args ) | ||
|  |     { | ||
|  |         *this = nullopt; | ||
|  |         contained.emplace( il, std::forward<Args>(args)...  ); | ||
|  |         has_value_ = true; | ||
|  |     } | ||
|  | 
 | ||
|  | #endif // optional_CPP11_OR_GREATER
 | ||
|  | 
 | ||
|  |     // swap
 | ||
|  | 
 | ||
|  |     void swap( optional & rhs ) | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  |     noexcept( std::is_nothrow_move_constructible<T>::value && noexcept( std::swap( std::declval<T&>(), std::declval<T&>() ) ) ) | ||
|  | #endif
 | ||
|  |     { | ||
|  |         using std::swap; | ||
|  |         if      ( has_value() == true  && rhs.has_value() == true  ) { swap( **this, *rhs ); } | ||
|  |         else if ( has_value() == false && rhs.has_value() == true  ) { initialize( *rhs ); rhs.reset(); } | ||
|  |         else if ( has_value() == true  && rhs.has_value() == false ) { rhs.initialize( **this ); reset(); } | ||
|  |     } | ||
|  | 
 | ||
|  |     // observers
 | ||
|  | 
 | ||
|  |     optional_constexpr value_type const * operator ->() const | ||
|  |     { | ||
|  |         return assert( has_value() ), | ||
|  |             contained.value_ptr(); | ||
|  |     } | ||
|  | 
 | ||
|  |     optional_constexpr14 value_type * operator ->() | ||
|  |     { | ||
|  |         return assert( has_value() ), | ||
|  |             contained.value_ptr(); | ||
|  |     } | ||
|  | 
 | ||
|  |     optional_constexpr value_type const & operator *() const optional_ref_qual | ||
|  |     { | ||
|  |         return assert( has_value() ), | ||
|  |             contained.value(); | ||
|  |     } | ||
|  | 
 | ||
|  |     optional_constexpr14 value_type & operator *() optional_ref_qual | ||
|  |     { | ||
|  |         return assert( has_value() ), | ||
|  |             contained.value(); | ||
|  |     } | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  | 
 | ||
|  |     optional_constexpr value_type const && operator *() const optional_refref_qual | ||
|  |     { | ||
|  |         return assert( has_value() ), | ||
|  |             std::move( contained.value() ); | ||
|  |     } | ||
|  | 
 | ||
|  |     optional_constexpr14 value_type && operator *() optional_refref_qual | ||
|  |     { | ||
|  |         return assert( has_value() ), | ||
|  |             std::move( contained.value() ); | ||
|  |     } | ||
|  | 
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  |     optional_constexpr explicit operator bool() const optional_noexcept | ||
|  |     { | ||
|  |         return has_value(); | ||
|  |     } | ||
|  | #else
 | ||
|  |     optional_constexpr operator safe_bool() const optional_noexcept | ||
|  |     { | ||
|  |         return has_value() ? &optional::this_type_does_not_support_comparisons : 0; | ||
|  |     } | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     optional_constexpr bool has_value() const optional_noexcept | ||
|  |     { | ||
|  |         return has_value_; | ||
|  |     } | ||
|  | 
 | ||
|  |     optional_constexpr14 value_type const & value() const optional_ref_qual | ||
|  |     { | ||
|  |         if ( ! has_value() ) | ||
|  |             throw bad_optional_access(); | ||
|  | 
 | ||
|  |         return contained.value(); | ||
|  |     } | ||
|  | 
 | ||
|  |     optional_constexpr14 value_type & value() optional_ref_qual | ||
|  |     { | ||
|  |         if ( ! has_value() ) | ||
|  |             throw bad_optional_access(); | ||
|  | 
 | ||
|  |         return contained.value(); | ||
|  |     } | ||
|  | 
 | ||
|  | #if optional_HAVE( REF_QUALIFIER )
 | ||
|  | 
 | ||
|  |     optional_constexpr14 value_type const && value() const optional_refref_qual | ||
|  |     { | ||
|  |         if ( ! has_value() ) | ||
|  |             throw bad_optional_access(); | ||
|  | 
 | ||
|  |         return std::move( contained.value() ); | ||
|  |     } | ||
|  | 
 | ||
|  |     optional_constexpr14 value_type && value() optional_refref_qual | ||
|  |     { | ||
|  |         if ( ! has_value() ) | ||
|  |             throw bad_optional_access(); | ||
|  | 
 | ||
|  |         return std::move( contained.value() ); | ||
|  |     } | ||
|  | 
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  | 
 | ||
|  |     template< class U > | ||
|  |     optional_constexpr value_type value_or( U && v ) const optional_ref_qual | ||
|  |     { | ||
|  |         return has_value() ? contained.value() : static_cast<T>(std::forward<U>( v ) ); | ||
|  |     } | ||
|  | 
 | ||
|  |     template< class U > | ||
|  |     optional_constexpr value_type value_or( U && v ) const optional_refref_qual | ||
|  |     { | ||
|  |         return has_value() ? std::move( contained.value() ) : static_cast<T>(std::forward<U>( v ) ); | ||
|  |     } | ||
|  | 
 | ||
|  | #else
 | ||
|  | 
 | ||
|  |     template< class U > | ||
|  |     optional_constexpr value_type value_or( U const & v ) const | ||
|  |     { | ||
|  |         return has_value() ? contained.value() : static_cast<value_type>( v ); | ||
|  |     } | ||
|  | 
 | ||
|  | #endif // optional_CPP11_OR_GREATER
 | ||
|  | 
 | ||
|  |     // modifiers
 | ||
|  | 
 | ||
|  |     void reset() optional_noexcept | ||
|  |     { | ||
|  |         if ( has_value() ) | ||
|  |             contained.destruct_value(); | ||
|  | 
 | ||
|  |         has_value_ = false; | ||
|  |     } | ||
|  | 
 | ||
|  | private: | ||
|  |     void this_type_does_not_support_comparisons() const {} | ||
|  | 
 | ||
|  |     template< typename V > | ||
|  |     void initialize( V const & value ) | ||
|  |     { | ||
|  |         assert( ! has_value()  ); | ||
|  |         contained.construct_value( value ); | ||
|  |         has_value_ = true; | ||
|  |     } | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  |     template< typename V > | ||
|  |     void initialize( V && value ) | ||
|  |     { | ||
|  |         assert( ! has_value()  ); | ||
|  |         contained.construct_value( std::move( value ) ); | ||
|  |         has_value_ = true; | ||
|  |     } | ||
|  | 
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | private: | ||
|  |     bool has_value_; | ||
|  |     detail::storage_t< value_type > contained; | ||
|  | 
 | ||
|  | }; | ||
|  | 
 | ||
|  | // Relational operators
 | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator==( optional<T> const & x, optional<U> const & y ) | ||
|  | { | ||
|  |     return bool(x) != bool(y) ? false : !bool( x ) ? true : *x == *y; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator!=( optional<T> const & x, optional<U> const & y ) | ||
|  | { | ||
|  |     return !(x == y); | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator<( optional<T> const & x, optional<U> const & y ) | ||
|  | { | ||
|  |     return (!y) ? false : (!x) ? true : *x < *y; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator>( optional<T> const & x, optional<U> const & y ) | ||
|  | { | ||
|  |     return (y < x); | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator<=( optional<T> const & x, optional<U> const & y ) | ||
|  | { | ||
|  |     return !(y < x); | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator>=( optional<T> const & x, optional<U> const & y ) | ||
|  | { | ||
|  |     return !(x < y); | ||
|  | } | ||
|  | 
 | ||
|  | // Comparison with nullopt
 | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | inline optional_constexpr bool operator==( optional<T> const & x, nullopt_t ) optional_noexcept | ||
|  | { | ||
|  |     return (!x); | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | inline optional_constexpr bool operator==( nullopt_t, optional<T> const & x ) optional_noexcept | ||
|  | { | ||
|  |     return (!x); | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | inline optional_constexpr bool operator!=( optional<T> const & x, nullopt_t ) optional_noexcept | ||
|  | { | ||
|  |     return bool(x); | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | inline optional_constexpr bool operator!=( nullopt_t, optional<T> const & x ) optional_noexcept | ||
|  | { | ||
|  |     return bool(x); | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | inline optional_constexpr bool operator<( optional<T> const &, nullopt_t ) optional_noexcept | ||
|  | { | ||
|  |     return false; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | inline optional_constexpr bool operator<( nullopt_t, optional<T> const & x ) optional_noexcept | ||
|  | { | ||
|  |     return bool(x); | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | inline optional_constexpr bool operator<=( optional<T> const & x, nullopt_t ) optional_noexcept | ||
|  | { | ||
|  |     return (!x); | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | inline optional_constexpr bool operator<=( nullopt_t, optional<T> const & ) optional_noexcept | ||
|  | { | ||
|  |     return true; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | inline optional_constexpr bool operator>( optional<T> const & x, nullopt_t ) optional_noexcept | ||
|  | { | ||
|  |     return bool(x); | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | inline optional_constexpr bool operator>( nullopt_t, optional<T> const & ) optional_noexcept | ||
|  | { | ||
|  |     return false; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | inline optional_constexpr bool operator>=( optional<T> const &, nullopt_t ) optional_noexcept | ||
|  | { | ||
|  |     return true; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | inline optional_constexpr bool operator>=( nullopt_t, optional<T> const & x ) optional_noexcept | ||
|  | { | ||
|  |     return (!x); | ||
|  | } | ||
|  | 
 | ||
|  | // Comparison with T
 | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator==( optional<T> const & x, U const & v ) | ||
|  | { | ||
|  |     return bool(x) ? *x == v : false; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator==( U const & v, optional<T> const & x ) | ||
|  | { | ||
|  |     return bool(x) ? v == *x : false; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator!=( optional<T> const & x, U const & v ) | ||
|  | { | ||
|  |     return bool(x) ? *x != v : true; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator!=( U const & v, optional<T> const & x ) | ||
|  | { | ||
|  |     return bool(x) ? v != *x : true; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator<( optional<T> const & x, U const & v ) | ||
|  | { | ||
|  |     return bool(x) ? *x < v : true; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator<( U const & v, optional<T> const & x ) | ||
|  | { | ||
|  |     return bool(x) ? v < *x : false; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator<=( optional<T> const & x, U const & v ) | ||
|  | { | ||
|  |     return bool(x) ? *x <= v : true; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator<=( U const & v, optional<T> const & x ) | ||
|  | { | ||
|  |     return bool(x) ? v <= *x : false; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator>( optional<T> const & x, U const & v ) | ||
|  | { | ||
|  |     return bool(x) ? *x > v : false; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator>( U const & v, optional<T> const & x ) | ||
|  | { | ||
|  |     return bool(x) ? v > *x : true; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator>=( optional<T> const & x, U const & v ) | ||
|  | { | ||
|  |     return bool(x) ? *x >= v : false; | ||
|  | } | ||
|  | 
 | ||
|  | template< typename T, typename U > | ||
|  | inline optional_constexpr bool operator>=( U const & v, optional<T> const & x ) | ||
|  | { | ||
|  |     return bool(x) ? v >= *x : true; | ||
|  | } | ||
|  | 
 | ||
|  | // Specialized algorithms
 | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | void swap( optional<T> & x, optional<T> & y ) | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  |     noexcept( noexcept( x.swap(y) ) ) | ||
|  | #endif
 | ||
|  | { | ||
|  |     x.swap( y ); | ||
|  | } | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  | 
 | ||
|  | template< class T > | ||
|  | optional_constexpr optional< typename std::decay<T>::type > make_optional( T && v ) | ||
|  | { | ||
|  |     return optional< typename std::decay<T>::type >( std::forward<T>( v ) ); | ||
|  | } | ||
|  | 
 | ||
|  | template< class T, class...Args > | ||
|  | optional_constexpr optional<T> make_optional( Args&&... args ) | ||
|  | { | ||
|  |     return optional<T>( in_place, std::forward<Args>(args)...); | ||
|  | } | ||
|  | 
 | ||
|  | template< class T, class U, class... Args > | ||
|  | optional_constexpr optional<T> make_optional( std::initializer_list<U> il, Args&&... args ) | ||
|  | { | ||
|  |     return optional<T>( in_place, il, std::forward<Args>(args)...); | ||
|  | } | ||
|  | 
 | ||
|  | #else
 | ||
|  | 
 | ||
|  | template< typename T > | ||
|  | optional<T> make_optional( T const & v ) | ||
|  | { | ||
|  |     return optional<T>( v ); | ||
|  | } | ||
|  | 
 | ||
|  | #endif // optional_CPP11_OR_GREATER
 | ||
|  | 
 | ||
|  | } // namespace optional
 | ||
|  | 
 | ||
|  | using namespace optional_lite; | ||
|  | 
 | ||
|  | } // namespace nonstd
 | ||
|  | 
 | ||
|  | #if optional_CPP11_OR_GREATER
 | ||
|  | 
 | ||
|  | // specialize the std::hash algorithm:
 | ||
|  | 
 | ||
|  | namespace std { | ||
|  | 
 | ||
|  | template< class T > | ||
|  | struct hash< nonstd::optional<T> > | ||
|  | { | ||
|  | public: | ||
|  |     std::size_t operator()( nonstd::optional<T> const & v ) const optional_noexcept | ||
|  |     { | ||
|  |         return bool( v ) ? hash<T>()( *v ) : 0; | ||
|  |     } | ||
|  | }; | ||
|  | 
 | ||
|  | } //namespace std
 | ||
|  | 
 | ||
|  | #endif // optional_CPP11_OR_GREATER
 | ||
|  | 
 | ||
|  | #ifdef __clang__
 | ||
|  | # pragma clang diagnostic pop
 | ||
|  | #elif defined __GNUC__
 | ||
|  | # pragma GCC   diagnostic pop
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #endif // have C++17 std::optional
 | ||
|  | 
 | ||
|  | #endif // NONSTD_OPTIONAL_LITE_HPP
 |