Commit b7cf5022b8ff56ea8a0915dd1f56a01f3981fcef

Authored by DarkGod
1 parent 17b989ac

ah compiles better

... ... @@ -50,6 +50,7 @@ project "TEngine"
50 50 if _OPTIONS.relpath == "64" then defines{"TE4_RELPATH64"} end
51 51
52 52 links { "m" }
  53 + links { "stdc++" }
53 54 cppconfig()
54 55
55 56 if _OPTIONS.no_rwops_size then defines{"NO_RWOPS_SIZE"} end
... ...
... ... @@ -71,16 +71,8 @@ configuration "windows"
71 71 }
72 72 end
73 73
74   -function cppconfig(what)
75   - links { "stdc++" }
76   -end
77   -
78   -configuration "macosx"
79   - premake.gcc.cc = 'clang'
80   - premake.gcc.cxx = 'clang++'
81   -
82   - buildoptions { "-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk", "-mmacosx-version-min=10.7" }
83   - function cppconfig(what)
  74 +cppconfig = function(what)
  75 + if os.get() == "macosx" then
84 76 if what == "web" then
85 77 buildoptions { "-stdlib=libstdc++" }
86 78 linkoptions { "-stdlib=libstdc++" }
... ... @@ -88,8 +80,15 @@ configuration "macosx"
88 80 buildoptions { "-stdlib=libc++" }
89 81 linkoptions { "-stdlib=libc++" }
90 82 end
91   - links { "stdc++" }
92 83 end
  84 + -- links { "stdc++" }
  85 +end
  86 +
  87 +configuration "macosx"
  88 + premake.gcc.cc = 'clang'
  89 + premake.gcc.cxx = 'clang++'
  90 +
  91 + buildoptions { "-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk", "-mmacosx-version-min=10.7" }
93 92 includedirs {
94 93 "/Library/Frameworks/SDL2.framework/Headers",
95 94 "/Library/Frameworks/SDL2_image.framework/Headers",
... ...
... ... @@ -93,7 +93,7 @@ static void generate_table_from_output(lua_State *L, WFCOverlapping *config) {
93 93 static bool wfc_generate_overlapping(WFCOverlapping *config) {
94 94 OverlappingWFCOptions options = {config->periodic_in, config->periodic_out, config->output.height, config->output.width, config->symmetry, config->has_foundation, config->n};
95 95 OverlappingWFC<char> wfc(config->sample, options, gen_rand32());
96   - cl::optional<Array2D<char>> success = wfc.run();
  96 + nonstd::optional<Array2D<char>> success = wfc.run();
97 97 if (success.has_value()) {
98 98 config->output.import(success.value());
99 99 return true;
... ...
1   -// Copyright (c) 2016, Charles Lechasseur
2   -// Distributed under the MIT license (see LICENSE).
  1 +//
  2 +// Copyright (c) 2014-2018 Martin Moene
  3 +//
  4 +// https://github.com/martinmoene/optional-lite
  5 +//
  6 +// Distributed under the Boost Software License, Version 1.0.
  7 +// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
3 8
4   -// Implementation of C++17's std::optional
  9 +#pragma once
5 10
6   -#ifndef CL_OPTIONAL_H
7   -#define CL_OPTIONAL_H
  11 +#ifndef NONSTD_OPTIONAL_LITE_HPP
  12 +#define NONSTD_OPTIONAL_LITE_HPP
8 13
9   -#include <functional>
  14 +#define optional_lite_MAJOR 3
  15 +#define optional_lite_MINOR 1
  16 +#define optional_lite_PATCH 1
  17 +
  18 +#define optional_lite_VERSION optional_STRINGIFY(optional_lite_MAJOR) "." optional_STRINGIFY(optional_lite_MINOR) "." optional_STRINGIFY(optional_lite_PATCH)
  19 +
  20 +#define optional_STRINGIFY( x ) optional_STRINGIFY_( x )
  21 +#define optional_STRINGIFY_( x ) #x
  22 +
  23 +// optional-lite configuration:
  24 +
  25 +#define optional_OPTIONAL_DEFAULT 0
  26 +#define optional_OPTIONAL_NONSTD 1
  27 +#define optional_OPTIONAL_STD 2
  28 +
  29 +#if !defined( optional_CONFIG_SELECT_OPTIONAL )
  30 +# define optional_CONFIG_SELECT_OPTIONAL ( optional_HAVE_STD_OPTIONAL ? optional_OPTIONAL_STD : optional_OPTIONAL_NONSTD )
  31 +#endif
  32 +
  33 +// C++ language version detection (C++20 is speculative):
  34 +// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
  35 +
  36 +#ifndef optional_CPLUSPLUS
  37 +# if defined(_MSVC_LANG ) && !defined(__clang__)
  38 +# define optional_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
  39 +# else
  40 +# define optional_CPLUSPLUS __cplusplus
  41 +# endif
  42 +#endif
  43 +
  44 +#define optional_CPP98_OR_GREATER ( optional_CPLUSPLUS >= 199711L )
  45 +#define optional_CPP11_OR_GREATER ( optional_CPLUSPLUS >= 201103L )
  46 +#define optional_CPP11_OR_GREATER_ ( optional_CPLUSPLUS >= 201103L )
  47 +#define optional_CPP14_OR_GREATER ( optional_CPLUSPLUS >= 201402L )
  48 +#define optional_CPP17_OR_GREATER ( optional_CPLUSPLUS >= 201703L )
  49 +#define optional_CPP20_OR_GREATER ( optional_CPLUSPLUS >= 202000L )
  50 +
  51 +// C++ language version (represent 98 as 3):
  52 +
  53 +#define optional_CPLUSPLUS_V ( optional_CPLUSPLUS / 100 - (optional_CPLUSPLUS > 200000 ? 2000 : 1994) )
  54 +
  55 +// Use C++17 std::optional if available and requested:
  56 +
  57 +#if optional_CPP17_OR_GREATER && defined(__has_include )
  58 +# if __has_include( <optional> )
  59 +# define optional_HAVE_STD_OPTIONAL 1
  60 +# else
  61 +# define optional_HAVE_STD_OPTIONAL 0
  62 +# endif
  63 +#else
  64 +# define optional_HAVE_STD_OPTIONAL 0
  65 +#endif
  66 +
  67 +#define optional_USES_STD_OPTIONAL ( (optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_STD) || ((optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_DEFAULT) && optional_HAVE_STD_OPTIONAL) )
  68 +
  69 +//
  70 +// in_place: code duplicated in any-lite, expected-lite, optional-lite, value-ptr-lite, variant-lite:
  71 +//
  72 +
  73 +#ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
  74 +#define nonstd_lite_HAVE_IN_PLACE_TYPES 1
  75 +
  76 +// C++17 std::in_place in <utility>:
  77 +
  78 +#if optional_CPP17_OR_GREATER
  79 +
  80 +#include <utility>
  81 +
  82 +namespace nonstd {
  83 +
  84 +using std::in_place;
  85 +using std::in_place_type;
  86 +using std::in_place_index;
  87 +using std::in_place_t;
  88 +using std::in_place_type_t;
  89 +using std::in_place_index_t;
  90 +
  91 +#define nonstd_lite_in_place_t( T) std::in_place_t
  92 +#define nonstd_lite_in_place_type_t( T) std::in_place_type_t<T>
  93 +#define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
  94 +
  95 +#define nonstd_lite_in_place( T) std::in_place_t{}
  96 +#define nonstd_lite_in_place_type( T) std::in_place_type_t<T>{}
  97 +#define nonstd_lite_in_place_index(K) std::in_place_index_t<K>{}
  98 +
  99 +} // namespace nonstd
  100 +
  101 +#else // optional_CPP17_OR_GREATER
  102 +
  103 +#include <cstddef>
  104 +
  105 +namespace nonstd {
  106 +namespace detail {
  107 +
  108 +template< class T >
  109 +struct in_place_type_tag {};
  110 +
  111 +template< std::size_t K >
  112 +struct in_place_index_tag {};
  113 +
  114 +} // namespace detail
  115 +
  116 +struct in_place_t {};
  117 +
  118 +template< class T >
  119 +inline in_place_t in_place( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
  120 +{
  121 + return in_place_t();
  122 +}
  123 +
  124 +template< std::size_t K >
  125 +inline in_place_t in_place( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
  126 +{
  127 + return in_place_t();
  128 +}
  129 +
  130 +template< class T >
  131 +inline in_place_t in_place_type( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
  132 +{
  133 + return in_place_t();
  134 +}
  135 +
  136 +template< std::size_t K >
  137 +inline in_place_t in_place_index( detail::in_place_index_tag<K> = detail::in_place_index_tag<K>() )
  138 +{
  139 + return in_place_t();
  140 +}
  141 +
  142 +// mimic templated typedef:
  143 +
  144 +#define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
  145 +#define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
  146 +#define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> )
  147 +
  148 +#define nonstd_lite_in_place( T) nonstd::in_place_type<T>
  149 +#define nonstd_lite_in_place_type( T) nonstd::in_place_type<T>
  150 +#define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
  151 +
  152 +} // namespace nonstd
  153 +
  154 +#endif // optional_CPP17_OR_GREATER
  155 +#endif // nonstd_lite_HAVE_IN_PLACE_TYPES
  156 +
  157 +//
  158 +// Using std::optional:
  159 +//
  160 +
  161 +#if optional_USES_STD_OPTIONAL
  162 +
  163 +#include <optional>
  164 +
  165 +namespace nonstd {
  166 +
  167 + using std::optional;
  168 + using std::bad_optional_access;
  169 + using std::hash;
  170 +
  171 + using std::nullopt;
  172 + using std::nullopt_t;
  173 +
  174 + using std::operator==;
  175 + using std::operator!=;
  176 + using std::operator<;
  177 + using std::operator<=;
  178 + using std::operator>;
  179 + using std::operator>=;
  180 + using std::make_optional;
  181 + using std::swap;
  182 +}
  183 +
  184 +#else // optional_USES_STD_OPTIONAL
  185 +
  186 +#include <cassert>
10 187 #include <stdexcept>
11   -#include <string>
12   -#include <type_traits>
13 188 #include <utility>
14 189
  190 +// optional-lite alignment configuration:
  191 +
  192 +#ifndef optional_CONFIG_MAX_ALIGN_HACK
  193 +# define optional_CONFIG_MAX_ALIGN_HACK 0
  194 +#endif
  195 +
  196 +#ifndef optional_CONFIG_ALIGN_AS
  197 +// no default, used in #if defined()
  198 +#endif
  199 +
  200 +#ifndef optional_CONFIG_ALIGN_AS_FALLBACK
  201 +# define optional_CONFIG_ALIGN_AS_FALLBACK double
  202 +#endif
  203 +
  204 +// Compiler warning suppression:
  205 +
  206 +#if defined(__clang__)
  207 +# pragma clang diagnostic push
  208 +# pragma clang diagnostic ignored "-Wundef"
  209 +#elif defined(__GNUC__)
  210 +# pragma GCC diagnostic push
  211 +# pragma GCC diagnostic ignored "-Wundef"
  212 +#endif
  213 +
  214 +// half-open range [lo..hi):
  215 +#define optional_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
  216 +
  217 +// Compiler versions:
  218 +//
  219 +// MSVC++ 6.0 _MSC_VER == 1200 (Visual Studio 6.0)
  220 +// MSVC++ 7.0 _MSC_VER == 1300 (Visual Studio .NET 2002)
  221 +// MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio .NET 2003)
  222 +// MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
  223 +// MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
  224 +// MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
  225 +// MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
  226 +// MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
  227 +// MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
  228 +// MSVC++ 14.1 _MSC_VER >= 1910 (Visual Studio 2017)
  229 +
  230 +#if defined(_MSC_VER ) && !defined(__clang__)
  231 +# define optional_COMPILER_MSVC_VER (_MSC_VER )
  232 +# define optional_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
  233 +#else
  234 +# define optional_COMPILER_MSVC_VER 0
  235 +# define optional_COMPILER_MSVC_VERSION 0
  236 +#endif
  237 +
  238 +#define optional_COMPILER_VERSION( major, minor, patch ) ( 10 * (10 * major + minor ) + patch )
15 239
16   -// Compiler detection
17   -#if defined(_MSC_VER)
18   -# if _MSC_VER >= 1800 // Visual Studio 2013
19   -# define CL_OPTIONAL_VARIADIC
20   -# define CL_OPTIONAL_EXPLICIT_OP_BOOL
21   -# define CL_OPTIONAL_TEMPLATE_FUNCS_DEFAULT_PARAMS
22   -# endif
23   -# if _MSC_VER >= 1900 // Visual Studio 2015
24   -# define CL_OPTIONAL_NORETURN
25   -# define CL_OPTIONAL_MEMBERS_REF_QUALIFIERS
26   -# endif
27   -# if _MSC_VER >= 1910 // Visual Studio 2017
28   -# define CL_OPTIONAL_NOEXCEPT // Note: in theory this is supported in VC14, but a bug in VC14 update 3 can cause compiler errors
29   -# define CL_OPTIONAL_CONSTEXPR
30   -# endif
31   -#elif defined(__clang__)
32   -# if __has_feature(cxx_noexcept)
33   -# define CL_OPTIONAL_NOEXCEPT
34   -# endif
35   -# if __has_feature(cxx_constexpr) && __cplusplus >= 201402L
36   -# define CL_OPTIONAL_CONSTEXPR
37   -# endif
38   -# if __has_feature(cxx_attributes)
39   -# define CL_OPTIONAL_NORETURN
40   -# endif
41   -# if __has_feature(cxx_variadic_templates)
42   -# define CL_OPTIONAL_VARIADIC
43   -# endif
44   -# if __has_feature(cxx_reference_qualified_functions) && __cplusplus >= 201402L
45   -# define CL_OPTIONAL_MEMBERS_REF_QUALIFIERS
46   -# endif
47   -# if __has_feature(cxx_explicit_conversions)
48   -# define CL_OPTIONAL_EXPLICIT_OP_BOOL
49   -# endif
50   -# if __has_feature(cxx_default_function_template_args)
51   -# define CL_OPTIONAL_TEMPLATE_FUNCS_DEFAULT_PARAMS
52   -# endif
53   -#elif defined(__GNUG__)
54   -# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
55   -# define CL_OPTIONAL_NOEXCEPT
56   -# define CL_OPTIONAL_NORETURN
57   -# define CL_OPTIONAL_VARIADIC
58   -# define CL_OPTIONAL_MEMBERS_REF_QUALIFIERS
59   -# define CL_OPTIONAL_EXPLICIT_OP_BOOL
60   -# define CL_OPTIONAL_TEMPLATE_FUNCS_DEFAULT_PARAMS
61   -# endif
62   -# if __GNUC__ >= 5
63   -# define CL_OPTIONAL_CONSTEXPR
64   -# endif
65   -#endif
66   -
67   -
68   -// Define CL_OPTIONAL_NOEXCEPT to get noexcept specifications
69   -#ifdef CL_OPTIONAL_NOEXCEPT
70   -# define _CL_OPT_NOEXCEPT noexcept
71   -# define _CL_OPT_NOEXCEPTEX(...) noexcept(__VA_ARGS__)
  240 +#if defined(__GNUC__) && !defined(__clang__)
  241 +# define optional_COMPILER_GNUC_VERSION optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
72 242 #else
73   -# define _CL_OPT_NOEXCEPT
74   -# define _CL_OPT_NOEXCEPTEX(...)
  243 +# define optional_COMPILER_GNUC_VERSION 0
75 244 #endif
76 245
77   -// Define CL_OPTIONAL_CONSTEXPR to get constexpr specifications
78   -#ifdef CL_OPTIONAL_CONSTEXPR
79   -# define _CL_OPT_CONSTEXPR constexpr
80   -# define _CL_OPT_CONSTEXPR_OR_CONST constexpr
  246 +#if defined(__clang__)
  247 +# define optional_COMPILER_CLANG_VERSION optional_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
81 248 #else
82   -# define _CL_OPT_CONSTEXPR
83   -# define _CL_OPT_CONSTEXPR_OR_CONST const
  249 +# define optional_COMPILER_CLANG_VERSION 0
  250 +#endif
  251 +
  252 +#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 140 )
  253 +# pragma warning( push )
  254 +# pragma warning( disable: 4345 ) // initialization behavior changed
  255 +#endif
  256 +
  257 +#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 150 )
  258 +# pragma warning( push )
  259 +# pragma warning( disable: 4814 ) // in C++14 'constexpr' will not imply 'const'
84 260 #endif
85 261
86   -// Define CL_OPTIONAL_VARIADIC to get variadic templates
87   -#ifdef CL_OPTIONAL_VARIADIC
88   -# define _CL_OPT_VARIADIC 1
  262 +// Presence of language and library features:
  263 +
  264 +#define optional_HAVE(FEATURE) ( optional_HAVE_##FEATURE )
  265 +
  266 +#ifdef _HAS_CPP0X
  267 +# define optional_HAS_CPP0X _HAS_CPP0X
  268 +#else
  269 +# define optional_HAS_CPP0X 0
  270 +#endif
  271 +
  272 +// Unless defined otherwise below, consider VC14 as C++11 for optional-lite:
  273 +
  274 +#if optional_COMPILER_MSVC_VER >= 1900
  275 +# undef optional_CPP11_OR_GREATER
  276 +# define optional_CPP11_OR_GREATER 1
  277 +#endif
  278 +
  279 +#define optional_CPP11_90 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1500)
  280 +#define optional_CPP11_100 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1600)
  281 +#define optional_CPP11_110 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1700)
  282 +#define optional_CPP11_120 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1800)
  283 +#define optional_CPP11_140 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1900)
  284 +#define optional_CPP11_141 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1910)
  285 +
  286 +#define optional_CPP14_000 (optional_CPP14_OR_GREATER)
  287 +#define optional_CPP17_000 (optional_CPP17_OR_GREATER)
  288 +
  289 +// Presence of C++11 language features:
  290 +
  291 +#define optional_HAVE_CONSTEXPR_11 optional_CPP11_140
  292 +#define optional_HAVE_NOEXCEPT optional_CPP11_140
  293 +#define optional_HAVE_NULLPTR optional_CPP11_100
  294 +#define optional_HAVE_REF_QUALIFIER optional_CPP11_140
  295 +
  296 +// Presence of C++14 language features:
  297 +
  298 +#define optional_HAVE_CONSTEXPR_14 optional_CPP14_000
  299 +
  300 +// Presence of C++17 language features:
  301 +
  302 +// no flag
  303 +
  304 +// Presence of C++ library features:
  305 +
  306 +#define optional_HAVE_CONDITIONAL optional_CPP11_120
  307 +#define optional_HAVE_REMOVE_CV optional_CPP11_120
  308 +#define optional_HAVE_TYPE_TRAITS optional_CPP11_90
  309 +
  310 +#define optional_HAVE_TR1_TYPE_TRAITS (!! optional_COMPILER_GNUC_VERSION )
  311 +#define optional_HAVE_TR1_ADD_POINTER (!! optional_COMPILER_GNUC_VERSION )
  312 +
  313 +// C++ feature usage:
  314 +
  315 +#if optional_HAVE( CONSTEXPR_11 )
  316 +# define optional_constexpr constexpr
89 317 #else
90   -# define _CL_OPT_VARIADIC 0
  318 +# define optional_constexpr /*constexpr*/
91 319 #endif
92 320
93   -// Define CL_OPTIONAL_NORETURN to get noreturn specifications
94   -#ifdef CL_OPTIONAL_NORETURN
95   -# define _CL_OPT_NORETURN [[noreturn]]
  321 +#if optional_HAVE( CONSTEXPR_14 )
  322 +# define optional_constexpr14 constexpr
96 323 #else
97   -# define _CL_OPT_NORETURN
  324 +# define optional_constexpr14 /*constexpr*/
98 325 #endif
99 326
100   -// Define CL_OPTIONAL_MEMBERS_REF_QUALIFIERS to get lvalue- and rvalue-qualified members
101   -#ifdef CL_OPTIONAL_MEMBERS_REF_QUALIFIERS
102   -# define _CL_OPT_MEMBERS_REF_QUALIFIERS 1
103   -# define _CL_OPT_LVALUE_REF_QUALIF &
  327 +#if optional_HAVE( NOEXCEPT )
  328 +# define optional_noexcept noexcept
104 329 #else
105   -# define _CL_OPT_MEMBERS_REF_QUALIFIERS 0
106   -# define _CL_OPT_LVALUE_REF_QUALIF
  330 +# define optional_noexcept /*noexcept*/
107 331 #endif
108 332
109   -// Define CL_OPTIONAL_EXPLICIT_OP_BOOL to get explicit operator bool()
110   -#ifdef CL_OPTIONAL_EXPLICIT_OP_BOOL
111   -# define _CL_OPT_OP_EXPLICIT explicit
  333 +#if optional_HAVE( NULLPTR )
  334 +# define optional_nullptr nullptr
112 335 #else
113   -# define _CL_OPT_OP_EXPLICIT
  336 +# define optional_nullptr NULL
114 337 #endif
115 338
116   -// Define CL_OPTIONAL_TEMPLATE_FUNCS_DEFAULT_PARAMS to get template methods
117   -// with default template params, like assignment operator from value
118   -#ifdef CL_OPTIONAL_TEMPLATE_FUNCS_DEFAULT_PARAMS
119   -# define _CL_OPT_TEMPL_FUNC_DEF_PARAMS 1
  339 +#if optional_HAVE( REF_QUALIFIER )
  340 +# define optional_ref_qual &
  341 +# define optional_refref_qual &&
120 342 #else
121   -# define _CL_OPT_TEMPL_FUNC_DEF_PARAMS 0
  343 +# define optional_ref_qual /*&*/
  344 +# define optional_refref_qual /*&&*/
  345 +#endif
  346 +
  347 +// additional includes:
  348 +
  349 +#if optional_CPP11_OR_GREATER
  350 +# include <functional>
  351 +#endif
  352 +
  353 +#if optional_HAVE( INITIALIZER_LIST )
  354 +# include <initializer_list>
122 355 #endif
123 356
  357 +#if optional_HAVE( TYPE_TRAITS )
  358 +# include <type_traits>
  359 +#elif optional_HAVE( TR1_TYPE_TRAITS )
  360 +# include <tr1/type_traits>
  361 +#endif
  362 +
  363 +// Method enabling
  364 +
  365 +#if optional_CPP11_OR_GREATER
  366 +
  367 +# define optional_REQUIRES_T(...) \
  368 + , typename = typename std::enable_if<__VA_ARGS__>::type
  369 +
  370 +# define optional_REQUIRES_R(R, ...) \
  371 + typename std::enable_if<__VA_ARGS__, R>::type
  372 +
  373 +# define optional_REQUIRES_A(...) \
  374 + , typename std::enable_if<__VA_ARGS__, void*>::type = optional_nullptr
124 375
125   -#if _CL_OPT_VARIADIC
126   -# include <initializer_list>
127 376 #endif
128 377
129   -namespace cl {
  378 +//
  379 +// optional:
  380 +//
  381 +
  382 +namespace nonstd { namespace optional_lite {
  383 +
  384 +namespace detail {
130 385
131   -// Type indicating an optional object with no value. See:
132   -// http://en.cppreference.com/w/cpp/utility/optional/nullopt_t
133   -struct nullopt_t {
134   - _CL_OPT_CONSTEXPR nullopt_t(int) { }
  386 +#if optional_HAVE( CONDITIONAL )
  387 + using std::conditional;
  388 +#else
  389 + template< bool B, typename T, typename F > struct conditional { typedef T type; };
  390 + template< typename T, typename F > struct conditional<false, T, F> { typedef F type; };
  391 +#endif // optional_HAVE_CONDITIONAL
  392 +
  393 +} // namespace detail
  394 +
  395 +#if optional_CPP11_OR_GREATER
  396 +
  397 +namespace std20 {
  398 +
  399 +// type traits C++20:
  400 +
  401 +template< typename T >
  402 +struct remove_cvref
  403 +{
  404 + typedef typename std::remove_cv< typename std::remove_reference<T>::type >::type type;
135 405 };
136 406
137   -// Instance of nullopt_t passed to optional's members. See:
138   -// http://en.cppreference.com/w/cpp/utility/optional/nullopt
139   -_CL_OPT_CONSTEXPR_OR_CONST nullopt_t nullopt = 0;
  407 +} // namespace std20
140 408
141   -#if _CL_OPT_VARIADIC
142   -// Empty type used for in_place functions. See:
143   -// http://en.cppreference.com/w/cpp/utility/in_place_tag
144   -struct in_place_tag {
145   - in_place_tag() = delete;
146   -private:
147   - in_place_tag(int) { }
148   - friend in_place_tag in_place();
  409 +#endif // optional_CPP11_OR_GREATER
  410 +
  411 +/// class optional
  412 +
  413 +template< typename T >
  414 +class optional;
  415 +
  416 +namespace detail {
  417 +
  418 +// C++11 emulation:
  419 +
  420 +struct nulltype{};
  421 +
  422 +template< typename Head, typename Tail >
  423 +struct typelist
  424 +{
  425 + typedef Head head;
  426 + typedef Tail tail;
149 427 };
150 428
151   -// Function to identify an optional method with in-place construction. See:
152   -// http://en.cppreference.com/w/cpp/utility/in_place
153   -inline in_place_tag in_place() { return in_place_tag(0); }
154   -using in_place_t = in_place_tag (&)();
155   -#endif // _CL_OPT_VARIADIC
  429 +#if optional_CONFIG_MAX_ALIGN_HACK
156 430
157   -// Exception thrown by optional when trying to access
158   -// an optional with no value. See:
159   -// http://en.cppreference.com/w/cpp/utility/optional/bad_optional_access
160   -class bad_optional_access : public std::logic_error
  431 +// Max align, use most restricted type for alignment:
  432 +
  433 +#define optional_UNIQUE( name ) optional_UNIQUE2( name, __LINE__ )
  434 +#define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line )
  435 +#define optional_UNIQUE3( name, line ) name ## line
  436 +
  437 +#define optional_ALIGN_TYPE( type ) \
  438 + type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st )
  439 +
  440 +template< typename T >
  441 +struct struct_t { T _; };
  442 +
  443 +union max_align_t
161 444 {
162   -public:
163   - bad_optional_access(const std::string& what_arg)
164   - : std::logic_error(what_arg) { }
165   - bad_optional_access(const char* what_arg)
166   - : std::logic_error(what_arg) { }
  445 + optional_ALIGN_TYPE( char );
  446 + optional_ALIGN_TYPE( short int );
  447 + optional_ALIGN_TYPE( int );
  448 + optional_ALIGN_TYPE( long int );
  449 + optional_ALIGN_TYPE( float );
  450 + optional_ALIGN_TYPE( double );
  451 + optional_ALIGN_TYPE( long double );
  452 + optional_ALIGN_TYPE( char * );
  453 + optional_ALIGN_TYPE( short int * );
  454 + optional_ALIGN_TYPE( int * );
  455 + optional_ALIGN_TYPE( long int * );
  456 + optional_ALIGN_TYPE( float * );
  457 + optional_ALIGN_TYPE( double * );
  458 + optional_ALIGN_TYPE( long double * );
  459 + optional_ALIGN_TYPE( void * );
  460 +
  461 +#ifdef HAVE_LONG_LONG
  462 + optional_ALIGN_TYPE( long long );
  463 +#endif
  464 +
  465 + struct Unknown;
  466 +
  467 + Unknown ( * optional_UNIQUE(_) )( Unknown );
  468 + Unknown * Unknown::* optional_UNIQUE(_);
  469 + Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown );
  470 +
  471 + struct_t< Unknown ( * )( Unknown) > optional_UNIQUE(_);
  472 + struct_t< Unknown * Unknown::* > optional_UNIQUE(_);
  473 + struct_t< Unknown ( Unknown::* )(Unknown) > optional_UNIQUE(_);
167 474 };
168 475
169   -// Wrapper for an optional value. Part of future C++17 API. See:
170   -// http://en.cppreference.com/w/cpp/utility/optional
171   -template<typename T>
172   -class optional
  476 +#undef optional_UNIQUE
  477 +#undef optional_UNIQUE2
  478 +#undef optional_UNIQUE3
  479 +
  480 +#undef optional_ALIGN_TYPE
  481 +
  482 +#elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK
  483 +
  484 +// Use user-specified type for alignment:
  485 +
  486 +#define optional_ALIGN_AS( unused ) \
  487 + optional_CONFIG_ALIGN_AS
  488 +
  489 +#else // optional_CONFIG_MAX_ALIGN_HACK
  490 +
  491 +// Determine POD type to use for alignment:
  492 +
  493 +#define optional_ALIGN_AS( to_align ) \
  494 + typename type_of_size< alignment_types, alignment_of< to_align >::value >::type
  495 +
  496 +template< typename T >
  497 +struct alignment_of;
  498 +
  499 +template< typename T >
  500 +struct alignment_of_hack
  501 +{
  502 + char c;
  503 + T t;
  504 + alignment_of_hack();
  505 +};
  506 +
  507 +template< size_t A, size_t S >
  508 +struct alignment_logic
173 509 {
174   - static_assert(!std::is_reference<T>::value, "cl::optional does not work with reference types");
175   - static_assert(std::is_destructible<T>::value, "cl::optional requires type to be Destructible");
  510 + enum { value = A < S ? A : S };
  511 +};
176 512
177   -private:
178   - typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type stg_; // We store any value here.
179   - T* const pval_; // Pointer to value stored in stg_.
180   - bool has_value_; // Whether we have a value in stg_.
  513 +template< typename T >
  514 +struct alignment_of
  515 +{
  516 + enum { value = alignment_logic<
  517 + sizeof( alignment_of_hack<T> ) - sizeof(T), sizeof(T) >::value };
  518 +};
  519 +
  520 +template< typename List, size_t N >
  521 +struct type_of_size
  522 +{
  523 + typedef typename conditional<
  524 + N == sizeof( typename List::head ),
  525 + typename List::head,
  526 + typename type_of_size<typename List::tail, N >::type >::type type;
  527 +};
  528 +
  529 +template< size_t N >
  530 +struct type_of_size< nulltype, N >
  531 +{
  532 + typedef optional_CONFIG_ALIGN_AS_FALLBACK type;
  533 +};
  534 +
  535 +template< typename T>
  536 +struct struct_t { T _; };
  537 +
  538 +#define optional_ALIGN_TYPE( type ) \
  539 + typelist< type , typelist< struct_t< type >
  540 +
  541 +struct Unknown;
181 542
182   - // Exception helpers
183   - _CL_OPT_NORETURN void throw_bad_optional_access() const {
184   - throw bad_optional_access("bad_optional_access");
  543 +typedef
  544 + optional_ALIGN_TYPE( char ),
  545 + optional_ALIGN_TYPE( short ),
  546 + optional_ALIGN_TYPE( int ),
  547 + optional_ALIGN_TYPE( long ),
  548 + optional_ALIGN_TYPE( float ),
  549 + optional_ALIGN_TYPE( double ),
  550 + optional_ALIGN_TYPE( long double ),
  551 +
  552 + optional_ALIGN_TYPE( char *),
  553 + optional_ALIGN_TYPE( short * ),
  554 + optional_ALIGN_TYPE( int * ),
  555 + optional_ALIGN_TYPE( long * ),
  556 + optional_ALIGN_TYPE( float * ),
  557 + optional_ALIGN_TYPE( double * ),
  558 + optional_ALIGN_TYPE( long double * ),
  559 +
  560 + optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ),
  561 + optional_ALIGN_TYPE( Unknown * Unknown::* ),
  562 + optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ),
  563 +
  564 + nulltype
  565 + > > > > > > > > > > > > > >
  566 + > > > > > > > > > > > > > >
  567 + > > > > > >
  568 + alignment_types;
  569 +
  570 +#undef optional_ALIGN_TYPE
  571 +
  572 +#endif // optional_CONFIG_MAX_ALIGN_HACK
  573 +
  574 +/// C++03 constructed union to hold value.
  575 +
  576 +template< typename T >
  577 +union storage_t
  578 +{
  579 +//private:
  580 +// template< typename > friend class optional;
  581 +
  582 + typedef T value_type;
  583 +
  584 + storage_t() {}
  585 +
  586 + storage_t( value_type const & v )
  587 + {
  588 + construct_value( v );
185 589 }
186 590
187   - // Helper for swap when one has a value and the other does not
188   - static void swap_helper(optional& from, optional& to) _CL_OPT_NOEXCEPTEX(std::is_nothrow_move_constructible<T>::value &&
189   - std::is_nothrow_destructible<T>::value)
  591 + void construct_value( value_type const & v )
190 592 {
191   - new (to.pval_) T(std::move(*from.pval_));
192   - from.pval_->~T();
193   - to.has_value_ = true;
194   - from.has_value_ = false;
  593 + ::new( value_ptr() ) value_type( v );
195 594 }
196 595
197   -public:
198   - typedef T value_type;
  596 +#if optional_CPP11_OR_GREATER
199 597
200   - // Constructors of optional without a value
201   - _CL_OPT_CONSTEXPR optional() _CL_OPT_NOEXCEPT
202   - : stg_(), pval_(reinterpret_cast<T*>(&stg_)), has_value_(false) { }
203   - _CL_OPT_CONSTEXPR optional(nullopt_t) _CL_OPT_NOEXCEPT
204   - : stg_(), pval_(reinterpret_cast<T*>(&stg_)), has_value_(false) { }
  598 + storage_t( value_type && v )
  599 + {
  600 + construct_value( std::move( v ) );
  601 + }
205 602
206   - // Copy constructor
207   - optional(const optional& obj) _CL_OPT_NOEXCEPTEX(std::is_nothrow_copy_constructible<T>::value)
208   - : stg_(), pval_(reinterpret_cast<T*>(&stg_)), has_value_(obj.has_value_)
  603 + void construct_value( value_type && v )
209 604 {
210   - if (has_value_) {
211   - new (pval_) T(*obj.pval_);
212   - }
  605 + ::new( value_ptr() ) value_type( std::move( v ) );
213 606 }
214 607
215   - // Move constructor (note: does not steal has_value_, see API)
216   - optional(optional&& obj) _CL_OPT_NOEXCEPTEX(std::is_nothrow_move_constructible<T>::value)
217   - : stg_(), pval_(reinterpret_cast<T*>(&stg_)), has_value_(obj.has_value_)
  608 + template< class... Args >
  609 + void emplace( Args&&... args )
218 610 {
219   - if (has_value_) {
220   - new (pval_) T(std::move(*obj.pval_));
221   - }
  611 + ::new( value_ptr() ) value_type( std::forward<Args>(args)... );
222 612 }
223 613
224   - // Constructors of optional with a value
225   - optional(const T& val) _CL_OPT_NOEXCEPTEX(std::is_nothrow_copy_constructible<T>::value)
226   - : stg_(), pval_(reinterpret_cast<T*>(&stg_)), has_value_(true)
  614 + template< class U, class... Args >
  615 + void emplace( std::initializer_list<U> il, Args&&... args )
227 616 {
228   - new (pval_) T(val);
  617 + ::new( value_ptr() ) value_type( il, std::forward<Args>(args)... );
229 618 }
230   - optional(T&& val) _CL_OPT_NOEXCEPTEX(std::is_nothrow_move_constructible<T>::value)
231   - : stg_(), pval_(reinterpret_cast<T*>(&stg_)), has_value_(true)
  619 +
  620 +#endif
  621 +
  622 + void destruct_value()
232 623 {
233   - new (pval_) T(std::move(val));
  624 + value_ptr()->~T();
234 625 }
235 626
236   -#if _CL_OPT_VARIADIC
237   - // In-place constructor of optional with a value
238   - template<typename... Args>
239   - _CL_OPT_CONSTEXPR explicit optional(in_place_t, Args&&... args)
240   - _CL_OPT_NOEXCEPTEX(std::is_nothrow_constructible<T, Args&&...>::value)
241   - : stg_(), pval_(reinterpret_cast<T*>(&stg_)), has_value_(true)
  627 + value_type const * value_ptr() const
242 628 {
243   - new (pval_) T(std::forward<Args>(args)...);
  629 + return as<value_type>();
244 630 }
245 631
246   - // Same but with an initializer_list thrown in just for fun
247   - template<typename U, typename... Args,
248   - typename = typename std::enable_if<std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value, void>::type>
249   - _CL_OPT_CONSTEXPR explicit optional(in_place_t,
250   - std::initializer_list<U> ilist,
251   - Args&&... args)
252   - _CL_OPT_NOEXCEPTEX(std::is_nothrow_constructible<T, std::initializer_list<U>&, Args&&...>::value)
253   - : stg_(), pval_(reinterpret_cast<T*>(&stg_)), has_value_(true)
  632 + value_type * value_ptr()
254 633 {
255   - new (pval_) T(ilist, std::forward<Args>(args)...);
  634 + return as<value_type>();
256 635 }
257   -#endif // _CL_OPT_VARIADIC
258 636
259   - // Destructor
260   - ~optional() _CL_OPT_NOEXCEPTEX(std::is_nothrow_destructible<T>::value) {
261   - if (has_value_) {
262   - // #clp TODO we should not do this for trivially-destructible types as per API
263   - pval_->~T();
264   - }
  637 + value_type const & value() const optional_ref_qual
  638 + {
  639 + return * value_ptr();
265 640 }
266 641
267   - // Assignment operator that clears any held value
268   - optional& operator=(nullopt_t) _CL_OPT_NOEXCEPTEX(std::is_nothrow_destructible<T>::value)
  642 + value_type & value() optional_ref_qual
269 643 {
270   - if (has_value_) {
271   - pval_->~T();
272   - has_value_ = false;
273   - }
274   - return *this;
  644 + return * value_ptr();
275 645 }
276 646
277   - // Copy assignment operator
278   - optional& operator=(const optional& obj) _CL_OPT_NOEXCEPTEX(std::is_nothrow_copy_constructible<T>::value &&
279   - std::is_nothrow_copy_assignable<T>::value &&
280   - std::is_nothrow_destructible<T>::value)
281   - {
282   - if (obj.has_value_) {
283   - if (has_value_) {
284   - // Can assign
285   - *pval_ = *obj.pval_;
286   - } else {
287   - // Need to construct
288   - new (pval_) T(*obj.pval_);
289   - has_value_ = true;
290   - }
291   - } else if (has_value_) {
292   - pval_->~T();
293   - has_value_ = false;
294   - }
295   - return *this;
  647 +#if optional_CPP11_OR_GREATER
  648 +
  649 + value_type const && value() const optional_refref_qual
  650 + {
  651 + return std::move( value() );
296 652 }
297 653
298   - // Move assignment (note: does not steal has_value_, see API)
299   - optional& operator=(optional&& obj) _CL_OPT_NOEXCEPTEX(std::is_nothrow_move_constructible<T>::value &&
300   - std::is_nothrow_move_assignable<T>::value &&
301   - std::is_nothrow_destructible<T>::value)
302   - {
303   - if (obj.has_value_) {
304   - if (has_value_) {
305   - // Can assign
306   - *pval_ = std::move(*obj.pval_);
307   - } else {
308   - // Need to construct
309   - new (pval_) T(std::move(*obj.pval_));
310   - has_value_ = true;
311   - }
312   - } else if (has_value_) {
313   - pval_->~T();
314   - has_value_ = false;
315   - }
316   - return *this;
  654 + value_type && value() optional_refref_qual
  655 + {
  656 + return std::move( value() );
317 657 }
318 658
319   -#if _CL_OPT_TEMPL_FUNC_DEF_PARAMS
320   - // Assignment from a value
321   - template<typename U,
322   - typename = typename std::enable_if<std::is_same<typename std::decay<U>::type, T>::value, void>::type>
323   - optional& operator=(U&& val)
324   - _CL_OPT_NOEXCEPTEX(std::is_nothrow_constructible<T, U>::value &&
325   - std::is_nothrow_assignable<T, U>::value)
326   - {
327   - if (has_value_) {
328   - // Can assign
329   - *pval_ = std::forward<U>(val);
330   - } else {
331   - // Need to construct
332   - new (pval_) T(std::forward<U>(val));
333   - has_value_ = true;
334   - }
335   - return *this;
  659 +#endif
  660 +
  661 +#if optional_CPP11_OR_GREATER
  662 +
  663 + using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type;
  664 + aligned_storage_t data;
  665 +
  666 +#elif optional_CONFIG_MAX_ALIGN_HACK
  667 +
  668 + typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t;
  669 +
  670 + max_align_t hack;
  671 + aligned_storage_t data;
  672 +
  673 +#else
  674 + typedef optional_ALIGN_AS(value_type) align_as_type;
  675 +
  676 + typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t;
  677 + aligned_storage_t data;
  678 +
  679 +# undef optional_ALIGN_AS
  680 +
  681 +#endif // optional_CONFIG_MAX_ALIGN_HACK
  682 +
  683 + void * ptr() optional_noexcept
  684 + {
  685 + return &data;
336 686 }
337   -#endif // _CL_OPT_TEMPL_FUNC_DEF_PARAMS
338 687
339   - // Unchecked operators that access the value
340   - _CL_OPT_CONSTEXPR const T* operator->() const {
341   - return pval_;
  688 + void const * ptr() const optional_noexcept
  689 + {
  690 + return &data;
342 691 }
343   - _CL_OPT_CONSTEXPR T* operator->() {
344   - return pval_;
  692 +
  693 + template <typename U>
  694 + U * as()
  695 + {
  696 + return reinterpret_cast<U*>( ptr() );
345 697 }
346   - _CL_OPT_CONSTEXPR const T& operator*() const _CL_OPT_LVALUE_REF_QUALIF {
347   - return *pval_;
  698 +
  699 + template <typename U>
  700 + U const * as() const
  701 + {
  702 + return reinterpret_cast<U const *>( ptr() );
348 703 }
349   - _CL_OPT_CONSTEXPR T& operator*() _CL_OPT_LVALUE_REF_QUALIF {
350   - return *pval_;
  704 +};
  705 +
  706 +} // namespace detail
  707 +
  708 +/// disengaged state tag
  709 +
  710 +struct nullopt_t
  711 +{
  712 + struct init{};
  713 + optional_constexpr nullopt_t( init ) {}
  714 +};
  715 +
  716 +#if optional_HAVE( CONSTEXPR_11 )
  717 +constexpr nullopt_t nullopt{ nullopt_t::init{} };
  718 +#else
  719 +// extra parenthesis to prevent the most vexing parse:
  720 +const nullopt_t nullopt(( nullopt_t::init() ));
  721 +#endif
  722 +
  723 +/// optional access error
  724 +
  725 +class bad_optional_access : public std::logic_error
  726 +{
  727 +public:
  728 + explicit bad_optional_access()
  729 + : logic_error( "bad optional access" ) {}
  730 +};
  731 +
  732 +/// optional
  733 +
  734 +template< typename T>
  735 +class optional
  736 +{
  737 +private:
  738 + template< typename > friend class optional;
  739 +
  740 + typedef void (optional::*safe_bool)() const;
  741 +
  742 +public:
  743 + typedef T value_type;
  744 +
  745 + // x.x.3.1, constructors
  746 +
  747 + // 1a - default construct
  748 + optional_constexpr optional() optional_noexcept
  749 + : has_value_( false )
  750 + , contained()
  751 + {}
  752 +
  753 + // 1b - construct explicitly empty
  754 + optional_constexpr optional( nullopt_t ) optional_noexcept
  755 + : has_value_( false )
  756 + , contained()
  757 + {}
  758 +
  759 + // 2 - copy-construct
  760 + optional_constexpr14 optional( optional const & other
  761 +#if optional_CPP11_OR_GREATER
  762 + optional_REQUIRES_A(
  763 + true || std::is_copy_constructible<T>::value
  764 + )
  765 +#endif
  766 + )
  767 + : has_value_( other.has_value() )
  768 + {
  769 + if ( other.has_value() )
  770 + contained.construct_value( other.contained.value() );
351 771 }
352   -#if _CL_OPT_MEMBERS_REF_QUALIFIERS
353   - _CL_OPT_CONSTEXPR const T&& operator*() const && {
354   - return std::move(*pval_);
  772 +
  773 +#if optional_CPP11_OR_GREATER
  774 +
  775 + // 3 (C++11) - move-construct from optional
  776 + optional_constexpr14 optional( optional && other
  777 + optional_REQUIRES_A(
  778 + true || std::is_move_constructible<T>::value
  779 + )
  780 + ) noexcept( std::is_nothrow_move_constructible<T>::value )
  781 + : has_value_( other.has_value() )
  782 + {
  783 + if ( other.has_value() )
  784 + contained.construct_value( std::move( other.contained.value() ) );
355 785 }
356   - _CL_OPT_CONSTEXPR T&& operator*() && {
357   - return std::move(*pval_);
  786 +
  787 + // 4 (C++11) - explicit converting copy-construct from optional
  788 + template< typename U >
  789 + explicit optional( optional<U> const & other
  790 + optional_REQUIRES_A(
  791 + std::is_constructible<T, U const &>::value
  792 + && !std::is_constructible<T, optional<U> & >::value
  793 + && !std::is_constructible<T, optional<U> && >::value
  794 + && !std::is_constructible<T, optional<U> const & >::value
  795 + && !std::is_constructible<T, optional<U> const && >::value
  796 + && !std::is_convertible< optional<U> & , T>::value
  797 + && !std::is_convertible< optional<U> && , T>::value
  798 + && !std::is_convertible< optional<U> const & , T>::value
  799 + && !std::is_convertible< optional<U> const &&, T>::value
  800 + && !std::is_convertible< U const & , T>::value /*=> explicit */
  801 + )
  802 + )
  803 + : has_value_( other.has_value() )
  804 + {
  805 + if ( other.has_value() )
  806 + contained.construct_value( other.contained.value() );
358 807 }
359   -#endif // _CL_OPT_MEMBERS_REF_QUALIFIERS
  808 +#endif // optional_CPP11_OR_GREATER
360 809
361   - // Value detection
362   - _CL_OPT_CONSTEXPR _CL_OPT_OP_EXPLICIT operator bool() const _CL_OPT_NOEXCEPT {
363   - return has_value_;
  810 + // 4 (C++98 and later) - non-explicit converting copy-construct from optional
  811 + template< typename U >
  812 + optional( optional<U> const & other
  813 +#if optional_CPP11_OR_GREATER
  814 + optional_REQUIRES_A(
  815 + std::is_constructible<T, U const &>::value
  816 + && !std::is_constructible<T, optional<U> & >::value
  817 + && !std::is_constructible<T, optional<U> && >::value
  818 + && !std::is_constructible<T, optional<U> const & >::value
  819 + && !std::is_constructible<T, optional<U> const && >::value
  820 + && !std::is_convertible< optional<U> & , T>::value
  821 + && !std::is_convertible< optional<U> && , T>::value
  822 + && !std::is_convertible< optional<U> const & , T>::value
  823 + && !std::is_convertible< optional<U> const &&, T>::value
  824 + && std::is_convertible< U const & , T>::value /*=> non-explicit */
  825 + )
  826 +#endif // optional_CPP11_OR_GREATER
  827 + )
  828 + : has_value_( other.has_value() )
  829 + {
  830 + if ( other.has_value() )
  831 + contained.construct_value( other.contained.value() );
364 832 }
365   - _CL_OPT_CONSTEXPR bool has_value() const _CL_OPT_NOEXCEPT {
366   - return has_value_;
  833 +
  834 +#if optional_CPP11_OR_GREATER
  835 +
  836 + // 5a (C++11) - explicit converting move-construct from optional
  837 + template< typename U >
  838 + optional( optional<U> && other
  839 + optional_REQUIRES_A(
  840 + std::is_constructible<T, U const &>::value
  841 + && !std::is_constructible<T, optional<U> & >::value
  842 + && !std::is_constructible<T, optional<U> && >::value
  843 + && !std::is_constructible<T, optional<U> const & >::value
  844 + && !std::is_constructible<T, optional<U> const && >::value
  845 + && !std::is_convertible< optional<U> & , T>::value
  846 + && !std::is_convertible< optional<U> && , T>::value
  847 + && !std::is_convertible< optional<U> const & , T>::value
  848 + && !std::is_convertible< optional<U> const &&, T>::value
  849 + && !std::is_convertible< U &&, T>::value /*=> explicit */
  850 + )
  851 + )
  852 + : has_value_( other.has_value() )
  853 + {
  854 + if ( other.has_value() )
  855 + contained.construct_value( std::move( other.contained.value() ) );
367 856 }
368 857
369   - // Value accessors that throw if optional doesn't have a value
370   - _CL_OPT_CONSTEXPR const T& value() const _CL_OPT_LVALUE_REF_QUALIF {
371   - if (!has_value_) {
372   - throw_bad_optional_access();
373   - }
374   - return *pval_;
375   - }
376   - _CL_OPT_CONSTEXPR T& value() _CL_OPT_LVALUE_REF_QUALIF {
377   - if (!has_value_) {
378   - throw_bad_optional_access();
379   - }
380   - return *pval_;
381   - }
382   -#if _CL_OPT_MEMBERS_REF_QUALIFIERS
383   - _CL_OPT_CONSTEXPR const T&& value() const && {
384   - if (!has_value_) {
385   - throw_bad_optional_access();
386   - }
387   - return std::move(*pval_);
388   - }
389   - _CL_OPT_CONSTEXPR T&& value() && {
390   - if (!has_value_) {
391   - throw_bad_optional_access();
392   - }
393   - return std::move(*pval_);
394   - }
395   -#endif // _CL_OPT_MEMBERS_REF_QUALIFIERS
396   -
397   - // Value accessors with an alternative if optional doesn't have a value
398   - template<typename U>
399   - _CL_OPT_CONSTEXPR T value_or(U&& default_val) const _CL_OPT_LVALUE_REF_QUALIF
400   - _CL_OPT_NOEXCEPTEX(std::is_nothrow_copy_constructible<T>::value &&
401   - std::is_nothrow_constructible<T, U>::value)
402   - {
403   - return has_value_ ? *pval_ : T(std::forward<U>(default_val));
404   - }
405   -#if _CL_OPT_MEMBERS_REF_QUALIFIERS
406   - template<typename U>
407   - _CL_OPT_CONSTEXPR T value_or(U&& default_val) &&
408   - _CL_OPT_NOEXCEPTEX(std::is_nothrow_move_constructible<T>::value &&
409   - std::is_nothrow_constructible<T, U>::value)
410   - {
411   - return has_value_ ? std::move(*pval_) : T(std::forward<U>(default_val));
412   - }
413   -#endif // _CL_OPT_MEMBERS_REF_QUALIFIERS
414   -
415   - // Swap implementation
416   - void swap(optional& obj) _CL_OPT_NOEXCEPTEX(std::is_nothrow_move_constructible<T>::value &&
417   - std::is_nothrow_destructible<T>::value &&
418   - noexcept(std::swap(std::declval<T&>(), std::declval<T&>()))) // #clp TODO using std::swap here seems wrong, no?
419   - {
420   - if (obj.has_value_) {
421   - if (has_value_) {
422   - using std::swap;
423   - swap(*pval_, *obj.pval_);
424   - } else {
425   - swap_helper(obj, *this);
426   - }
427   - } else if (has_value_) {
428   - swap_helper(*this, obj);
429   - }
430   - }
431   - // Non-member version of swap for ADL
432   - friend void swap(optional& obj1, optional& obj2) {
433   - obj1.swap(obj2);
434   - }
435   -
436   - // Removes any value held
437   - void reset() _CL_OPT_NOEXCEPTEX(std::is_nothrow_destructible<T>::value)
438   - {
439   - if (has_value_) {
440   - pval_->~T();
441   - has_value_ = false;
442   - }
443   - }
444   -
445   -#if _CL_OPT_VARIADIC
446   - // Destroys any held value and constructs a new one in-place
447   - template<typename... Args>
448   - void emplace(Args&&... args) _CL_OPT_NOEXCEPTEX(std::is_nothrow_destructible<T>::value &&
449   - std::is_nothrow_constructible<T, Args...>::value)
  858 + // 5a (C++11) - non-explicit converting move-construct from optional
  859 + template< typename U >
  860 + optional( optional<U> && other
  861 + optional_REQUIRES_A(
  862 + std::is_constructible<T, U const &>::value
  863 + && !std::is_constructible<T, optional<U> & >::value
  864 + && !std::is_constructible<T, optional<U> && >::value
  865 + && !std::is_constructible<T, optional<U> const & >::value
  866 + && !std::is_constructible<T, optional<U> const && >::value
  867 + && !std::is_convertible< optional<U> & , T>::value
  868 + && !std::is_convertible< optional<U> && , T>::value
  869 + && !std::is_convertible< optional<U> const & , T>::value
  870 + && !std::is_convertible< optional<U> const &&, T>::value
  871 + && std::is_convertible< U &&, T>::value /*=> non-explicit */
  872 + )
  873 + )
  874 + : has_value_( other.has_value() )
450 875 {
451   - reset();
452   - new (pval_) T(std::forward<Args>(args)...);
453   - has_value_ = true;
  876 + if ( other.has_value() )
  877 + contained.construct_value( std::move( other.contained.value() ) );
  878 + }
  879 +
  880 + // 6 (C++11) - in-place construct
  881 + template< typename... Args
  882 + optional_REQUIRES_T(
  883 + std::is_constructible<T, Args&&...>::value
  884 + )
  885 + >
  886 + optional_constexpr explicit optional( nonstd_lite_in_place_t(T), Args&&... args )
  887 + : has_value_( true )
  888 + , contained( T( std::forward<Args>(args)...) )
  889 + {}
  890 +
  891 + // 7 (C++11) - in-place construct, initializer-list
  892 + template< typename U, typename... Args
  893 + optional_REQUIRES_T(
  894 + std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value
  895 + )
  896 + >
  897 + optional_constexpr explicit optional( nonstd_lite_in_place_t(T), std::initializer_list<U> il, Args&&... args )
  898 + : has_value_( true )
  899 + , contained( T( il, std::forward<Args>(args)...) )
  900 + {}
  901 +
  902 + // 8a (C++11) - explicit move construct from value
  903 + template< typename U = value_type >
  904 + optional_constexpr explicit optional( U && value
  905 + optional_REQUIRES_A(
  906 + std::is_constructible<T, U&&>::value
  907 + && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
  908 + && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
  909 + && !std::is_convertible<U&&, T>::value /*=> explicit */
  910 + )
  911 + )
  912 + : has_value_( true )
  913 + , contained( std::forward<U>( value ) )
  914 + {}
  915 +
  916 + // 8a (C++11) - non-explicit move construct from value
  917 + template< typename U = value_type >
  918 + optional_constexpr optional( U && value
  919 + optional_REQUIRES_A(
  920 + std::is_constructible<T, U&&>::value
  921 + && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
  922 + && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
  923 + && std::is_convertible<U&&, T>::value /*=> non-explicit */
  924 + )
  925 + )
  926 + : has_value_( true )
  927 + , contained( std::forward<U>( value ) )