// This version targets C++11 and later.
//
-// Copyright (C) 2016-2018 Martin Moene.
+// Copyright (C) 2016-2020 Martin Moene.
//
// 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)
# define nsel_P0323R 7
#endif
-// Control presence of exception handling (try and auto discover):
+// Control presence of C++ exception handling (try and auto discover):
#ifndef nsel_CONFIG_NO_EXCEPTIONS
-# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
+# if defined(_MSC_VER)
+# include <cstddef> // for _HAS_EXCEPTIONS
+# endif
+# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
# define nsel_CONFIG_NO_EXCEPTIONS 0
# else
# define nsel_CONFIG_NO_EXCEPTIONS 1
# endif
#endif
+// at default use SEH with MSVC for no C++ exceptions
+
+#ifndef nsel_CONFIG_NO_EXCEPTIONS_SEH
+# define nsel_CONFIG_NO_EXCEPTIONS_SEH ( nsel_CONFIG_NO_EXCEPTIONS && _MSC_VER )
+#endif
+
// C++ language version detection (C++20 is speculative):
// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
// additional includes:
#if nsel_CONFIG_NO_EXCEPTIONS
+# if nsel_CONFIG_NO_EXCEPTIONS_SEH
+# include <windows.h> // for ExceptionCodes
+# else
// already included: <cassert>
+# endif
#else
# include <stdexcept>
#endif
{
static void rethrow( Error const & /*e*/ )
{
+#if nsel_CONFIG_NO_EXCEPTIONS_SEH
+ RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
+#else
assert( false && detail::text("throw bad_expected_access<Error>{ e };") );
+#endif
}
};
{
static void rethrow( std::exception_ptr const & /*e*/ )
{
+#if nsel_CONFIG_NO_EXCEPTIONS_SEH
+ RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
+#else
assert( false && detail::text("throw bad_expected_access<std::exception_ptr>{ e };") );
+#endif
}
};
{
static void rethrow( std::error_code const & /*e*/ )
{
+#if nsel_CONFIG_NO_EXCEPTIONS_SEH
+ RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL );
+#else
assert( false && detail::text("throw std::system_error( e );") );
+#endif
}
};
return *this;
}
- template< typename G
+ template< typename G = E
nsel_REQUIRES_T(
- std::is_copy_constructible<E>::value // TODO: std::is_nothrow_copy_constructible<E>
- && std::is_copy_assignable<E>::value
+ std::is_constructible<E, G const&>::value &&
+ std::is_copy_constructible<G>::value // TODO: std::is_nothrow_copy_constructible<G>
+ && std::is_copy_assignable<G>::value
)
>
expected & operator=( nonstd::unexpected_type<G> const & error )
return *this;
}
- template< typename G
+ template< typename G = E
nsel_REQUIRES_T(
- std::is_move_constructible<E>::value // TODO: std::is_nothrow_move_constructible<E>
- && std::is_move_assignable<E>::value
+ std::is_constructible<E, G&&>::value &&
+ std::is_move_constructible<G>::value // TODO: std::is_nothrow_move_constructible<G>
+ && std::is_move_assignable<G>::value
)
>
expected & operator=( nonstd::unexpected_type<G> && error )
constexpr value_type const && operator *() const &&
{
- return assert( has_value() ), std::move( contained.value() );
+ return std::move( ( assert( has_value() ), contained.value() ) );
}
nsel_constexpr14 value_type && operator *() &&
{
- return assert( has_value() ), std::move( contained.value() );
+ return std::move( ( assert( has_value() ), contained.value() ) );
}
#endif
constexpr error_type const && error() const &&
{
- return assert( ! has_value() ), std::move( contained.error() );
+ return std::move( ( assert( ! has_value() ), contained.error() ) );
}
error_type && error() &&
{
- return assert( ! has_value() ), std::move( contained.error() );
+ return std::move( ( assert( ! has_value() ), contained.error() ) );
}
#endif
constexpr error_type const && error() const &&
{
- return assert( ! has_value() ), std::move( contained.error() );
+ return std::move( ( assert( ! has_value() ), contained.error() ) );
}
error_type && error() &&
{
- return assert( ! has_value() ), std::move( contained.error() );
+ return std::move( ( assert( ! has_value() ), contained.error() ) );
}
#endif