mirror of
https://github.com/zama-ai/concrete.git
synced 2026-02-10 04:35:03 -05:00
7940 lines
346 KiB
C++
7940 lines
346 KiB
C++
/* Include the default amount of outcome
|
|
(C) 2018-2021 Niall Douglas <http://www.nedproductions.biz/> (4 commits)
|
|
File Created: Mar 2018
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#if !OUTCOME_ENABLE_CXX_MODULES || !0 || defined(GENERATING_OUTCOME_MODULE_INTERFACE) || OUTCOME_DISABLE_CXX_MODULES
|
|
/* Tells C++ coroutines about Outcome's result
|
|
(C) 2019 Niall Douglas <http://www.nedproductions.biz/> (12 commits)
|
|
File Created: Oct 2019
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_COROUTINE_SUPPORT_HPP
|
|
#define OUTCOME_COROUTINE_SUPPORT_HPP
|
|
/* Configure Outcome with QuickCppLib
|
|
(C) 2015-2021 Niall Douglas <http://www.nedproductions.biz/> (24 commits)
|
|
File Created: August 2015
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_V2_CONFIG_HPP
|
|
#define OUTCOME_V2_CONFIG_HPP
|
|
/* Sets Outcome version
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (4 commits)
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL */
|
|
#define OUTCOME_VERSION_MAJOR 2
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL */
|
|
#define OUTCOME_VERSION_MINOR 2
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL */
|
|
#define OUTCOME_VERSION_PATCH 0
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL */
|
|
#define OUTCOME_VERSION_REVISION 0 // Revision version for cmake and DLL version stamping
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL */
|
|
#ifndef OUTCOME_DISABLE_ABI_PERMUTATION
|
|
#define OUTCOME_UNSTABLE_VERSION
|
|
#endif
|
|
// Pull in detection of __MINGW64_VERSION_MAJOR
|
|
#if defined(__MINGW32__) && !0
|
|
#include <_mingw.h>
|
|
#endif
|
|
/* Configure QuickCppLib
|
|
(C) 2016-2021 Niall Douglas <http://www.nedproductions.biz/> (8 commits)
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef QUICKCPPLIB_CONFIG_HPP
|
|
#define QUICKCPPLIB_CONFIG_HPP
|
|
/* Provides SG-10 feature checking for all C++ compilers
|
|
(C) 2014-2017 Niall Douglas <http://www.nedproductions.biz/> (13 commits)
|
|
File Created: Nov 2014
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef QUICKCPPLIB_HAS_FEATURE_H
|
|
#define QUICKCPPLIB_HAS_FEATURE_H
|
|
#if __cplusplus >= 201103
|
|
// Some of these macros ended up getting removed by ISO standards,
|
|
// they are prefixed with ////
|
|
////#if !defined(__cpp_alignas)
|
|
////#define __cpp_alignas 190000
|
|
////#endif
|
|
////#if !defined(__cpp_default_function_template_args)
|
|
////#define __cpp_default_function_template_args 190000
|
|
////#endif
|
|
////#if !defined(__cpp_defaulted_functions)
|
|
////#define __cpp_defaulted_functions 190000
|
|
////#endif
|
|
////#if !defined(__cpp_deleted_functions)
|
|
////#define __cpp_deleted_functions 190000
|
|
////#endif
|
|
////#if !defined(__cpp_generalized_initializers)
|
|
////#define __cpp_generalized_initializers 190000
|
|
////#endif
|
|
////#if !defined(__cpp_implicit_moves)
|
|
////#define __cpp_implicit_moves 190000
|
|
////#endif
|
|
////#if !defined(__cpp_inline_namespaces)
|
|
////#define __cpp_inline_namespaces 190000
|
|
////#endif
|
|
////#if !defined(__cpp_local_type_template_args)
|
|
////#define __cpp_local_type_template_args 190000
|
|
////#endif
|
|
////#if !defined(__cpp_noexcept)
|
|
////#define __cpp_noexcept 190000
|
|
////#endif
|
|
////#if !defined(__cpp_nonstatic_member_init)
|
|
////#define __cpp_nonstatic_member_init 190000
|
|
////#endif
|
|
////#if !defined(__cpp_nullptr)
|
|
////#define __cpp_nullptr 190000
|
|
////#endif
|
|
////#if !defined(__cpp_override_control)
|
|
////#define __cpp_override_control 190000
|
|
////#endif
|
|
////#if !defined(__cpp_thread_local)
|
|
////#define __cpp_thread_local 190000
|
|
////#endif
|
|
////#if !defined(__cpp_auto_type)
|
|
////#define __cpp_auto_type 190000
|
|
////#endif
|
|
////#if !defined(__cpp_strong_enums)
|
|
////#define __cpp_strong_enums 190000
|
|
////#endif
|
|
////#if !defined(__cpp_trailing_return)
|
|
////#define __cpp_trailing_return 190000
|
|
////#endif
|
|
////#if !defined(__cpp_unrestricted_unions)
|
|
////#define __cpp_unrestricted_unions 190000
|
|
////#endif
|
|
#if !defined(__cpp_alias_templates)
|
|
#define __cpp_alias_templates 190000
|
|
#endif
|
|
#if !defined(__cpp_attributes)
|
|
#define __cpp_attributes 190000
|
|
#endif
|
|
#if !defined(__cpp_constexpr)
|
|
#if __cplusplus >= 201402
|
|
#define __cpp_constexpr 201304 // relaxed constexpr
|
|
#else
|
|
#define __cpp_constexpr 190000
|
|
#endif
|
|
#endif
|
|
#if !defined(__cpp_decltype)
|
|
#define __cpp_decltype 190000
|
|
#endif
|
|
#if !defined(__cpp_delegating_constructors)
|
|
#define __cpp_delegating_constructors 190000
|
|
#endif
|
|
#if !defined(__cpp_explicit_conversion) //// renamed from __cpp_explicit_conversions
|
|
#define __cpp_explicit_conversion 190000
|
|
#endif
|
|
#if !defined(__cpp_inheriting_constructors)
|
|
#define __cpp_inheriting_constructors 190000
|
|
#endif
|
|
#if !defined(__cpp_initializer_lists) //// NEW
|
|
#define __cpp_initializer_lists 190000
|
|
#endif
|
|
#if !defined(__cpp_lambdas)
|
|
#define __cpp_lambdas 190000
|
|
#endif
|
|
#if !defined(__cpp_nsdmi)
|
|
#define __cpp_nsdmi 190000 //// NEW
|
|
#endif
|
|
#if !defined(__cpp_range_based_for) //// renamed from __cpp_range_for
|
|
#define __cpp_range_based_for 190000
|
|
#endif
|
|
#if !defined(__cpp_raw_strings)
|
|
#define __cpp_raw_strings 190000
|
|
#endif
|
|
#if !defined(__cpp_ref_qualifiers) //// renamed from __cpp_reference_qualified_functions
|
|
#define __cpp_ref_qualifiers 190000
|
|
#endif
|
|
#if !defined(__cpp_rvalue_references)
|
|
#define __cpp_rvalue_references 190000
|
|
#endif
|
|
#if !defined(__cpp_static_assert)
|
|
#define __cpp_static_assert 190000
|
|
#endif
|
|
#if !defined(__cpp_unicode_characters) //// NEW
|
|
#define __cpp_unicode_characters 190000
|
|
#endif
|
|
#if !defined(__cpp_unicode_literals)
|
|
#define __cpp_unicode_literals 190000
|
|
#endif
|
|
#if !defined(__cpp_user_defined_literals)
|
|
#define __cpp_user_defined_literals 190000
|
|
#endif
|
|
#if !defined(__cpp_variadic_templates)
|
|
#define __cpp_variadic_templates 190000
|
|
#endif
|
|
#endif
|
|
#if __cplusplus >= 201402
|
|
// Some of these macros ended up getting removed by ISO standards,
|
|
// they are prefixed with ////
|
|
////#if !defined(__cpp_contextual_conversions)
|
|
////#define __cpp_contextual_conversions 190000
|
|
////#endif
|
|
////#if !defined(__cpp_digit_separators)
|
|
////#define __cpp_digit_separators 190000
|
|
////#endif
|
|
////#if !defined(__cpp_relaxed_constexpr)
|
|
////#define __cpp_relaxed_constexpr 190000
|
|
////#endif
|
|
////#if !defined(__cpp_runtime_arrays)
|
|
////# define __cpp_runtime_arrays 190000
|
|
////#endif
|
|
#if !defined(__cpp_aggregate_nsdmi)
|
|
#define __cpp_aggregate_nsdmi 190000
|
|
#endif
|
|
#if !defined(__cpp_binary_literals)
|
|
#define __cpp_binary_literals 190000
|
|
#endif
|
|
#if !defined(__cpp_decltype_auto)
|
|
#define __cpp_decltype_auto 190000
|
|
#endif
|
|
#if !defined(__cpp_generic_lambdas)
|
|
#define __cpp_generic_lambdas 190000
|
|
#endif
|
|
#if !defined(__cpp_init_captures)
|
|
#define __cpp_init_captures 190000
|
|
#endif
|
|
#if !defined(__cpp_return_type_deduction)
|
|
#define __cpp_return_type_deduction 190000
|
|
#endif
|
|
#if !defined(__cpp_sized_deallocation)
|
|
#define __cpp_sized_deallocation 190000
|
|
#endif
|
|
#if !defined(__cpp_variable_templates)
|
|
#define __cpp_variable_templates 190000
|
|
#endif
|
|
#endif
|
|
// VS2010: _MSC_VER=1600
|
|
// VS2012: _MSC_VER=1700
|
|
// VS2013: _MSC_VER=1800
|
|
// VS2015: _MSC_VER=1900
|
|
// VS2017: _MSC_VER=1910
|
|
#if defined(_MSC_VER) && !defined(__clang__)
|
|
#if !defined(__cpp_exceptions) && defined(_CPPUNWIND)
|
|
#define __cpp_exceptions 190000
|
|
#endif
|
|
#if !defined(__cpp_rtti) && defined(_CPPRTTI)
|
|
#define __cpp_rtti 190000
|
|
#endif
|
|
// C++ 11
|
|
#if !defined(__cpp_alias_templates) && _MSC_VER >= 1800
|
|
#define __cpp_alias_templates 190000
|
|
#endif
|
|
#if !defined(__cpp_attributes)
|
|
#define __cpp_attributes 190000
|
|
#endif
|
|
#if !defined(__cpp_constexpr) && _MSC_FULL_VER >= 190023506 /* VS2015 */
|
|
#define __cpp_constexpr 190000
|
|
#endif
|
|
#if !defined(__cpp_decltype) && _MSC_VER >= 1600
|
|
#define __cpp_decltype 190000
|
|
#endif
|
|
#if !defined(__cpp_delegating_constructors) && _MSC_VER >= 1800
|
|
#define __cpp_delegating_constructors 190000
|
|
#endif
|
|
#if !defined(__cpp_explicit_conversion) && _MSC_VER >= 1800
|
|
#define __cpp_explicit_conversion 190000
|
|
#endif
|
|
#if !defined(__cpp_inheriting_constructors) && _MSC_VER >= 1900
|
|
#define __cpp_inheriting_constructors 190000
|
|
#endif
|
|
#if !defined(__cpp_initializer_lists) && _MSC_VER >= 1900
|
|
#define __cpp_initializer_lists 190000
|
|
#endif
|
|
#if !defined(__cpp_lambdas) && _MSC_VER >= 1600
|
|
#define __cpp_lambdas 190000
|
|
#endif
|
|
#if !defined(__cpp_nsdmi) && _MSC_VER >= 1900
|
|
#define __cpp_nsdmi 190000
|
|
#endif
|
|
#if !defined(__cpp_range_based_for) && _MSC_VER >= 1700
|
|
#define __cpp_range_based_for 190000
|
|
#endif
|
|
#if !defined(__cpp_raw_strings) && _MSC_VER >= 1800
|
|
#define __cpp_raw_strings 190000
|
|
#endif
|
|
#if !defined(__cpp_ref_qualifiers) && _MSC_VER >= 1900
|
|
#define __cpp_ref_qualifiers 190000
|
|
#endif
|
|
#if !defined(__cpp_rvalue_references) && _MSC_VER >= 1600
|
|
#define __cpp_rvalue_references 190000
|
|
#endif
|
|
#if !defined(__cpp_static_assert) && _MSC_VER >= 1600
|
|
#define __cpp_static_assert 190000
|
|
#endif
|
|
//#if !defined(__cpp_unicode_literals)
|
|
//# define __cpp_unicode_literals 190000
|
|
//#endif
|
|
#if !defined(__cpp_user_defined_literals) && _MSC_VER >= 1900
|
|
#define __cpp_user_defined_literals 190000
|
|
#endif
|
|
#if !defined(__cpp_variadic_templates) && _MSC_VER >= 1800
|
|
#define __cpp_variadic_templates 190000
|
|
#endif
|
|
// C++ 14
|
|
//#if !defined(__cpp_aggregate_nsdmi)
|
|
//#define __cpp_aggregate_nsdmi 190000
|
|
//#endif
|
|
#if !defined(__cpp_binary_literals) && _MSC_VER >= 1900
|
|
#define __cpp_binary_literals 190000
|
|
#endif
|
|
#if !defined(__cpp_decltype_auto) && _MSC_VER >= 1900
|
|
#define __cpp_decltype_auto 190000
|
|
#endif
|
|
#if !defined(__cpp_generic_lambdas) && _MSC_VER >= 1900
|
|
#define __cpp_generic_lambdas 190000
|
|
#endif
|
|
#if !defined(__cpp_init_captures) && _MSC_VER >= 1900
|
|
#define __cpp_init_captures 190000
|
|
#endif
|
|
#if !defined(__cpp_return_type_deduction) && _MSC_VER >= 1900
|
|
#define __cpp_return_type_deduction 190000
|
|
#endif
|
|
#if !defined(__cpp_sized_deallocation) && _MSC_VER >= 1900
|
|
#define __cpp_sized_deallocation 190000
|
|
#endif
|
|
#if !defined(__cpp_variable_templates) && _MSC_FULL_VER >= 190023506
|
|
#define __cpp_variable_templates 190000
|
|
#endif
|
|
#endif // _MSC_VER
|
|
// Much to my surprise, GCC's support of these is actually incomplete, so fill in the gaps
|
|
#if (defined(__GNUC__) && !defined(__clang__))
|
|
#define QUICKCPPLIB_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
|
#if !defined(__cpp_exceptions) && defined(__EXCEPTIONS)
|
|
#define __cpp_exceptions 190000
|
|
#endif
|
|
#if !defined(__cpp_rtti) && defined(__GXX_RTTI)
|
|
#define __cpp_rtti 190000
|
|
#endif
|
|
// C++ 11
|
|
#if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
|
#if !defined(__cpp_alias_templates) && (QUICKCPPLIB_GCC >= 40700)
|
|
#define __cpp_alias_templates 190000
|
|
#endif
|
|
#if !defined(__cpp_attributes) && (QUICKCPPLIB_GCC >= 40800)
|
|
#define __cpp_attributes 190000
|
|
#endif
|
|
#if !defined(__cpp_constexpr) && (QUICKCPPLIB_GCC >= 40600)
|
|
#define __cpp_constexpr 190000
|
|
#endif
|
|
#if !defined(__cpp_decltype) && (QUICKCPPLIB_GCC >= 40300)
|
|
#define __cpp_decltype 190000
|
|
#endif
|
|
#if !defined(__cpp_delegating_constructors) && (QUICKCPPLIB_GCC >= 40700)
|
|
#define __cpp_delegating_constructors 190000
|
|
#endif
|
|
#if !defined(__cpp_explicit_conversion) && (QUICKCPPLIB_GCC >= 40500)
|
|
#define __cpp_explicit_conversion 190000
|
|
#endif
|
|
#if !defined(__cpp_inheriting_constructors) && (QUICKCPPLIB_GCC >= 40800)
|
|
#define __cpp_inheriting_constructors 190000
|
|
#endif
|
|
#if !defined(__cpp_initializer_lists) && (QUICKCPPLIB_GCC >= 40800)
|
|
#define __cpp_initializer_lists 190000
|
|
#endif
|
|
#if !defined(__cpp_lambdas) && (QUICKCPPLIB_GCC >= 40500)
|
|
#define __cpp_lambdas 190000
|
|
#endif
|
|
#if !defined(__cpp_nsdmi) && (QUICKCPPLIB_GCC >= 40700)
|
|
#define __cpp_nsdmi 190000
|
|
#endif
|
|
#if !defined(__cpp_range_based_for) && (QUICKCPPLIB_GCC >= 40600)
|
|
#define __cpp_range_based_for 190000
|
|
#endif
|
|
#if !defined(__cpp_raw_strings) && (QUICKCPPLIB_GCC >= 40500)
|
|
#define __cpp_raw_strings 190000
|
|
#endif
|
|
#if !defined(__cpp_ref_qualifiers) && (QUICKCPPLIB_GCC >= 40801)
|
|
#define __cpp_ref_qualifiers 190000
|
|
#endif
|
|
// __cpp_rvalue_reference deviation
|
|
#if !defined(__cpp_rvalue_references) && defined(__cpp_rvalue_reference)
|
|
#define __cpp_rvalue_references __cpp_rvalue_reference
|
|
#endif
|
|
#if !defined(__cpp_static_assert) && (QUICKCPPLIB_GCC >= 40300)
|
|
#define __cpp_static_assert 190000
|
|
#endif
|
|
#if !defined(__cpp_unicode_characters) && (QUICKCPPLIB_GCC >= 40500)
|
|
#define __cpp_unicode_characters 190000
|
|
#endif
|
|
#if !defined(__cpp_unicode_literals) && (QUICKCPPLIB_GCC >= 40500)
|
|
#define __cpp_unicode_literals 190000
|
|
#endif
|
|
#if !defined(__cpp_user_defined_literals) && (QUICKCPPLIB_GCC >= 40700)
|
|
#define __cpp_user_defined_literals 190000
|
|
#endif
|
|
#if !defined(__cpp_variadic_templates) && (QUICKCPPLIB_GCC >= 40400)
|
|
#define __cpp_variadic_templates 190000
|
|
#endif
|
|
// C++ 14
|
|
// Every C++ 14 supporting GCC does the right thing here
|
|
#endif // __GXX_EXPERIMENTAL_CXX0X__
|
|
#endif // GCC
|
|
// clang deviates in some places from the present SG-10 draft, plus older
|
|
// clangs are quite incomplete
|
|
#if defined(__clang__)
|
|
#define QUICKCPPLIB_CLANG (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
|
|
#if !defined(__cpp_exceptions) && (defined(__EXCEPTIONS) || defined(_CPPUNWIND))
|
|
#define __cpp_exceptions 190000
|
|
#endif
|
|
#if !defined(__cpp_rtti) && (defined(__GXX_RTTI) || defined(_CPPRTTI))
|
|
#define __cpp_rtti 190000
|
|
#endif
|
|
// C++ 11
|
|
#if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
|
#if !defined(__cpp_alias_templates) && (QUICKCPPLIB_CLANG >= 30000)
|
|
#define __cpp_alias_templates 190000
|
|
#endif
|
|
#if !defined(__cpp_attributes) && (QUICKCPPLIB_CLANG >= 30300)
|
|
#define __cpp_attributes 190000
|
|
#endif
|
|
#if !defined(__cpp_constexpr) && (QUICKCPPLIB_CLANG >= 30100)
|
|
#define __cpp_constexpr 190000
|
|
#endif
|
|
#if !defined(__cpp_decltype) && (QUICKCPPLIB_CLANG >= 20900)
|
|
#define __cpp_decltype 190000
|
|
#endif
|
|
#if !defined(__cpp_delegating_constructors) && (QUICKCPPLIB_CLANG >= 30000)
|
|
#define __cpp_delegating_constructors 190000
|
|
#endif
|
|
#if !defined(__cpp_explicit_conversion) && (QUICKCPPLIB_CLANG >= 30000)
|
|
#define __cpp_explicit_conversion 190000
|
|
#endif
|
|
#if !defined(__cpp_inheriting_constructors) && (QUICKCPPLIB_CLANG >= 30300)
|
|
#define __cpp_inheriting_constructors 190000
|
|
#endif
|
|
#if !defined(__cpp_initializer_lists) && (QUICKCPPLIB_CLANG >= 30100)
|
|
#define __cpp_initializer_lists 190000
|
|
#endif
|
|
#if !defined(__cpp_lambdas) && (QUICKCPPLIB_CLANG >= 30100)
|
|
#define __cpp_lambdas 190000
|
|
#endif
|
|
#if !defined(__cpp_nsdmi) && (QUICKCPPLIB_CLANG >= 30000)
|
|
#define __cpp_nsdmi 190000
|
|
#endif
|
|
#if !defined(__cpp_range_based_for) && (QUICKCPPLIB_CLANG >= 30000)
|
|
#define __cpp_range_based_for 190000
|
|
#endif
|
|
// __cpp_raw_string_literals deviation
|
|
#if !defined(__cpp_raw_strings) && defined(__cpp_raw_string_literals)
|
|
#define __cpp_raw_strings __cpp_raw_string_literals
|
|
#endif
|
|
#if !defined(__cpp_raw_strings) && (QUICKCPPLIB_CLANG >= 30000)
|
|
#define __cpp_raw_strings 190000
|
|
#endif
|
|
#if !defined(__cpp_ref_qualifiers) && (QUICKCPPLIB_CLANG >= 20900)
|
|
#define __cpp_ref_qualifiers 190000
|
|
#endif
|
|
// __cpp_rvalue_reference deviation
|
|
#if !defined(__cpp_rvalue_references) && defined(__cpp_rvalue_reference)
|
|
#define __cpp_rvalue_references __cpp_rvalue_reference
|
|
#endif
|
|
#if !defined(__cpp_rvalue_references) && (QUICKCPPLIB_CLANG >= 20900)
|
|
#define __cpp_rvalue_references 190000
|
|
#endif
|
|
#if !defined(__cpp_static_assert) && (QUICKCPPLIB_CLANG >= 20900)
|
|
#define __cpp_static_assert 190000
|
|
#endif
|
|
#if !defined(__cpp_unicode_characters) && (QUICKCPPLIB_CLANG >= 30000)
|
|
#define __cpp_unicode_characters 190000
|
|
#endif
|
|
#if !defined(__cpp_unicode_literals) && (QUICKCPPLIB_CLANG >= 30000)
|
|
#define __cpp_unicode_literals 190000
|
|
#endif
|
|
// __cpp_user_literals deviation
|
|
#if !defined(__cpp_user_defined_literals) && defined(__cpp_user_literals)
|
|
#define __cpp_user_defined_literals __cpp_user_literals
|
|
#endif
|
|
#if !defined(__cpp_user_defined_literals) && (QUICKCPPLIB_CLANG >= 30100)
|
|
#define __cpp_user_defined_literals 190000
|
|
#endif
|
|
#if !defined(__cpp_variadic_templates) && (QUICKCPPLIB_CLANG >= 20900)
|
|
#define __cpp_variadic_templates 190000
|
|
#endif
|
|
// C++ 14
|
|
// Every C++ 14 supporting clang does the right thing here
|
|
#endif // __GXX_EXPERIMENTAL_CXX0X__
|
|
#endif // clang
|
|
#endif
|
|
#ifndef QUICKCPPLIB_DISABLE_ABI_PERMUTATION
|
|
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
|
|
#define QUICKCPPLIB_PREVIOUS_COMMIT_REF e691a6dc0358c1091d59022af06a97d68fcc074d
|
|
#define QUICKCPPLIB_PREVIOUS_COMMIT_DATE "2021-09-15 10:28:22 +00:00"
|
|
#define QUICKCPPLIB_PREVIOUS_COMMIT_UNIQUE e691a6dc
|
|
#endif
|
|
#define QUICKCPPLIB_VERSION_GLUE2(a, b) a##b
|
|
#define QUICKCPPLIB_VERSION_GLUE(a, b) QUICKCPPLIB_VERSION_GLUE2(a, b)
|
|
// clang-format off
|
|
#if defined(QUICKCPPLIB_DISABLE_ABI_PERMUTATION)
|
|
#define QUICKCPPLIB_NAMESPACE quickcpplib
|
|
#define QUICKCPPLIB_NAMESPACE_BEGIN namespace quickcpplib {
|
|
#define QUICKCPPLIB_NAMESPACE_END }
|
|
#else
|
|
#define QUICKCPPLIB_NAMESPACE quickcpplib::QUICKCPPLIB_VERSION_GLUE(_, QUICKCPPLIB_PREVIOUS_COMMIT_UNIQUE)
|
|
#define QUICKCPPLIB_NAMESPACE_BEGIN namespace quickcpplib { namespace QUICKCPPLIB_VERSION_GLUE(_, QUICKCPPLIB_PREVIOUS_COMMIT_UNIQUE) {
|
|
#define QUICKCPPLIB_NAMESPACE_END } }
|
|
#endif
|
|
// clang-format on
|
|
#ifdef _MSC_VER
|
|
#define QUICKCPPLIB_BIND_MESSAGE_PRAGMA2(x) __pragma(message(x))
|
|
#define QUICKCPPLIB_BIND_MESSAGE_PRAGMA(x) QUICKCPPLIB_BIND_MESSAGE_PRAGMA2(x)
|
|
#define QUICKCPPLIB_BIND_MESSAGE_PREFIX(type) __FILE__ "(" QUICKCPPLIB_BIND_STRINGIZE2(__LINE__) "): " type ": "
|
|
#define QUICKCPPLIB_BIND_MESSAGE_(type, prefix, msg) QUICKCPPLIB_BIND_MESSAGE_PRAGMA(prefix msg)
|
|
#else
|
|
#define QUICKCPPLIB_BIND_MESSAGE_PRAGMA2(x) _Pragma(#x)
|
|
#define QUICKCPPLIB_BIND_MESSAGE_PRAGMA(type, x) QUICKCPPLIB_BIND_MESSAGE_PRAGMA2(type x)
|
|
#define QUICKCPPLIB_BIND_MESSAGE_(type, prefix, msg) QUICKCPPLIB_BIND_MESSAGE_PRAGMA(type, msg)
|
|
#endif
|
|
//! Have the compiler output a message
|
|
#define QUICKCPPLIB_MESSAGE(msg) QUICKCPPLIB_BIND_MESSAGE_(message, QUICKCPPLIB_BIND_MESSAGE_PREFIX("message"), msg)
|
|
//! Have the compiler output a note
|
|
#define QUICKCPPLIB_NOTE(msg) QUICKCPPLIB_BIND_MESSAGE_(message, QUICKCPPLIB_BIND_MESSAGE_PREFIX("note"), msg)
|
|
//! Have the compiler output a warning
|
|
#define QUICKCPPLIB_WARNING(msg) QUICKCPPLIB_BIND_MESSAGE_(GCC warning, QUICKCPPLIB_BIND_MESSAGE_PREFIX("warning"), msg)
|
|
//! Have the compiler output an error
|
|
#define QUICKCPPLIB_ERROR(msg) QUICKCPPLIB_BIND_MESSAGE_(GCC error, QUICKCPPLIB_BIND_MESSAGE_PREFIX("error"), msg)
|
|
#define QUICKCPPLIB_ANNOTATE_RWLOCK_CREATE(p)
|
|
#define QUICKCPPLIB_ANNOTATE_RWLOCK_DESTROY(p)
|
|
#define QUICKCPPLIB_ANNOTATE_RWLOCK_ACQUIRED(p, s)
|
|
#define QUICKCPPLIB_ANNOTATE_RWLOCK_RELEASED(p, s)
|
|
#define QUICKCPPLIB_ANNOTATE_IGNORE_READS_BEGIN()
|
|
#define QUICKCPPLIB_ANNOTATE_IGNORE_READS_END()
|
|
#define QUICKCPPLIB_ANNOTATE_IGNORE_WRITES_BEGIN()
|
|
#define QUICKCPPLIB_ANNOTATE_IGNORE_WRITES_END()
|
|
#define QUICKCPPLIB_DRD_IGNORE_VAR(x)
|
|
#define QUICKCPPLIB_DRD_STOP_IGNORING_VAR(x)
|
|
#define QUICKCPPLIB_RUNNING_ON_VALGRIND (0)
|
|
#ifndef QUICKCPPLIB_IN_THREAD_SANITIZER
|
|
#if defined(__has_feature)
|
|
#if __has_feature(thread_sanitizer)
|
|
#define QUICKCPPLIB_IN_THREAD_SANITIZER 1
|
|
#endif
|
|
#elif defined(__SANITIZE_THREAD__)
|
|
#define QUICKCPPLIB_IN_THREAD_SANITIZER 1
|
|
#endif
|
|
#endif
|
|
#ifndef QUICKCPPLIB_IN_THREAD_SANITIZER
|
|
#define QUICKCPPLIB_IN_THREAD_SANITIZER 0
|
|
#endif
|
|
#if QUICKCPPLIB_IN_THREAD_SANITIZER
|
|
#define QUICKCPPLIB_DISABLE_THREAD_SANITIZE __attribute__((no_sanitize_thread))
|
|
#else
|
|
#define QUICKCPPLIB_DISABLE_THREAD_SANITIZE
|
|
#endif
|
|
#ifndef QUICKCPPLIB_SMT_PAUSE
|
|
#if !defined(__clang__) && defined(_MSC_VER) && _MSC_VER >= 1310 && (defined(_M_IX86) || defined(_M_X64))
|
|
extern "C" void _mm_pause();
|
|
#pragma intrinsic(_mm_pause)
|
|
#define QUICKCPPLIB_SMT_PAUSE _mm_pause();
|
|
#elif !defined(__c2__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
|
#define QUICKCPPLIB_SMT_PAUSE __asm__ __volatile__("rep; nop" : : : "memory");
|
|
#endif
|
|
#endif
|
|
#ifndef QUICKCPPLIB_FORCEINLINE
|
|
#if defined(_MSC_VER)
|
|
#define QUICKCPPLIB_FORCEINLINE __forceinline
|
|
#elif defined(__GNUC__)
|
|
#define QUICKCPPLIB_FORCEINLINE __attribute__((always_inline))
|
|
#else
|
|
#define QUICKCPPLIB_FORCEINLINE
|
|
#endif
|
|
#endif
|
|
#ifndef QUICKCPPLIB_NOINLINE
|
|
#if defined(_MSC_VER)
|
|
#define QUICKCPPLIB_NOINLINE __declspec(noinline)
|
|
#elif defined(__GNUC__)
|
|
#define QUICKCPPLIB_NOINLINE __attribute__((noinline))
|
|
#else
|
|
#define QUICKCPPLIB_NOINLINE
|
|
#endif
|
|
#endif
|
|
#ifdef __has_cpp_attribute
|
|
#define QUICKCPPLIB_HAS_CPP_ATTRIBUTE(attr) __has_cpp_attribute(attr)
|
|
#else
|
|
#define QUICKCPPLIB_HAS_CPP_ATTRIBUTE(attr) (0)
|
|
#endif
|
|
#if !defined(QUICKCPPLIB_NORETURN)
|
|
#if QUICKCPPLIB_HAS_CPP_ATTRIBUTE(noreturn)
|
|
#define QUICKCPPLIB_NORETURN [[noreturn]]
|
|
#elif defined(_MSC_VER)
|
|
#define QUICKCPPLIB_NORETURN __declspec(noreturn)
|
|
#elif defined(__GNUC__)
|
|
#define QUICKCPPLIB_NORETURN __attribute__((__noreturn__))
|
|
#else
|
|
#define QUICKCPPLIB_NORETURN
|
|
#endif
|
|
#endif
|
|
#ifndef QUICKCPPLIB_NODISCARD
|
|
#if 0 || (_HAS_CXX17 && _MSC_VER >= 1911 /* VS2017.3 */)
|
|
#define QUICKCPPLIB_NODISCARD [[nodiscard]]
|
|
#endif
|
|
#endif
|
|
#ifndef QUICKCPPLIB_NODISCARD
|
|
#if defined(__clang__) && !_HAS_CXX17
|
|
#define QUICKCPPLIB_NODISCARD __attribute__((warn_unused_result))
|
|
#elif QUICKCPPLIB_HAS_CPP_ATTRIBUTE(nodiscard)
|
|
#define QUICKCPPLIB_NODISCARD [[nodiscard]]
|
|
#elif defined(_MSC_VER)
|
|
// _Must_inspect_result_ expands into this
|
|
#define QUICKCPPLIB_NODISCARD __declspec("SAL_name" "(" "\"_Must_inspect_result_\"" "," "\"\"" "," "\"2\"" ")") __declspec("SAL_begin") __declspec("SAL_post") __declspec("SAL_mustInspect") __declspec("SAL_post") __declspec("SAL_checkReturn") __declspec("SAL_end")
|
|
#endif
|
|
#endif
|
|
#ifndef QUICKCPPLIB_NODISCARD
|
|
#define QUICKCPPLIB_NODISCARD
|
|
#endif
|
|
#ifndef QUICKCPPLIB_SYMBOL_VISIBLE
|
|
#if defined(_MSC_VER)
|
|
#define QUICKCPPLIB_SYMBOL_VISIBLE
|
|
#elif defined(__GNUC__)
|
|
#define QUICKCPPLIB_SYMBOL_VISIBLE __attribute__((visibility("default")))
|
|
#else
|
|
#define QUICKCPPLIB_SYMBOL_VISIBLE
|
|
#endif
|
|
#endif
|
|
#ifndef QUICKCPPLIB_SYMBOL_EXPORT
|
|
#if defined(_MSC_VER)
|
|
#define QUICKCPPLIB_SYMBOL_EXPORT __declspec(dllexport)
|
|
#elif defined(__GNUC__)
|
|
#define QUICKCPPLIB_SYMBOL_EXPORT __attribute__((visibility("default")))
|
|
#else
|
|
#define QUICKCPPLIB_SYMBOL_EXPORT
|
|
#endif
|
|
#endif
|
|
#ifndef QUICKCPPLIB_SYMBOL_IMPORT
|
|
#if defined(_MSC_VER)
|
|
#define QUICKCPPLIB_SYMBOL_IMPORT __declspec(dllimport)
|
|
#elif defined(__GNUC__)
|
|
#define QUICKCPPLIB_SYMBOL_IMPORT
|
|
#else
|
|
#define QUICKCPPLIB_SYMBOL_IMPORT
|
|
#endif
|
|
#endif
|
|
#ifndef QUICKCPPLIB_THREAD_LOCAL
|
|
#if _MSC_VER >= 1800
|
|
#define QUICKCPPLIB_THREAD_LOCAL_IS_CXX11 1
|
|
#elif __cplusplus >= 201103
|
|
#if __GNUC__ >= 5 && !defined(__clang__)
|
|
#define QUICKCPPLIB_THREAD_LOCAL_IS_CXX11 1
|
|
#elif defined(__has_feature)
|
|
#if __has_feature(cxx_thread_local)
|
|
#define QUICKCPPLIB_THREAD_LOCAL_IS_CXX11 1
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#ifdef QUICKCPPLIB_THREAD_LOCAL_IS_CXX11
|
|
#define QUICKCPPLIB_THREAD_LOCAL thread_local
|
|
#endif
|
|
#ifndef QUICKCPPLIB_THREAD_LOCAL
|
|
#if defined(_MSC_VER)
|
|
#define QUICKCPPLIB_THREAD_LOCAL __declspec(thread)
|
|
#elif defined(__GNUC__)
|
|
#define QUICKCPPLIB_THREAD_LOCAL __thread
|
|
#else
|
|
#error Unknown compiler, cannot set QUICKCPPLIB_THREAD_LOCAL
|
|
#endif
|
|
#endif
|
|
#endif
|
|
/* MSVC capable preprocessor macro overloading
|
|
(C) 2014-2017 Niall Douglas <http://www.nedproductions.biz/> (3 commits)
|
|
File Created: Aug 2014
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef QUICKCPPLIB_PREPROCESSOR_MACRO_OVERLOAD_H
|
|
#define QUICKCPPLIB_PREPROCESSOR_MACRO_OVERLOAD_H
|
|
#define QUICKCPPLIB_GLUE(x, y) x y
|
|
#define QUICKCPPLIB_RETURN_ARG_COUNT(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, count, ...) count
|
|
#define QUICKCPPLIB_EXPAND_ARGS(args) QUICKCPPLIB_RETURN_ARG_COUNT args
|
|
#define QUICKCPPLIB_COUNT_ARGS_MAX8(...) QUICKCPPLIB_EXPAND_ARGS((__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0))
|
|
#define QUICKCPPLIB_OVERLOAD_MACRO2(name, count) name##count
|
|
#define QUICKCPPLIB_OVERLOAD_MACRO1(name, count) QUICKCPPLIB_OVERLOAD_MACRO2(name, count)
|
|
#define QUICKCPPLIB_OVERLOAD_MACRO(name, count) QUICKCPPLIB_OVERLOAD_MACRO1(name, count)
|
|
#define QUICKCPPLIB_CALL_OVERLOAD(name, ...) QUICKCPPLIB_GLUE(QUICKCPPLIB_OVERLOAD_MACRO(name, QUICKCPPLIB_COUNT_ARGS_MAX8(__VA_ARGS__)), (__VA_ARGS__))
|
|
#define QUICKCPPLIB_GLUE_(x, y) x y
|
|
#define QUICKCPPLIB_RETURN_ARG_COUNT_(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, count, ...) count
|
|
#define QUICKCPPLIB_EXPAND_ARGS_(args) QUICKCPPLIB_RETURN_ARG_COUNT_ args
|
|
#define QUICKCPPLIB_COUNT_ARGS_MAX8_(...) QUICKCPPLIB_EXPAND_ARGS_((__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0))
|
|
#define QUICKCPPLIB_OVERLOAD_MACRO2_(name, count) name##count
|
|
#define QUICKCPPLIB_OVERLOAD_MACRO1_(name, count) QUICKCPPLIB_OVERLOAD_MACRO2_(name, count)
|
|
#define QUICKCPPLIB_OVERLOAD_MACRO_(name, count) QUICKCPPLIB_OVERLOAD_MACRO1_(name, count)
|
|
#define QUICKCPPLIB_CALL_OVERLOAD_(name, ...) QUICKCPPLIB_GLUE_(QUICKCPPLIB_OVERLOAD_MACRO_(name, QUICKCPPLIB_COUNT_ARGS_MAX8_(__VA_ARGS__)), (__VA_ARGS__))
|
|
#endif
|
|
#if defined(__cpp_concepts) && !defined(QUICKCPPLIB_DISABLE_CONCEPTS_SUPPORT)
|
|
#define QUICKCPPLIB_TREQUIRES_EXPAND8(a, b, c, d, e, f, g, h) a &&QUICKCPPLIB_TREQUIRES_EXPAND7(b, c, d, e, f, g, h)
|
|
#define QUICKCPPLIB_TREQUIRES_EXPAND7(a, b, c, d, e, f, g) a &&QUICKCPPLIB_TREQUIRES_EXPAND6(b, c, d, e, f, g)
|
|
#define QUICKCPPLIB_TREQUIRES_EXPAND6(a, b, c, d, e, f) a &&QUICKCPPLIB_TREQUIRES_EXPAND5(b, c, d, e, f)
|
|
#define QUICKCPPLIB_TREQUIRES_EXPAND5(a, b, c, d, e) a &&QUICKCPPLIB_TREQUIRES_EXPAND4(b, c, d, e)
|
|
#define QUICKCPPLIB_TREQUIRES_EXPAND4(a, b, c, d) a &&QUICKCPPLIB_TREQUIRES_EXPAND3(b, c, d)
|
|
#define QUICKCPPLIB_TREQUIRES_EXPAND3(a, b, c) a &&QUICKCPPLIB_TREQUIRES_EXPAND2(b, c)
|
|
#define QUICKCPPLIB_TREQUIRES_EXPAND2(a, b) a &&QUICKCPPLIB_TREQUIRES_EXPAND1(b)
|
|
#define QUICKCPPLIB_TREQUIRES_EXPAND1(a) a
|
|
//! Expands into a && b && c && ...
|
|
#define QUICKCPPLIB_TREQUIRES(...) requires QUICKCPPLIB_CALL_OVERLOAD(QUICKCPPLIB_TREQUIRES_EXPAND, __VA_ARGS__)
|
|
#define QUICKCPPLIB_TEMPLATE(...) template <__VA_ARGS__>
|
|
#define QUICKCPPLIB_TEXPR(...) requires { (__VA_ARGS__); }
|
|
#define QUICKCPPLIB_TPRED(...) (__VA_ARGS__)
|
|
#if !defined(_MSC_VER) || _MSC_FULL_VER >= 192400000 // VS 2019 16.3 is broken here
|
|
#define QUICKCPPLIB_REQUIRES(...) requires(__VA_ARGS__)
|
|
#else
|
|
#define QUICKCPPLIB_REQUIRES(...)
|
|
#endif
|
|
#else
|
|
#define QUICKCPPLIB_TEMPLATE(...) template <__VA_ARGS__
|
|
#define QUICKCPPLIB_TREQUIRES(...) , __VA_ARGS__ >
|
|
#define QUICKCPPLIB_TEXPR(...) typename = decltype(__VA_ARGS__)
|
|
#ifdef _MSC_VER
|
|
// MSVC gives an error if every specialisation of a template is always ill-formed, so
|
|
// the more powerful SFINAE form below causes pukeage :(
|
|
#define QUICKCPPLIB_TPRED(...) typename = typename std::enable_if<(__VA_ARGS__)>::type
|
|
#else
|
|
#define QUICKCPPLIB_TPRED(...) typename std::enable_if<(__VA_ARGS__), bool>::type = true
|
|
#endif
|
|
#define QUICKCPPLIB_REQUIRES(...)
|
|
#endif
|
|
#endif
|
|
#ifndef __cpp_variadic_templates
|
|
#error Outcome needs variadic template support in the compiler
|
|
#endif
|
|
#if __cpp_constexpr < 201304 && _MSC_FULL_VER < 191100000
|
|
#error Outcome needs constexpr (C++ 14) support in the compiler
|
|
#endif
|
|
#ifndef __cpp_variable_templates
|
|
#error Outcome needs variable template support in the compiler
|
|
#endif
|
|
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 6
|
|
#error Due to a bug in nested template variables parsing, Outcome does not work on GCCs earlier than v6.
|
|
#endif
|
|
#ifndef OUTCOME_SYMBOL_VISIBLE
|
|
#define OUTCOME_SYMBOL_VISIBLE QUICKCPPLIB_SYMBOL_VISIBLE
|
|
#endif
|
|
#ifndef OUTCOME_FORCEINLINE
|
|
#define OUTCOME_FORCEINLINE QUICKCPPLIB_FORCEINLINE
|
|
#endif
|
|
#ifndef OUTCOME_NODISCARD
|
|
#define OUTCOME_NODISCARD QUICKCPPLIB_NODISCARD
|
|
#endif
|
|
#ifndef OUTCOME_THREAD_LOCAL
|
|
#define OUTCOME_THREAD_LOCAL QUICKCPPLIB_THREAD_LOCAL
|
|
#endif
|
|
#ifndef OUTCOME_TEMPLATE
|
|
#define OUTCOME_TEMPLATE(...) QUICKCPPLIB_TEMPLATE(__VA_ARGS__)
|
|
#endif
|
|
#ifndef OUTCOME_TREQUIRES
|
|
#define OUTCOME_TREQUIRES(...) QUICKCPPLIB_TREQUIRES(__VA_ARGS__)
|
|
#endif
|
|
#ifndef OUTCOME_TEXPR
|
|
#define OUTCOME_TEXPR(...) QUICKCPPLIB_TEXPR(__VA_ARGS__)
|
|
#endif
|
|
#ifndef OUTCOME_TPRED
|
|
#define OUTCOME_TPRED(...) QUICKCPPLIB_TPRED(__VA_ARGS__)
|
|
#endif
|
|
#ifndef OUTCOME_REQUIRES
|
|
#define OUTCOME_REQUIRES(...) QUICKCPPLIB_REQUIRES(__VA_ARGS__)
|
|
#endif
|
|
/* Convenience macros for importing local namespace binds
|
|
(C) 2014-2017 Niall Douglas <http://www.nedproductions.biz/> (9 commits)
|
|
File Created: Aug 2014
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef QUICKCPPLIB_BIND_IMPORT_HPP
|
|
#define QUICKCPPLIB_BIND_IMPORT_HPP
|
|
/* 2014-10-9 ned: I lost today figuring out the below. I really hate the C preprocessor now.
|
|
*
|
|
* Anyway, infinity = 8. It's easy to expand below if needed.
|
|
*/
|
|
#define QUICKCPPLIB_BIND_STRINGIZE(a) #a
|
|
#define QUICKCPPLIB_BIND_STRINGIZE2(a) QUICKCPPLIB_BIND_STRINGIZE(a)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_VERSION8(a, b, c, d, e, f, g, h) a##_##b##_##c##_##d##_##e##_##f##_##g##_##h
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_VERSION7(a, b, c, d, e, f, g) a##_##b##_##c##_##d##_##e##_##f##_##g
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_VERSION6(a, b, c, d, e, f) a##_##b##_##c##_##d##_##e##_##f
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_VERSION5(a, b, c, d, e) a##_##b##_##c##_##d##_##e
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_VERSION4(a, b, c, d) a##_##b##_##c##_##d
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_VERSION3(a, b, c) a##_##b##_##c
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_VERSION2(a, b) a##_##b
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_VERSION1(a) a
|
|
//! Concatenates each parameter with _
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_VERSION(...) QUICKCPPLIB_CALL_OVERLOAD(QUICKCPPLIB_BIND_NAMESPACE_VERSION, __VA_ARGS__)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_SELECT_2(name, modifier) name
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_SELECT2(name, modifier) ::name
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_SELECT_1(name) name
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_SELECT1(name) ::name
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_SELECT_(...) QUICKCPPLIB_CALL_OVERLOAD_(QUICKCPPLIB_BIND_NAMESPACE_SELECT_, __VA_ARGS__)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_SELECT(...) QUICKCPPLIB_CALL_OVERLOAD_(QUICKCPPLIB_BIND_NAMESPACE_SELECT, __VA_ARGS__)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPAND8(a, b, c, d, e, f, g, h) QUICKCPPLIB_BIND_NAMESPACE_SELECT_ a QUICKCPPLIB_BIND_NAMESPACE_SELECT b QUICKCPPLIB_BIND_NAMESPACE_SELECT c QUICKCPPLIB_BIND_NAMESPACE_SELECT d QUICKCPPLIB_BIND_NAMESPACE_SELECT e QUICKCPPLIB_BIND_NAMESPACE_SELECT f QUICKCPPLIB_BIND_NAMESPACE_SELECT g QUICKCPPLIB_BIND_NAMESPACE_SELECT h
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPAND7(a, b, c, d, e, f, g) QUICKCPPLIB_BIND_NAMESPACE_SELECT_ a QUICKCPPLIB_BIND_NAMESPACE_SELECT b QUICKCPPLIB_BIND_NAMESPACE_SELECT c QUICKCPPLIB_BIND_NAMESPACE_SELECT d QUICKCPPLIB_BIND_NAMESPACE_SELECT e QUICKCPPLIB_BIND_NAMESPACE_SELECT f QUICKCPPLIB_BIND_NAMESPACE_SELECT g
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPAND6(a, b, c, d, e, f) QUICKCPPLIB_BIND_NAMESPACE_SELECT_ a QUICKCPPLIB_BIND_NAMESPACE_SELECT b QUICKCPPLIB_BIND_NAMESPACE_SELECT c QUICKCPPLIB_BIND_NAMESPACE_SELECT d QUICKCPPLIB_BIND_NAMESPACE_SELECT e QUICKCPPLIB_BIND_NAMESPACE_SELECT f
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPAND5(a, b, c, d, e) QUICKCPPLIB_BIND_NAMESPACE_SELECT_ a QUICKCPPLIB_BIND_NAMESPACE_SELECT b QUICKCPPLIB_BIND_NAMESPACE_SELECT c QUICKCPPLIB_BIND_NAMESPACE_SELECT d QUICKCPPLIB_BIND_NAMESPACE_SELECT e
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPAND4(a, b, c, d) QUICKCPPLIB_BIND_NAMESPACE_SELECT_ a QUICKCPPLIB_BIND_NAMESPACE_SELECT b QUICKCPPLIB_BIND_NAMESPACE_SELECT c QUICKCPPLIB_BIND_NAMESPACE_SELECT d
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPAND3(a, b, c) QUICKCPPLIB_BIND_NAMESPACE_SELECT_ a QUICKCPPLIB_BIND_NAMESPACE_SELECT b QUICKCPPLIB_BIND_NAMESPACE_SELECT c
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPAND2(a, b) QUICKCPPLIB_BIND_NAMESPACE_SELECT_ a QUICKCPPLIB_BIND_NAMESPACE_SELECT b
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPAND1(a) QUICKCPPLIB_BIND_NAMESPACE_SELECT_ a
|
|
//! Expands into a::b::c:: ...
|
|
#define QUICKCPPLIB_BIND_NAMESPACE(...) QUICKCPPLIB_CALL_OVERLOAD(QUICKCPPLIB_BIND_NAMESPACE_EXPAND, __VA_ARGS__)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_BEGIN_NAMESPACE_SELECT2(name, modifier) modifier namespace name {
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_BEGIN_NAMESPACE_SELECT1(name) namespace name {
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_BEGIN_NAMESPACE_SELECT(...) QUICKCPPLIB_CALL_OVERLOAD_(QUICKCPPLIB_BIND_NAMESPACE_BEGIN_NAMESPACE_SELECT, __VA_ARGS__)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND8(a, b, c, d, e, f, g, h) QUICKCPPLIB_BIND_NAMESPACE_BEGIN_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND7(b, c, d, e, f, g, h)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND7(a, b, c, d, e, f, g) QUICKCPPLIB_BIND_NAMESPACE_BEGIN_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND6(b, c, d, e, f, g)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND6(a, b, c, d, e, f) QUICKCPPLIB_BIND_NAMESPACE_BEGIN_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND5(b, c, d, e, f)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND5(a, b, c, d, e) QUICKCPPLIB_BIND_NAMESPACE_BEGIN_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND4(b, c, d, e)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND4(a, b, c, d) QUICKCPPLIB_BIND_NAMESPACE_BEGIN_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND3(b, c, d)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND3(a, b, c) QUICKCPPLIB_BIND_NAMESPACE_BEGIN_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND2(b, c)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND2(a, b) QUICKCPPLIB_BIND_NAMESPACE_BEGIN_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND1(b)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND1(a) QUICKCPPLIB_BIND_NAMESPACE_BEGIN_NAMESPACE_SELECT a
|
|
//! Expands into namespace a { namespace b { namespace c ...
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_BEGIN(...) QUICKCPPLIB_CALL_OVERLOAD(QUICKCPPLIB_BIND_NAMESPACE_BEGIN_EXPAND, __VA_ARGS__)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_NAMESPACE_SELECT2(name, modifier) modifier namespace name {
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_NAMESPACE_SELECT1(name) export namespace name {
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_NAMESPACE_SELECT(...) QUICKCPPLIB_CALL_OVERLOAD_(QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_NAMESPACE_SELECT, __VA_ARGS__)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND8(a, b, c, d, e, f, g, h) QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND7(b, c, d, e, f, g, h)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND7(a, b, c, d, e, f, g) QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND6(b, c, d, e, f, g)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND6(a, b, c, d, e, f) QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND5(b, c, d, e, f)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND5(a, b, c, d, e) QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND4(b, c, d, e)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND4(a, b, c, d) QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND3(b, c, d)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND3(a, b, c) QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND2(b, c)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND2(a, b) QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND1(b)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND1(a) QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_NAMESPACE_SELECT a
|
|
//! Expands into export namespace a { namespace b { namespace c ...
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN(...) QUICKCPPLIB_CALL_OVERLOAD(QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN_EXPAND, __VA_ARGS__)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_END_NAMESPACE_SELECT2(name, modifier) }
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_END_NAMESPACE_SELECT1(name) }
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_END_NAMESPACE_SELECT(...) QUICKCPPLIB_CALL_OVERLOAD_(QUICKCPPLIB_BIND_NAMESPACE_END_NAMESPACE_SELECT, __VA_ARGS__)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND8(a, b, c, d, e, f, g, h) QUICKCPPLIB_BIND_NAMESPACE_END_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND7(b, c, d, e, f, g, h)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND7(a, b, c, d, e, f, g) QUICKCPPLIB_BIND_NAMESPACE_END_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND6(b, c, d, e, f, g)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND6(a, b, c, d, e, f) QUICKCPPLIB_BIND_NAMESPACE_END_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND5(b, c, d, e, f)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND5(a, b, c, d, e) QUICKCPPLIB_BIND_NAMESPACE_END_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND4(b, c, d, e)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND4(a, b, c, d) QUICKCPPLIB_BIND_NAMESPACE_END_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND3(b, c, d)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND3(a, b, c) QUICKCPPLIB_BIND_NAMESPACE_END_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND2(b, c)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND2(a, b) QUICKCPPLIB_BIND_NAMESPACE_END_NAMESPACE_SELECT a QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND1(b)
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND1(a) QUICKCPPLIB_BIND_NAMESPACE_END_NAMESPACE_SELECT a
|
|
//! Expands into } } ...
|
|
#define QUICKCPPLIB_BIND_NAMESPACE_END(...) QUICKCPPLIB_CALL_OVERLOAD(QUICKCPPLIB_BIND_NAMESPACE_END_EXPAND, __VA_ARGS__)
|
|
//! Expands into a static const char string array used to mark BindLib compatible namespaces
|
|
#define QUICKCPPLIB_BIND_DECLARE(decl, desc) static const char *quickcpplib_out[] = {#decl, desc};
|
|
#endif
|
|
#ifndef OUTCOME_ENABLE_LEGACY_SUPPORT_FOR
|
|
#define OUTCOME_ENABLE_LEGACY_SUPPORT_FOR 220 // the v2.2 Outcome release
|
|
#endif
|
|
#if defined(OUTCOME_UNSTABLE_VERSION)
|
|
/* UPDATED BY SCRIPT
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (225 commits)
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
// Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time
|
|
#define OUTCOME_PREVIOUS_COMMIT_REF e261cebddfd2d5d1229dbf66c6dc0091a9f2a6f8
|
|
#define OUTCOME_PREVIOUS_COMMIT_DATE "2021-10-26 10:23:56 +00:00"
|
|
#define OUTCOME_PREVIOUS_COMMIT_UNIQUE e261cebd
|
|
#define OUTCOME_V2 (QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2, OUTCOME_PREVIOUS_COMMIT_UNIQUE))
|
|
#ifdef _DEBUG
|
|
#define OUTCOME_V2_CXX_MODULE_NAME QUICKCPPLIB_BIND_NAMESPACE((QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2d, OUTCOME_PREVIOUS_COMMIT_UNIQUE)))
|
|
#else
|
|
#define OUTCOME_V2_CXX_MODULE_NAME QUICKCPPLIB_BIND_NAMESPACE((QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2, OUTCOME_PREVIOUS_COMMIT_UNIQUE)))
|
|
#endif
|
|
#else
|
|
#define OUTCOME_V2 (QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2))
|
|
#ifdef _DEBUG
|
|
#define OUTCOME_V2_CXX_MODULE_NAME QUICKCPPLIB_BIND_NAMESPACE((QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2d)))
|
|
#else
|
|
#define OUTCOME_V2_CXX_MODULE_NAME QUICKCPPLIB_BIND_NAMESPACE((QUICKCPPLIB_BIND_NAMESPACE_VERSION(outcome_v2)))
|
|
#endif
|
|
#endif
|
|
#if defined(GENERATING_OUTCOME_MODULE_INTERFACE)
|
|
#define OUTCOME_V2_NAMESPACE QUICKCPPLIB_BIND_NAMESPACE(OUTCOME_V2)
|
|
#define OUTCOME_V2_NAMESPACE_BEGIN QUICKCPPLIB_BIND_NAMESPACE_BEGIN(OUTCOME_V2)
|
|
#define OUTCOME_V2_NAMESPACE_EXPORT_BEGIN QUICKCPPLIB_BIND_NAMESPACE_EXPORT_BEGIN(OUTCOME_V2)
|
|
#define OUTCOME_V2_NAMESPACE_END QUICKCPPLIB_BIND_NAMESPACE_END(OUTCOME_V2)
|
|
#else
|
|
#define OUTCOME_V2_NAMESPACE QUICKCPPLIB_BIND_NAMESPACE(OUTCOME_V2)
|
|
#define OUTCOME_V2_NAMESPACE_BEGIN QUICKCPPLIB_BIND_NAMESPACE_BEGIN(OUTCOME_V2)
|
|
#define OUTCOME_V2_NAMESPACE_EXPORT_BEGIN QUICKCPPLIB_BIND_NAMESPACE_BEGIN(OUTCOME_V2)
|
|
#define OUTCOME_V2_NAMESPACE_END QUICKCPPLIB_BIND_NAMESPACE_END(OUTCOME_V2)
|
|
#endif
|
|
#include <cstdint> // for uint32_t etc
|
|
#include <initializer_list>
|
|
#include <iosfwd> // for future serialisation
|
|
#include <new> // for placement in moves etc
|
|
#include <type_traits>
|
|
#ifndef OUTCOME_USE_STD_IN_PLACE_TYPE
|
|
#if defined(_MSC_VER) && _HAS_CXX17
|
|
#define OUTCOME_USE_STD_IN_PLACE_TYPE 1 // MSVC always has std::in_place_type
|
|
#elif __cplusplus >= 201700
|
|
// libstdc++ before GCC 6 doesn't have it, despite claiming C++ 17 support
|
|
#ifdef __has_include
|
|
#if !__has_include(<variant>)
|
|
#define OUTCOME_USE_STD_IN_PLACE_TYPE 0 // must have it if <variant> is present
|
|
#endif
|
|
#endif
|
|
#ifndef OUTCOME_USE_STD_IN_PLACE_TYPE
|
|
#define OUTCOME_USE_STD_IN_PLACE_TYPE 1
|
|
#endif
|
|
#else
|
|
#define OUTCOME_USE_STD_IN_PLACE_TYPE 0
|
|
#endif
|
|
#endif
|
|
#if OUTCOME_USE_STD_IN_PLACE_TYPE
|
|
#include <utility> // for in_place_type_t
|
|
OUTCOME_V2_NAMESPACE_BEGIN
|
|
template <class T> using in_place_type_t = std::in_place_type_t<T>;
|
|
using std::in_place_type;
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#else
|
|
OUTCOME_V2_NAMESPACE_BEGIN
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition template <class T> in_place_type_t. Potential doc page: `in_place_type_t<T>`
|
|
*/
|
|
template <class T> struct in_place_type_t
|
|
{
|
|
explicit in_place_type_t() = default;
|
|
};
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T> constexpr in_place_type_t<T> in_place_type{};
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
#ifndef OUTCOME_TRIVIAL_ABI
|
|
#if 0 || __clang_major__ >= 7
|
|
//! Defined to be `[[clang::trivial_abi]]` when on a new enough clang compiler. Usually automatic, can be overriden.
|
|
#define OUTCOME_TRIVIAL_ABI [[clang::trivial_abi]]
|
|
#else
|
|
#define OUTCOME_TRIVIAL_ABI
|
|
#endif
|
|
#endif
|
|
OUTCOME_V2_NAMESPACE_BEGIN
|
|
namespace detail
|
|
{
|
|
// Test if type is an in_place_type_t
|
|
template <class T> struct is_in_place_type_t
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
template <class U> struct is_in_place_type_t<in_place_type_t<U>>
|
|
{
|
|
static constexpr bool value = true;
|
|
};
|
|
// Replace void with constructible void_type
|
|
struct empty_type
|
|
{
|
|
};
|
|
struct void_type
|
|
{
|
|
// We always compare true to another instance of me
|
|
constexpr bool operator==(void_type /*unused*/) const noexcept { return true; }
|
|
constexpr bool operator!=(void_type /*unused*/) const noexcept { return false; }
|
|
};
|
|
template <class T> using devoid = std::conditional_t<std::is_void<T>::value, void_type, T>;
|
|
template <class Output, class Input> using rebind_type5 = Output;
|
|
template <class Output, class Input>
|
|
using rebind_type4 = std::conditional_t< //
|
|
std::is_volatile<Input>::value, //
|
|
std::add_volatile_t<rebind_type5<Output, std::remove_volatile_t<Input>>>, //
|
|
rebind_type5<Output, Input>>;
|
|
template <class Output, class Input>
|
|
using rebind_type3 = std::conditional_t< //
|
|
std::is_const<Input>::value, //
|
|
std::add_const_t<rebind_type4<Output, std::remove_const_t<Input>>>, //
|
|
rebind_type4<Output, Input>>;
|
|
template <class Output, class Input>
|
|
using rebind_type2 = std::conditional_t< //
|
|
std::is_lvalue_reference<Input>::value, //
|
|
std::add_lvalue_reference_t<rebind_type3<Output, std::remove_reference_t<Input>>>, //
|
|
rebind_type3<Output, Input>>;
|
|
template <class Output, class Input>
|
|
using rebind_type = std::conditional_t< //
|
|
std::is_rvalue_reference<Input>::value, //
|
|
std::add_rvalue_reference_t<rebind_type2<Output, std::remove_reference_t<Input>>>, //
|
|
rebind_type2<Output, Input>>;
|
|
// static_assert(std::is_same_v<rebind_type<int, volatile const double &&>, volatile const int &&>, "");
|
|
/* True if type is the same or constructible. Works around a bug where clang + libstdc++
|
|
pukes on std::is_constructible<filesystem::path, void> (this bug is fixed upstream).
|
|
*/
|
|
template <class T, class U> struct _is_explicitly_constructible
|
|
{
|
|
static constexpr bool value = std::is_constructible<T, U>::value;
|
|
};
|
|
template <class T> struct _is_explicitly_constructible<T, void>
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
template <> struct _is_explicitly_constructible<void, void>
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
template <class T, class U> static constexpr bool is_explicitly_constructible = _is_explicitly_constructible<T, U>::value;
|
|
template <class T, class U> struct _is_implicitly_constructible
|
|
{
|
|
static constexpr bool value = std::is_convertible<U, T>::value;
|
|
};
|
|
template <class T> struct _is_implicitly_constructible<T, void>
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
template <> struct _is_implicitly_constructible<void, void>
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
template <class T, class U> static constexpr bool is_implicitly_constructible = _is_implicitly_constructible<T, U>::value;
|
|
template <class T, class... Args> struct _is_nothrow_constructible
|
|
{
|
|
static constexpr bool value = std::is_nothrow_constructible<T, Args...>::value;
|
|
};
|
|
template <class T> struct _is_nothrow_constructible<T, void>
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
template <> struct _is_nothrow_constructible<void, void>
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
template <class T, class... Args> static constexpr bool is_nothrow_constructible = _is_nothrow_constructible<T, Args...>::value;
|
|
template <class T, class... Args> struct _is_constructible
|
|
{
|
|
static constexpr bool value = std::is_constructible<T, Args...>::value;
|
|
};
|
|
template <class T> struct _is_constructible<T, void>
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
template <> struct _is_constructible<void, void>
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
template <class T, class... Args> static constexpr bool is_constructible = _is_constructible<T, Args...>::value;
|
|
#ifndef OUTCOME_USE_STD_IS_NOTHROW_SWAPPABLE
|
|
#if defined(_MSC_VER) && _HAS_CXX17
|
|
#define OUTCOME_USE_STD_IS_NOTHROW_SWAPPABLE 1 // MSVC always has std::is_nothrow_swappable
|
|
#elif __cplusplus >= 201700
|
|
// libstdc++ before GCC 6 doesn't have it, despite claiming C++ 17 support
|
|
#ifdef __has_include
|
|
#if !__has_include(<variant>)
|
|
#define OUTCOME_USE_STD_IS_NOTHROW_SWAPPABLE 0
|
|
#endif
|
|
#endif
|
|
#ifndef OUTCOME_USE_STD_IS_NOTHROW_SWAPPABLE
|
|
#define OUTCOME_USE_STD_IS_NOTHROW_SWAPPABLE 1
|
|
#endif
|
|
#else
|
|
#define OUTCOME_USE_STD_IS_NOTHROW_SWAPPABLE 0
|
|
#endif
|
|
#endif
|
|
// True if type is nothrow swappable
|
|
#if !0 && OUTCOME_USE_STD_IS_NOTHROW_SWAPPABLE
|
|
template <class T> using is_nothrow_swappable = std::is_nothrow_swappable<T>;
|
|
#else
|
|
template <class T> struct is_nothrow_swappable
|
|
{
|
|
static constexpr bool value = std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_assignable<T>::value;
|
|
};
|
|
#endif
|
|
} // namespace detail
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#ifndef OUTCOME_THROW_EXCEPTION
|
|
#ifdef __cpp_exceptions
|
|
#define OUTCOME_THROW_EXCEPTION(expr) throw expr
|
|
#else
|
|
#ifdef __ANDROID__
|
|
#define OUTCOME_DISABLE_EXECINFO
|
|
#endif
|
|
#ifndef OUTCOME_DISABLE_EXECINFO
|
|
#ifdef _WIN32
|
|
/* Implements backtrace() et al from glibc on win64
|
|
(C) 2016-2017 Niall Douglas <http://www.nedproductions.biz/> (4 commits)
|
|
File Created: Mar 2016
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef BOOST_BINDLIB_EXECINFO_WIN64_H
|
|
#define BOOST_BINDLIB_EXECINFO_WIN64_H
|
|
#ifndef _WIN32
|
|
#error Can only be included on Windows
|
|
#endif
|
|
#include <sal.h>
|
|
#include <stddef.h>
|
|
#ifdef QUICKCPPLIB_EXPORTS
|
|
#define EXECINFO_DECL extern __declspec(dllexport)
|
|
#else
|
|
#if defined(__cplusplus) && (!defined(QUICKCPPLIB_HEADERS_ONLY) || QUICKCPPLIB_HEADERS_ONLY == 1) && !0
|
|
#define EXECINFO_DECL inline
|
|
#elif defined(QUICKCPPLIB_DYN_LINK) && !defined(QUICKCPPLIB_STATIC_LINK)
|
|
#define EXECINFO_DECL extern __declspec(dllimport)
|
|
#else
|
|
#define EXECINFO_DECL extern
|
|
#endif
|
|
#endif
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
//! Fill the array of void * at bt with up to len entries, returning entries filled.
|
|
EXECINFO_DECL _Check_return_ size_t backtrace(_Out_writes_(len) void **bt, _In_ size_t len);
|
|
//! Returns a malloced block of string representations of the input backtrace.
|
|
EXECINFO_DECL _Check_return_ _Ret_writes_maybenull_(len) char **backtrace_symbols(_In_reads_(len) void *const *bt, _In_ size_t len);
|
|
// extern void backtrace_symbols_fd(void *const *bt, size_t len, int fd);
|
|
#ifdef __cplusplus
|
|
}
|
|
#if (!defined(QUICKCPPLIB_HEADERS_ONLY) || QUICKCPPLIB_HEADERS_ONLY == 1) && !0
|
|
#define QUICKCPPLIB_INCLUDED_BY_HEADER 1
|
|
/* Implements backtrace() et al from glibc on win64
|
|
(C) 2016-2017 Niall Douglas <http://www.nedproductions.biz/> (14 commits)
|
|
File Created: Mar 2016
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
/* Implements backtrace() et al from glibc on win64
|
|
(C) 2016-2017 Niall Douglas <http://www.nedproductions.biz/> (4 commits)
|
|
File Created: Mar 2016
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#include <atomic>
|
|
#include <stdlib.h> // for abort
|
|
#include <string.h>
|
|
// To avoid including windows.h, this source has been macro expanded and win32 function shimmed for C++ only
|
|
#if defined(__cplusplus) && !defined(__clang__)
|
|
namespace win32
|
|
{
|
|
extern _Ret_maybenull_ void *__stdcall LoadLibraryA(_In_ const char *lpLibFileName);
|
|
typedef int(__stdcall *GetProcAddress_returntype)();
|
|
extern GetProcAddress_returntype __stdcall GetProcAddress(_In_ void *hModule, _In_ const char *lpProcName);
|
|
extern _Success_(return != 0) unsigned short __stdcall RtlCaptureStackBackTrace(_In_ unsigned long FramesToSkip, _In_ unsigned long FramesToCapture,
|
|
_Out_writes_to_(FramesToCapture, return ) void **BackTrace,
|
|
_Out_opt_ unsigned long *BackTraceHash);
|
|
extern _Success_(return != 0)
|
|
_When_((cchWideChar == -1) && (cbMultiByte != 0),
|
|
_Post_equal_to_(_String_length_(lpMultiByteStr) +
|
|
1)) int __stdcall WideCharToMultiByte(_In_ unsigned int CodePage, _In_ unsigned long dwFlags, const wchar_t *lpWideCharStr,
|
|
_In_ int cchWideChar, _Out_writes_bytes_to_opt_(cbMultiByte, return ) char *lpMultiByteStr,
|
|
_In_ int cbMultiByte, _In_opt_ const char *lpDefaultChar, _Out_opt_ int *lpUsedDefaultChar);
|
|
#pragma comment(lib, "kernel32.lib")
|
|
#if (defined(__x86_64__) || defined(_M_X64)) || (defined(__aarch64__) || defined(_M_ARM64))
|
|
#pragma comment(linker, "/alternatename:?LoadLibraryA@win32@@YAPEAXPEBD@Z=LoadLibraryA")
|
|
#pragma comment(linker, "/alternatename:?GetProcAddress@win32@@YAP6AHXZPEAXPEBD@Z=GetProcAddress")
|
|
#pragma comment(linker, "/alternatename:?RtlCaptureStackBackTrace@win32@@YAGKKPEAPEAXPEAK@Z=RtlCaptureStackBackTrace")
|
|
#pragma comment(linker, "/alternatename:?WideCharToMultiByte@win32@@YAHIKPEB_WHPEADHPEBDPEAH@Z=WideCharToMultiByte")
|
|
#elif defined(__x86__) || defined(_M_IX86) || defined(__i386__)
|
|
#pragma comment(linker, "/alternatename:?LoadLibraryA@win32@@YGPAXPBD@Z=__imp__LoadLibraryA@4")
|
|
#pragma comment(linker, "/alternatename:?GetProcAddress@win32@@YGP6GHXZPAXPBD@Z=__imp__GetProcAddress@8")
|
|
#pragma comment(linker, "/alternatename:?RtlCaptureStackBackTrace@win32@@YGGKKPAPAXPAK@Z=__imp__RtlCaptureStackBackTrace@16")
|
|
#pragma comment(linker, "/alternatename:?WideCharToMultiByte@win32@@YGHIKPB_WHPADHPBDPAH@Z=__imp__WideCharToMultiByte@32")
|
|
#elif defined(__arm__) || defined(_M_ARM)
|
|
#pragma comment(linker, "/alternatename:?LoadLibraryA@win32@@YAPAXPBD@Z=LoadLibraryA")
|
|
#pragma comment(linker, "/alternatename:?GetProcAddress@win32@@YAP6AHXZPAXPBD@Z=GetProcAddress")
|
|
#pragma comment(linker, "/alternatename:?RtlCaptureStackBackTrace@win32@@YAGKKPAPAXPAK@Z=RtlCaptureStackBackTrace")
|
|
#pragma comment(linker, "/alternatename:?WideCharToMultiByte@win32@@YAHIKPB_WHPADHPBDPAH@Z=WideCharToMultiByte")
|
|
#else
|
|
#error Unknown architecture
|
|
#endif
|
|
} // namespace win32
|
|
#else
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#endif
|
|
#ifndef NOMINMAX
|
|
#define NOMINMAX
|
|
#endif
|
|
#include <Windows.h>
|
|
#endif
|
|
#ifdef __cplusplus
|
|
namespace
|
|
{
|
|
#endif
|
|
typedef struct _IMAGEHLP_LINE64
|
|
{
|
|
unsigned long SizeOfStruct;
|
|
void *Key;
|
|
unsigned long LineNumber;
|
|
wchar_t *FileName;
|
|
unsigned long long int Address;
|
|
} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
|
|
typedef int(__stdcall *SymInitialize_t)(_In_ void *hProcess, _In_opt_ const wchar_t *UserSearchPath, _In_ int fInvadeProcess);
|
|
typedef int(__stdcall *SymGetLineFromAddr64_t)(_In_ void *hProcess, _In_ unsigned long long int dwAddr, _Out_ unsigned long *pdwDisplacement,
|
|
_Out_ PIMAGEHLP_LINE64 Line);
|
|
static std::atomic<unsigned> dbghelp_init_lock;
|
|
#if defined(__cplusplus) && !defined(__clang__)
|
|
static void *dbghelp;
|
|
#else
|
|
static HMODULE dbghelp;
|
|
#endif
|
|
static SymInitialize_t SymInitialize;
|
|
static SymGetLineFromAddr64_t SymGetLineFromAddr64;
|
|
static void load_dbghelp()
|
|
{
|
|
#if defined(__cplusplus) && !defined(__clang__)
|
|
using win32::GetProcAddress;
|
|
using win32::LoadLibraryA;
|
|
#endif
|
|
while(dbghelp_init_lock.exchange(1, std::memory_order_acq_rel))
|
|
;
|
|
if(dbghelp)
|
|
{
|
|
dbghelp_init_lock.store(0, std::memory_order_release);
|
|
return;
|
|
}
|
|
dbghelp = LoadLibraryA("DBGHELP.DLL");
|
|
if(dbghelp)
|
|
{
|
|
SymInitialize = (SymInitialize_t) GetProcAddress(dbghelp, "SymInitializeW");
|
|
if(!SymInitialize)
|
|
abort();
|
|
if(!SymInitialize((void *) (size_t) -1 /*GetCurrentProcess()*/, NULL, 1))
|
|
abort();
|
|
SymGetLineFromAddr64 = (SymGetLineFromAddr64_t) GetProcAddress(dbghelp, "SymGetLineFromAddrW64");
|
|
if(!SymGetLineFromAddr64)
|
|
abort();
|
|
}
|
|
dbghelp_init_lock.store(0, std::memory_order_release);
|
|
}
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
_Check_return_ size_t backtrace(_Out_writes_(len) void **bt, _In_ size_t len)
|
|
{
|
|
#if defined(__cplusplus) && !defined(__clang__)
|
|
using win32::RtlCaptureStackBackTrace;
|
|
#endif
|
|
return RtlCaptureStackBackTrace(1, (unsigned long) len, bt, NULL);
|
|
}
|
|
#ifdef _MSC_VER
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 6385 6386) // MSVC static analyser can't grok this function. clang's analyser gives it thumbs up.
|
|
#endif
|
|
_Check_return_ _Ret_writes_maybenull_(len) char **backtrace_symbols(_In_reads_(len) void *const *bt, _In_ size_t len)
|
|
{
|
|
#if defined(__cplusplus) && !defined(__clang__)
|
|
using win32::WideCharToMultiByte;
|
|
#endif
|
|
size_t bytes = (len + 1) * sizeof(void *) + 256, n;
|
|
if(!len)
|
|
return NULL;
|
|
else
|
|
{
|
|
char **ret = (char **) malloc(bytes);
|
|
char *p = (char *) (ret + len + 1), *end = (char *) ret + bytes;
|
|
if(!ret)
|
|
return NULL;
|
|
for(n = 0; n < len + 1; n++)
|
|
ret[n] = NULL;
|
|
load_dbghelp();
|
|
for(n = 0; n < len; n++)
|
|
{
|
|
unsigned long displ;
|
|
IMAGEHLP_LINE64 ihl;
|
|
memset(&ihl, 0, sizeof(ihl));
|
|
ihl.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
|
int please_realloc = 0;
|
|
if(!bt[n])
|
|
{
|
|
ret[n] = NULL;
|
|
}
|
|
else
|
|
{
|
|
// Keep offset till later
|
|
ret[n] = (char *) ((char *) p - (char *) ret);
|
|
{
|
|
static std::atomic<unsigned> symlock(0);
|
|
while(symlock.exchange(1, std::memory_order_acq_rel))
|
|
;
|
|
if(!SymGetLineFromAddr64 || !SymGetLineFromAddr64((void *) (size_t) -1 /*GetCurrentProcess()*/, (size_t) bt[n], &displ, &ihl))
|
|
{
|
|
symlock.store(0, std::memory_order_release);
|
|
if(n == 0)
|
|
{
|
|
free(ret);
|
|
return NULL;
|
|
}
|
|
ihl.FileName = (wchar_t *) L"unknown";
|
|
ihl.LineNumber = 0;
|
|
}
|
|
else
|
|
{
|
|
symlock.store(0, std::memory_order_release);
|
|
}
|
|
}
|
|
retry:
|
|
if(please_realloc)
|
|
{
|
|
char **temp = (char **) realloc(ret, bytes + 256);
|
|
if(!temp)
|
|
{
|
|
free(ret);
|
|
return NULL;
|
|
}
|
|
p = (char *) temp + (p - (char *) ret);
|
|
ret = temp;
|
|
bytes += 256;
|
|
end = (char *) ret + bytes;
|
|
}
|
|
if(ihl.FileName && ihl.FileName[0])
|
|
{
|
|
int plen = WideCharToMultiByte(65001 /*CP_UTF8*/, 0, ihl.FileName, -1, p, (int) (end - p), NULL, NULL);
|
|
if(!plen)
|
|
{
|
|
please_realloc = 1;
|
|
goto retry;
|
|
}
|
|
p[plen - 1] = 0;
|
|
p += plen - 1;
|
|
}
|
|
else
|
|
{
|
|
if(end - p < 16)
|
|
{
|
|
please_realloc = 1;
|
|
goto retry;
|
|
}
|
|
_ui64toa_s((size_t) bt[n], p, end - p, 16);
|
|
p = strchr(p, 0);
|
|
}
|
|
if(end - p < 16)
|
|
{
|
|
please_realloc = 1;
|
|
goto retry;
|
|
}
|
|
*p++ = ':';
|
|
_itoa_s(ihl.LineNumber, p, end - p, 10);
|
|
p = strchr(p, 0) + 1;
|
|
}
|
|
}
|
|
for(n = 0; n < len; n++)
|
|
{
|
|
if(ret[n])
|
|
ret[n] = (char *) ret + (size_t) ret[n];
|
|
}
|
|
return ret;
|
|
}
|
|
}
|
|
#ifdef _MSC_VER
|
|
#pragma warning(pop)
|
|
#endif
|
|
// extern void backtrace_symbols_fd(void *const *bt, size_t len, int fd);
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#undef QUICKCPPLIB_INCLUDED_BY_HEADER
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#else
|
|
#include <execinfo.h>
|
|
#endif
|
|
#endif // OUTCOME_DISABLE_EXECINFO
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
OUTCOME_V2_NAMESPACE_BEGIN
|
|
namespace detail
|
|
{
|
|
QUICKCPPLIB_NORETURN inline void do_fatal_exit(const char *expr)
|
|
{
|
|
#if !defined(OUTCOME_DISABLE_EXECINFO)
|
|
void *bt[16];
|
|
size_t btlen = backtrace(bt, sizeof(bt) / sizeof(bt[0])); // NOLINT
|
|
#endif
|
|
fprintf(stderr, "FATAL: Outcome throws exception %s with exceptions disabled\n", expr); // NOLINT
|
|
#if !defined(OUTCOME_DISABLE_EXECINFO)
|
|
char **bts = backtrace_symbols(bt, btlen); // NOLINT
|
|
if(bts != nullptr)
|
|
{
|
|
for(size_t n = 0; n < btlen; n++)
|
|
{
|
|
fprintf(stderr, " %s\n", bts[n]); // NOLINT
|
|
}
|
|
free(bts); // NOLINT
|
|
}
|
|
#endif
|
|
abort();
|
|
}
|
|
} // namespace detail
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#define OUTCOME_THROW_EXCEPTION(expr) OUTCOME_V2_NAMESPACE::detail::do_fatal_exit(#expr), (void) (expr)
|
|
#endif
|
|
#endif
|
|
#ifndef BOOST_OUTCOME_AUTO_TEST_CASE
|
|
#define BOOST_OUTCOME_AUTO_TEST_CASE(a, b) BOOST_AUTO_TEST_CASE(a, b)
|
|
#endif
|
|
#endif
|
|
#define OUTCOME_COROUTINE_SUPPORT_NAMESPACE_BEGIN OUTCOME_V2_NAMESPACE_BEGIN namespace awaitables {
|
|
//
|
|
#define OUTCOME_COROUTINE_SUPPORT_NAMESPACE_EXPORT_BEGIN OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace awaitables {
|
|
//
|
|
#define OUTCOME_COROUTINE_SUPPORT_NAMESPACE_END } OUTCOME_V2_NAMESPACE_END
|
|
#ifdef __cpp_exceptions
|
|
/* Tries to convert an exception ptr into its equivalent error code
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (11 commits)
|
|
File Created: July 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_UTILS_HPP
|
|
#define OUTCOME_UTILS_HPP
|
|
#include <exception>
|
|
#include <string>
|
|
#include <system_error>
|
|
OUTCOME_V2_NAMESPACE_BEGIN
|
|
#ifdef __cpp_exceptions
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
inline std::error_code error_from_exception(std::exception_ptr &&ep = std::current_exception(), std::error_code not_matched = std::make_error_code(std::errc::resource_unavailable_try_again)) noexcept
|
|
{
|
|
if(!ep)
|
|
{
|
|
return {};
|
|
}
|
|
try
|
|
{
|
|
std::rethrow_exception(ep);
|
|
}
|
|
catch(const std::invalid_argument & /*unused*/)
|
|
{
|
|
ep = std::exception_ptr();
|
|
return std::make_error_code(std::errc::invalid_argument);
|
|
}
|
|
catch(const std::domain_error & /*unused*/)
|
|
{
|
|
ep = std::exception_ptr();
|
|
return std::make_error_code(std::errc::argument_out_of_domain);
|
|
}
|
|
catch(const std::length_error & /*unused*/)
|
|
{
|
|
ep = std::exception_ptr();
|
|
return std::make_error_code(std::errc::argument_list_too_long);
|
|
}
|
|
catch(const std::out_of_range & /*unused*/)
|
|
{
|
|
ep = std::exception_ptr();
|
|
return std::make_error_code(std::errc::result_out_of_range);
|
|
}
|
|
catch(const std::logic_error & /*unused*/) /* base class for this group */
|
|
{
|
|
ep = std::exception_ptr();
|
|
return std::make_error_code(std::errc::invalid_argument);
|
|
}
|
|
catch(const std::system_error &e) /* also catches ios::failure */
|
|
{
|
|
ep = std::exception_ptr();
|
|
return e.code();
|
|
}
|
|
catch(const std::overflow_error & /*unused*/)
|
|
{
|
|
ep = std::exception_ptr();
|
|
return std::make_error_code(std::errc::value_too_large);
|
|
}
|
|
catch(const std::range_error & /*unused*/)
|
|
{
|
|
ep = std::exception_ptr();
|
|
return std::make_error_code(std::errc::result_out_of_range);
|
|
}
|
|
catch(const std::runtime_error & /*unused*/) /* base class for this group */
|
|
{
|
|
ep = std::exception_ptr();
|
|
return std::make_error_code(std::errc::resource_unavailable_try_again);
|
|
}
|
|
catch(const std::bad_alloc & /*unused*/)
|
|
{
|
|
ep = std::exception_ptr();
|
|
return std::make_error_code(std::errc::not_enough_memory);
|
|
}
|
|
catch(...)
|
|
{
|
|
}
|
|
return not_matched;
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
inline void try_throw_std_exception_from_error(std::error_code ec, const std::string &msg = std::string{})
|
|
{
|
|
if(!ec || (ec.category() != std::generic_category()
|
|
#ifndef _WIN32
|
|
&& ec.category() != std::system_category()
|
|
#endif
|
|
))
|
|
{
|
|
return;
|
|
}
|
|
switch(ec.value())
|
|
{
|
|
case EINVAL:
|
|
throw msg.empty() ? std::invalid_argument("invalid argument") : std::invalid_argument(msg);
|
|
case EDOM:
|
|
throw msg.empty() ? std::domain_error("domain error") : std::domain_error(msg);
|
|
case E2BIG:
|
|
throw msg.empty() ? std::length_error("length error") : std::length_error(msg);
|
|
case ERANGE:
|
|
throw msg.empty() ? std::out_of_range("out of range") : std::out_of_range(msg);
|
|
case EOVERFLOW:
|
|
throw msg.empty() ? std::overflow_error("overflow error") : std::overflow_error(msg);
|
|
case ENOMEM:
|
|
throw std::bad_alloc();
|
|
}
|
|
}
|
|
#endif
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
OUTCOME_V2_NAMESPACE_BEGIN
|
|
namespace awaitables
|
|
{
|
|
namespace detail
|
|
{
|
|
inline bool error_is_set(std::error_code ec) noexcept { return !!ec; }
|
|
inline std::error_code error_from_exception(std::exception_ptr &&ep, std::error_code not_matched) noexcept { return OUTCOME_V2_NAMESPACE::error_from_exception(static_cast<std::exception_ptr &&>(ep), not_matched); }
|
|
} // namespace detail
|
|
} // namespace awaitables
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* Tells C++ coroutines about Outcome's result
|
|
(C) 2019-2020 Niall Douglas <http://www.nedproductions.biz/> (12 commits)
|
|
File Created: Oct 2019
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_DETAIL_COROUTINE_SUPPORT_HPP
|
|
#define OUTCOME_DETAIL_COROUTINE_SUPPORT_HPP
|
|
#include <atomic>
|
|
#include <cassert>
|
|
#if __cpp_impl_coroutine || (defined(_MSC_VER) && __cpp_coroutines) || (defined(__clang__) && __cpp_coroutines)
|
|
#ifndef OUTCOME_HAVE_NOOP_COROUTINE
|
|
#if defined(__has_builtin)
|
|
#if __has_builtin(__builtin_coro_noop)
|
|
#define OUTCOME_HAVE_NOOP_COROUTINE 1
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#ifndef OUTCOME_HAVE_NOOP_COROUTINE
|
|
#if _MSC_VER >= 1928
|
|
#define OUTCOME_HAVE_NOOP_COROUTINE 1
|
|
#else
|
|
#define OUTCOME_HAVE_NOOP_COROUTINE 0
|
|
#endif
|
|
#endif
|
|
#if __has_include(<coroutine>)
|
|
#include <coroutine>
|
|
OUTCOME_V2_NAMESPACE_BEGIN
|
|
namespace awaitables
|
|
{
|
|
template <class Promise = void> using coroutine_handle = std::coroutine_handle<Promise>;
|
|
template <class... Args> using coroutine_traits = std::coroutine_traits<Args...>;
|
|
using std::suspend_always;
|
|
using std::suspend_never;
|
|
#if OUTCOME_HAVE_NOOP_COROUTINE
|
|
using std::noop_coroutine;
|
|
#endif
|
|
} // namespace awaitables
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#define OUTCOME_FOUND_COROUTINE_HEADER 1
|
|
#elif __has_include(<experimental/coroutine>)
|
|
#include <experimental/coroutine>
|
|
OUTCOME_V2_NAMESPACE_BEGIN
|
|
namespace awaitables
|
|
{
|
|
template <class Promise = void> using coroutine_handle = std::experimental::coroutine_handle<Promise>;
|
|
template <class... Args> using coroutine_traits = std::experimental::coroutine_traits<Args...>;
|
|
using std::experimental::suspend_always;
|
|
using std::experimental::suspend_never;
|
|
#if OUTCOME_HAVE_NOOP_COROUTINE
|
|
using std::experimental::noop_coroutine;
|
|
#endif
|
|
} // namespace awaitables
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#define OUTCOME_FOUND_COROUTINE_HEADER 1
|
|
#endif
|
|
#endif
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace awaitables
|
|
{
|
|
namespace detail
|
|
{
|
|
struct error_type_not_found
|
|
{
|
|
};
|
|
struct exception_type_not_found
|
|
{
|
|
};
|
|
template <class T> struct type_found
|
|
{
|
|
using type = T;
|
|
};
|
|
template <class T, class U = typename T::error_type> constexpr inline type_found<U> extract_error_type(int /*unused*/) { return {}; }
|
|
template <class T> constexpr inline type_found<error_type_not_found> extract_error_type(...) { return {}; }
|
|
template <class T, class U = typename T::exception_type> constexpr inline type_found<U> extract_exception_type(int /*unused*/) { return {}; }
|
|
template <class T> constexpr inline type_found<exception_type_not_found> extract_exception_type(...) { return {}; }
|
|
OUTCOME_TEMPLATE(class T, class U)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(OUTCOME_V2_NAMESPACE::detail::is_constructible<U, T>))
|
|
inline bool try_set_error(T &&e, U *result)
|
|
{
|
|
new(result) U(static_cast<T &&>(e));
|
|
return true;
|
|
}
|
|
template <class T> inline bool try_set_error(T && /*unused*/, ...) { return false; }
|
|
OUTCOME_TEMPLATE(class T, class U)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(OUTCOME_V2_NAMESPACE::detail::is_constructible<U, T>))
|
|
inline void set_or_rethrow(T &e, U *result) { new(result) U(e); }
|
|
template <class T> inline void set_or_rethrow(T &e, ...) { rethrow_exception(e); }
|
|
template <class T> class fake_atomic
|
|
{
|
|
T _v;
|
|
public:
|
|
constexpr fake_atomic(T v)
|
|
: _v(v)
|
|
{
|
|
}
|
|
T load(std::memory_order /*unused*/) { return _v; }
|
|
void store(T v, std::memory_order /*unused*/) { _v = v; }
|
|
};
|
|
#ifdef OUTCOME_FOUND_COROUTINE_HEADER
|
|
template <class Awaitable, bool suspend_initial, bool use_atomic, bool is_void> struct outcome_promise_type
|
|
{
|
|
using container_type = typename Awaitable::container_type;
|
|
using result_set_type = std::conditional_t<use_atomic, std::atomic<bool>, fake_atomic<bool>>;
|
|
union
|
|
{
|
|
OUTCOME_V2_NAMESPACE::detail::empty_type _default{};
|
|
container_type result;
|
|
};
|
|
result_set_type result_set{false};
|
|
coroutine_handle<> continuation;
|
|
outcome_promise_type() noexcept {}
|
|
outcome_promise_type(const outcome_promise_type &) = delete;
|
|
outcome_promise_type(outcome_promise_type &&) = delete;
|
|
outcome_promise_type &operator=(const outcome_promise_type &) = delete;
|
|
outcome_promise_type &operator=(outcome_promise_type &&) = delete;
|
|
~outcome_promise_type()
|
|
{
|
|
if(result_set.load(std::memory_order_acquire))
|
|
{
|
|
result.~container_type(); // could throw
|
|
}
|
|
}
|
|
auto get_return_object()
|
|
{
|
|
return Awaitable{*this}; // could throw bad_alloc
|
|
}
|
|
void return_value(container_type &&value)
|
|
{
|
|
assert(!result_set.load(std::memory_order_acquire));
|
|
if(result_set.load(std::memory_order_acquire))
|
|
{
|
|
result.~container_type(); // could throw
|
|
}
|
|
new(&result) container_type(static_cast<container_type &&>(value)); // could throw
|
|
result_set.store(true, std::memory_order_release);
|
|
}
|
|
void return_value(const container_type &value)
|
|
{
|
|
assert(!result_set.load(std::memory_order_acquire));
|
|
if(result_set.load(std::memory_order_acquire))
|
|
{
|
|
result.~container_type(); // could throw
|
|
}
|
|
new(&result) container_type(value); // could throw
|
|
result_set.store(true, std::memory_order_release);
|
|
}
|
|
void unhandled_exception()
|
|
{
|
|
assert(!result_set.load(std::memory_order_acquire));
|
|
if(result_set.load(std::memory_order_acquire))
|
|
{
|
|
result.~container_type();
|
|
}
|
|
#ifdef __cpp_exceptions
|
|
auto e = std::current_exception();
|
|
auto ec = detail::error_from_exception(static_cast<decltype(e) &&>(e), {});
|
|
// Try to set error code first
|
|
if(!detail::error_is_set(ec) || !detail::try_set_error(static_cast<decltype(ec) &&>(ec), &result))
|
|
{
|
|
detail::set_or_rethrow(e, &result); // could throw
|
|
}
|
|
#else
|
|
std::terminate();
|
|
#endif
|
|
result_set.store(true, std::memory_order_release);
|
|
}
|
|
auto initial_suspend() noexcept
|
|
{
|
|
struct awaiter
|
|
{
|
|
bool await_ready() noexcept { return !suspend_initial; }
|
|
void await_resume() noexcept {}
|
|
void await_suspend(coroutine_handle<> /*unused*/) noexcept {}
|
|
};
|
|
return awaiter{};
|
|
}
|
|
auto final_suspend() noexcept
|
|
{
|
|
struct awaiter
|
|
{
|
|
bool await_ready() noexcept { return false; }
|
|
void await_resume() noexcept {}
|
|
#if OUTCOME_HAVE_NOOP_COROUTINE
|
|
coroutine_handle<> await_suspend(coroutine_handle<outcome_promise_type> self) noexcept
|
|
{
|
|
return self.promise().continuation ? self.promise().continuation : noop_coroutine();
|
|
}
|
|
#else
|
|
void await_suspend(coroutine_handle<outcome_promise_type> self)
|
|
{
|
|
if(self.promise().continuation)
|
|
{
|
|
return self.promise().continuation.resume();
|
|
}
|
|
}
|
|
#endif
|
|
};
|
|
return awaiter{};
|
|
}
|
|
};
|
|
template <class Awaitable, bool suspend_initial, bool use_atomic> struct outcome_promise_type<Awaitable, suspend_initial, use_atomic, true>
|
|
{
|
|
using container_type = void;
|
|
using result_set_type = std::conditional_t<use_atomic, std::atomic<bool>, fake_atomic<bool>>;
|
|
result_set_type result_set{false};
|
|
coroutine_handle<> continuation;
|
|
outcome_promise_type() {}
|
|
outcome_promise_type(const outcome_promise_type &) = delete;
|
|
outcome_promise_type(outcome_promise_type &&) = delete;
|
|
outcome_promise_type &operator=(const outcome_promise_type &) = delete;
|
|
outcome_promise_type &operator=(outcome_promise_type &&) = delete;
|
|
~outcome_promise_type() = default;
|
|
auto get_return_object()
|
|
{
|
|
return Awaitable{*this}; // could throw bad_alloc
|
|
}
|
|
void return_void() noexcept
|
|
{
|
|
assert(!result_set.load(std::memory_order_acquire));
|
|
result_set.store(true, std::memory_order_release);
|
|
}
|
|
void unhandled_exception()
|
|
{
|
|
assert(!result_set.load(std::memory_order_acquire));
|
|
std::rethrow_exception(std::current_exception()); // throws
|
|
}
|
|
auto initial_suspend() noexcept
|
|
{
|
|
struct awaiter
|
|
{
|
|
bool await_ready() noexcept { return !suspend_initial; }
|
|
void await_resume() noexcept {}
|
|
void await_suspend(coroutine_handle<> /*unused*/) noexcept {}
|
|
};
|
|
return awaiter{};
|
|
}
|
|
auto final_suspend() noexcept
|
|
{
|
|
struct awaiter
|
|
{
|
|
bool await_ready() noexcept { return false; }
|
|
void await_resume() noexcept {}
|
|
#if OUTCOME_HAVE_NOOP_COROUTINE
|
|
coroutine_handle<> await_suspend(coroutine_handle<outcome_promise_type> self) noexcept
|
|
{
|
|
return self.promise().continuation ? self.promise().continuation : noop_coroutine();
|
|
}
|
|
#else
|
|
void await_suspend(coroutine_handle<outcome_promise_type> self)
|
|
{
|
|
if(self.promise().continuation)
|
|
{
|
|
return self.promise().continuation.resume();
|
|
}
|
|
}
|
|
#endif
|
|
};
|
|
return awaiter{};
|
|
}
|
|
};
|
|
template <class Awaitable, bool suspend_initial, bool use_atomic>
|
|
constexpr inline auto move_result_from_promise_if_not_void(outcome_promise_type<Awaitable, suspend_initial, use_atomic, false> &p)
|
|
{
|
|
return static_cast<typename Awaitable::container_type &&>(p.result);
|
|
}
|
|
template <class Awaitable, bool suspend_initial, bool use_atomic>
|
|
constexpr inline void move_result_from_promise_if_not_void(outcome_promise_type<Awaitable, suspend_initial, use_atomic, true> & /*unused*/)
|
|
{
|
|
}
|
|
template <class Cont, bool suspend_initial, bool use_atomic> struct OUTCOME_NODISCARD awaitable
|
|
{
|
|
using container_type = Cont;
|
|
using promise_type = outcome_promise_type<awaitable, suspend_initial, use_atomic, std::is_void<container_type>::value>;
|
|
coroutine_handle<promise_type> _h;
|
|
awaitable(awaitable &&o) noexcept
|
|
: _h(static_cast<coroutine_handle<promise_type> &&>(o._h))
|
|
{
|
|
o._h = nullptr;
|
|
}
|
|
awaitable(const awaitable &o) = delete;
|
|
awaitable &operator=(awaitable &&) = delete; // as per P1056
|
|
awaitable &operator=(const awaitable &) = delete;
|
|
~awaitable()
|
|
{
|
|
if(_h)
|
|
{
|
|
_h.destroy();
|
|
}
|
|
}
|
|
explicit awaitable(promise_type &p) // could throw
|
|
: _h(coroutine_handle<promise_type>::from_promise(p))
|
|
{
|
|
}
|
|
bool await_ready() noexcept { return _h.promise().result_set.load(std::memory_order_acquire); }
|
|
container_type await_resume()
|
|
{
|
|
assert(_h.promise().result_set.load(std::memory_order_acquire));
|
|
if(!_h.promise().result_set.load(std::memory_order_acquire))
|
|
{
|
|
std::terminate();
|
|
}
|
|
return detail::move_result_from_promise_if_not_void(_h.promise());
|
|
}
|
|
#if OUTCOME_HAVE_NOOP_COROUTINE
|
|
coroutine_handle<> await_suspend(coroutine_handle<> cont) noexcept
|
|
{
|
|
_h.promise().continuation = cont;
|
|
return _h;
|
|
}
|
|
#else
|
|
void await_suspend(coroutine_handle<> cont)
|
|
{
|
|
_h.promise().continuation = cont;
|
|
_h.resume();
|
|
}
|
|
#endif
|
|
};
|
|
#endif
|
|
} // namespace detail
|
|
} // namespace awaitables
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
#ifdef OUTCOME_FOUND_COROUTINE_HEADER
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN namespace awaitables {
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T> using eager = OUTCOME_V2_NAMESPACE::awaitables::detail::awaitable<T, false, false>;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T> using atomic_eager = OUTCOME_V2_NAMESPACE::awaitables::detail::awaitable<T, false, true>;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T> using lazy = OUTCOME_V2_NAMESPACE::awaitables::detail::awaitable<T, true, false>;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T> using atomic_lazy = OUTCOME_V2_NAMESPACE::awaitables::detail::awaitable<T, true, true>;
|
|
} OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
#undef OUTCOME_COROUTINE_SUPPORT_NAMESPACE_BEGIN
|
|
#undef OUTCOME_COROUTINE_SUPPORT_NAMESPACE_EXPORT_BEGIN
|
|
#undef OUTCOME_COROUTINE_SUPPORT_NAMESPACE_END
|
|
#endif
|
|
/* iostream specialisations for result and outcome
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (21 commits)
|
|
File Created: July 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_IOSTREAM_SUPPORT_HPP
|
|
#define OUTCOME_IOSTREAM_SUPPORT_HPP
|
|
/* A less simple result type
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (79 commits)
|
|
File Created: June 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_OUTCOME_HPP
|
|
#define OUTCOME_OUTCOME_HPP
|
|
/* A very simple result type
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (99 commits)
|
|
File Created: June 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_RESULT_HPP
|
|
#define OUTCOME_RESULT_HPP
|
|
/* A very simple result type
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (8 commits)
|
|
File Created: June 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_STD_RESULT_HPP
|
|
#define OUTCOME_STD_RESULT_HPP
|
|
/* A very simple result type
|
|
(C) 2017-2021 Niall Douglas <http://www.nedproductions.biz/> (14 commits)
|
|
File Created: June 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_BASIC_RESULT_HPP
|
|
#define OUTCOME_BASIC_RESULT_HPP
|
|
/* Says how to convert value, error and exception types
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (12 commits)
|
|
File Created: Nov 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_CONVERT_HPP
|
|
#define OUTCOME_CONVERT_HPP
|
|
/* Storage for a very simple basic_result type
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_BASIC_RESULT_STORAGE_HPP
|
|
#define OUTCOME_BASIC_RESULT_STORAGE_HPP
|
|
/* Type sugar for success and failure
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (25 commits)
|
|
File Created: July 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_SUCCESS_FAILURE_HPP
|
|
#define OUTCOME_SUCCESS_FAILURE_HPP
|
|
OUTCOME_V2_NAMESPACE_BEGIN
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition template <class T> success_type. Potential doc page: `success_type<T>`
|
|
*/
|
|
template <class T> struct OUTCOME_NODISCARD success_type
|
|
{
|
|
using value_type = T;
|
|
private:
|
|
value_type _value;
|
|
uint16_t _spare_storage{0};
|
|
public:
|
|
success_type() = default;
|
|
success_type(const success_type &) = default;
|
|
success_type(success_type &&) = default; // NOLINT
|
|
success_type &operator=(const success_type &) = default;
|
|
success_type &operator=(success_type &&) = default; // NOLINT
|
|
~success_type() = default;
|
|
OUTCOME_TEMPLATE(class U)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!std::is_same<success_type, std::decay_t<U>>::value))
|
|
constexpr explicit success_type(U &&v, uint16_t spare_storage = 0)
|
|
: _value(static_cast<U &&>(v)) // NOLINT
|
|
, _spare_storage(spare_storage)
|
|
{
|
|
}
|
|
constexpr value_type &value() & { return _value; }
|
|
constexpr const value_type &value() const & { return _value; }
|
|
constexpr value_type &&value() && { return static_cast<value_type &&>(_value); }
|
|
constexpr const value_type &&value() const && { return static_cast<value_type &&>(_value); }
|
|
constexpr uint16_t spare_storage() const { return _spare_storage; }
|
|
};
|
|
template <> struct OUTCOME_NODISCARD success_type<void>
|
|
{
|
|
using value_type = void;
|
|
constexpr uint16_t spare_storage() const { return 0; }
|
|
};
|
|
/*! Returns type sugar for implicitly constructing a `basic_result<T>` with a successful state,
|
|
default constructing `T` if necessary.
|
|
*/
|
|
inline constexpr success_type<void> success() noexcept
|
|
{
|
|
return success_type<void>{};
|
|
}
|
|
/*! Returns type sugar for implicitly constructing a `basic_result<T>` with a successful state.
|
|
\effects Copies or moves the successful state supplied into the returned type sugar.
|
|
*/
|
|
template <class T> inline constexpr success_type<std::decay_t<T>> success(T &&v, uint16_t spare_storage = 0)
|
|
{
|
|
return success_type<std::decay_t<T>>{static_cast<T &&>(v), spare_storage};
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition template <class EC, class E = void> failure_type. Potential doc page: `failure_type<EC, EP = void>`
|
|
*/
|
|
template <class EC, class E = void> struct OUTCOME_NODISCARD failure_type
|
|
{
|
|
using error_type = EC;
|
|
using exception_type = E;
|
|
private:
|
|
error_type _error;
|
|
exception_type _exception;
|
|
bool _have_error{false}, _have_exception{false};
|
|
uint16_t _spare_storage{0};
|
|
struct error_init_tag
|
|
{
|
|
};
|
|
struct exception_init_tag
|
|
{
|
|
};
|
|
public:
|
|
failure_type() = default;
|
|
failure_type(const failure_type &) = default;
|
|
failure_type(failure_type &&) = default; // NOLINT
|
|
failure_type &operator=(const failure_type &) = default;
|
|
failure_type &operator=(failure_type &&) = default; // NOLINT
|
|
~failure_type() = default;
|
|
template <class U, class V>
|
|
constexpr explicit failure_type(U &&u, V &&v, uint16_t spare_storage = 0)
|
|
: _error(static_cast<U &&>(u))
|
|
, _exception(static_cast<V &&>(v))
|
|
, _have_error(true)
|
|
, _have_exception(true)
|
|
, _spare_storage(spare_storage)
|
|
{
|
|
}
|
|
template <class U>
|
|
constexpr explicit failure_type(in_place_type_t<error_type> /*unused*/, U &&u, uint16_t spare_storage = 0, error_init_tag /*unused*/ = error_init_tag())
|
|
: _error(static_cast<U &&>(u))
|
|
, _exception()
|
|
, _have_error(true)
|
|
, _spare_storage(spare_storage)
|
|
{
|
|
}
|
|
template <class U>
|
|
constexpr explicit failure_type(in_place_type_t<exception_type> /*unused*/, U &&u, uint16_t spare_storage = 0,
|
|
exception_init_tag /*unused*/ = exception_init_tag())
|
|
: _error()
|
|
, _exception(static_cast<U &&>(u))
|
|
, _have_exception(true)
|
|
, _spare_storage(spare_storage)
|
|
{
|
|
}
|
|
constexpr bool has_error() const { return _have_error; }
|
|
constexpr bool has_exception() const { return _have_exception; }
|
|
constexpr error_type &error() & { return _error; }
|
|
constexpr const error_type &error() const & { return _error; }
|
|
constexpr error_type &&error() && { return static_cast<error_type &&>(_error); }
|
|
constexpr const error_type &&error() const && { return static_cast<error_type &&>(_error); }
|
|
constexpr exception_type &exception() & { return _exception; }
|
|
constexpr const exception_type &exception() const & { return _exception; }
|
|
constexpr exception_type &&exception() && { return static_cast<exception_type &&>(_exception); }
|
|
constexpr const exception_type &&exception() const && { return static_cast<exception_type &&>(_exception); }
|
|
constexpr uint16_t spare_storage() const { return _spare_storage; }
|
|
};
|
|
template <class EC> struct OUTCOME_NODISCARD failure_type<EC, void>
|
|
{
|
|
using error_type = EC;
|
|
using exception_type = void;
|
|
private:
|
|
error_type _error;
|
|
uint16_t _spare_storage{0};
|
|
public:
|
|
failure_type() = default;
|
|
failure_type(const failure_type &) = default;
|
|
failure_type(failure_type &&) = default; // NOLINT
|
|
failure_type &operator=(const failure_type &) = default;
|
|
failure_type &operator=(failure_type &&) = default; // NOLINT
|
|
~failure_type() = default;
|
|
OUTCOME_TEMPLATE(class U)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!std::is_same<failure_type, std::decay_t<U>>::value))
|
|
constexpr explicit failure_type(U &&u, uint16_t spare_storage = 0)
|
|
: _error(static_cast<U &&>(u)) // NOLINT
|
|
, _spare_storage(spare_storage)
|
|
{
|
|
}
|
|
constexpr error_type &error() & { return _error; }
|
|
constexpr const error_type &error() const & { return _error; }
|
|
constexpr error_type &&error() && { return static_cast<error_type &&>(_error); }
|
|
constexpr const error_type &&error() const && { return static_cast<error_type &&>(_error); }
|
|
constexpr uint16_t spare_storage() const { return _spare_storage; }
|
|
};
|
|
template <class E> struct OUTCOME_NODISCARD failure_type<void, E>
|
|
{
|
|
using error_type = void;
|
|
using exception_type = E;
|
|
private:
|
|
exception_type _exception;
|
|
uint16_t _spare_storage{0};
|
|
public:
|
|
failure_type() = default;
|
|
failure_type(const failure_type &) = default;
|
|
failure_type(failure_type &&) = default; // NOLINT
|
|
failure_type &operator=(const failure_type &) = default;
|
|
failure_type &operator=(failure_type &&) = default; // NOLINT
|
|
~failure_type() = default;
|
|
OUTCOME_TEMPLATE(class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!std::is_same<failure_type, std::decay_t<V>>::value))
|
|
constexpr explicit failure_type(V &&v, uint16_t spare_storage = 0)
|
|
: _exception(static_cast<V &&>(v)) // NOLINT
|
|
, _spare_storage(spare_storage)
|
|
{
|
|
}
|
|
constexpr exception_type &exception() & { return _exception; }
|
|
constexpr const exception_type &exception() const & { return _exception; }
|
|
constexpr exception_type &&exception() && { return static_cast<exception_type &&>(_exception); }
|
|
constexpr const exception_type &&exception() const && { return static_cast<exception_type &&>(_exception); }
|
|
constexpr uint16_t spare_storage() const { return _spare_storage; }
|
|
};
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class EC> inline constexpr failure_type<std::decay_t<EC>> failure(EC &&v, uint16_t spare_storage = 0)
|
|
{
|
|
return failure_type<std::decay_t<EC>>{static_cast<EC &&>(v), spare_storage};
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class EC, class E> inline constexpr failure_type<std::decay_t<EC>, std::decay_t<E>> failure(EC &&v, E &&w, uint16_t spare_storage = 0)
|
|
{
|
|
return failure_type<std::decay_t<EC>, std::decay_t<E>>{static_cast<EC &&>(v), static_cast<E &&>(w), spare_storage};
|
|
}
|
|
namespace detail
|
|
{
|
|
template <class T> struct is_success_type
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
template <class T> struct is_success_type<success_type<T>>
|
|
{
|
|
static constexpr bool value = true;
|
|
};
|
|
template <class T> struct is_failure_type
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
template <class EC, class E> struct is_failure_type<failure_type<EC, E>>
|
|
{
|
|
static constexpr bool value = true;
|
|
};
|
|
} // namespace detail
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T> static constexpr bool is_success_type = detail::is_success_type<std::decay_t<T>>::value;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T> static constexpr bool is_failure_type = detail::is_failure_type<std::decay_t<T>>::value;
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* Traits for Outcome
|
|
(C) 2018-2019 Niall Douglas <http://www.nedproductions.biz/> (8 commits)
|
|
File Created: March 2018
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_TRAIT_HPP
|
|
#define OUTCOME_TRAIT_HPP
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace trait
|
|
{
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class R> //
|
|
static constexpr bool type_can_be_used_in_basic_result = //
|
|
(!std::is_reference<R>::value //
|
|
&& !OUTCOME_V2_NAMESPACE::detail::is_in_place_type_t<std::decay_t<R>>::value //
|
|
&& !is_success_type<R> //
|
|
&& !is_failure_type<R> //
|
|
&& !std::is_array<R>::value //
|
|
&& (std::is_void<R>::value || (std::is_object<R>::value //
|
|
&& std::is_destructible<R>::value)) //
|
|
);
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition is_error_type. Potential doc page: NOT FOUND
|
|
*/
|
|
template <class T> struct is_move_bitcopying
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition is_error_type. Potential doc page: NOT FOUND
|
|
*/
|
|
template <class E> struct is_error_type
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition is_error_type_enum. Potential doc page: NOT FOUND
|
|
*/
|
|
template <class E, class Enum> struct is_error_type_enum
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
namespace detail
|
|
{
|
|
template <class T> using devoid = OUTCOME_V2_NAMESPACE::detail::devoid<T>;
|
|
template <class T> std::add_rvalue_reference_t<devoid<T>> declval() noexcept;
|
|
// From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4436.pdf
|
|
namespace detector_impl
|
|
{
|
|
template <class...> using void_t = void;
|
|
template <class Default, class, template <class...> class Op, class... Args> struct detector
|
|
{
|
|
static constexpr bool value = false;
|
|
using type = Default;
|
|
};
|
|
template <class Default, template <class...> class Op, class... Args> struct detector<Default, void_t<Op<Args...>>, Op, Args...>
|
|
{
|
|
static constexpr bool value = true;
|
|
using type = Op<Args...>;
|
|
};
|
|
} // namespace detector_impl
|
|
template <template <class...> class Op, class... Args> using is_detected = detector_impl::detector<void, void, Op, Args...>;
|
|
template <class Arg> using result_of_make_error_code = decltype(make_error_code(declval<Arg>()));
|
|
template <class Arg> using introspect_make_error_code = is_detected<result_of_make_error_code, Arg>;
|
|
template <class Arg> using result_of_make_exception_ptr = decltype(make_exception_ptr(declval<Arg>()));
|
|
template <class Arg> using introspect_make_exception_ptr = is_detected<result_of_make_exception_ptr, Arg>;
|
|
template <class T> struct _is_error_code_available
|
|
{
|
|
static constexpr bool value = detail::introspect_make_error_code<T>::value;
|
|
using type = typename detail::introspect_make_error_code<T>::type;
|
|
};
|
|
template <class T> struct _is_exception_ptr_available
|
|
{
|
|
static constexpr bool value = detail::introspect_make_exception_ptr<T>::value;
|
|
using type = typename detail::introspect_make_exception_ptr<T>::type;
|
|
};
|
|
} // namespace detail
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition is_error_code_available. Potential doc page: NOT FOUND
|
|
*/
|
|
template <class T> struct is_error_code_available
|
|
{
|
|
static constexpr bool value = detail::_is_error_code_available<std::decay_t<T>>::value;
|
|
using type = typename detail::_is_error_code_available<std::decay_t<T>>::type;
|
|
};
|
|
template <class T> constexpr bool is_error_code_available_v = detail::_is_error_code_available<std::decay_t<T>>::value;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition is_exception_ptr_available. Potential doc page: NOT FOUND
|
|
*/
|
|
template <class T> struct is_exception_ptr_available
|
|
{
|
|
static constexpr bool value = detail::_is_exception_ptr_available<std::decay_t<T>>::value;
|
|
using type = typename detail::_is_exception_ptr_available<std::decay_t<T>>::type;
|
|
};
|
|
template <class T> constexpr bool is_exception_ptr_available_v = detail::_is_exception_ptr_available<std::decay_t<T>>::value;
|
|
} // namespace trait
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* Essentially an internal optional implementation :)
|
|
(C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (24 commits)
|
|
File Created: June 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_VALUE_STORAGE_HPP
|
|
#define OUTCOME_VALUE_STORAGE_HPP
|
|
#include <cassert>
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace detail
|
|
{
|
|
template <class T, bool nothrow> struct strong_swap_impl
|
|
{
|
|
constexpr strong_swap_impl(bool &allgood, T &a, T &b)
|
|
{
|
|
allgood = true;
|
|
using std::swap;
|
|
swap(a, b);
|
|
}
|
|
};
|
|
template <class T, bool nothrow> struct strong_placement_impl
|
|
{
|
|
template <class F> constexpr strong_placement_impl(bool &allgood, T *a, T *b, F &&f)
|
|
{
|
|
allgood = true;
|
|
new(a) T(static_cast<T &&>(*b));
|
|
b->~T();
|
|
f();
|
|
}
|
|
};
|
|
#ifdef __cpp_exceptions
|
|
template <class T> struct strong_swap_impl<T, false>
|
|
{
|
|
strong_swap_impl(bool &allgood, T &a, T &b)
|
|
{
|
|
allgood = true;
|
|
T v(static_cast<T &&>(a));
|
|
try
|
|
{
|
|
a = static_cast<T &&>(b);
|
|
}
|
|
catch(...)
|
|
{
|
|
// Try to put back a
|
|
try
|
|
{
|
|
a = static_cast<T &&>(v);
|
|
// fall through as all good
|
|
}
|
|
catch(...)
|
|
{
|
|
// failed to completely restore
|
|
allgood = false;
|
|
// throw away second exception
|
|
}
|
|
throw; // rethrow original exception
|
|
}
|
|
// b has been moved to a, try to move v to b
|
|
try
|
|
{
|
|
b = static_cast<T &&>(v);
|
|
}
|
|
catch(...)
|
|
{
|
|
// Try to restore a to b, and v to a
|
|
try
|
|
{
|
|
b = static_cast<T &&>(a);
|
|
a = static_cast<T &&>(v);
|
|
// fall through as all good
|
|
}
|
|
catch(...)
|
|
{
|
|
// failed to completely restore
|
|
allgood = false;
|
|
// throw away second exception
|
|
}
|
|
throw; // rethrow original exception
|
|
}
|
|
}
|
|
};
|
|
template <class T> struct strong_placement_impl<T, false>
|
|
{
|
|
template <class F> strong_placement_impl(bool &allgood, T *a, T *b, F &&f)
|
|
{
|
|
new(a) T(static_cast<T &&>(*b));
|
|
try
|
|
{
|
|
b->~T();
|
|
f();
|
|
}
|
|
catch(...)
|
|
{
|
|
// Try to put back a, but only if we are still good
|
|
if(allgood)
|
|
{
|
|
try
|
|
{
|
|
new(b) T(static_cast<T &&>(*a));
|
|
// fall through as all good
|
|
}
|
|
catch(...)
|
|
{
|
|
// failed to completely restore
|
|
allgood = false;
|
|
// throw away second exception
|
|
}
|
|
throw; // rethrow original exception
|
|
}
|
|
}
|
|
}
|
|
};
|
|
#endif
|
|
} // namespace detail
|
|
/*!
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(std::is_move_constructible<T>::value &&std::is_move_assignable<T>::value))
|
|
constexpr inline void strong_swap(bool &allgood, T &a, T &b) noexcept(detail::is_nothrow_swappable<T>::value)
|
|
{
|
|
detail::strong_swap_impl<T, detail::is_nothrow_swappable<T>::value>(allgood, a, b);
|
|
}
|
|
/*!
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class F)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(std::is_move_constructible<T>::value &&std::is_move_assignable<T>::value))
|
|
constexpr inline void strong_placement(bool &allgood, T *a, T *b, F &&f) noexcept(std::is_nothrow_move_constructible<T>::value)
|
|
{
|
|
detail::strong_placement_impl<T, std::is_nothrow_move_constructible<T>::value>(allgood, a, b, static_cast<F &&>(f));
|
|
}
|
|
namespace detail
|
|
{
|
|
template <class T>
|
|
constexpr
|
|
#ifdef _MSC_VER
|
|
__declspec(noreturn)
|
|
#elif defined(__GNUC__) || defined(__clang__)
|
|
__attribute__((noreturn))
|
|
#endif
|
|
void make_ub(T && /*unused*/)
|
|
{
|
|
assert(false); // NOLINT
|
|
#if defined(__GNUC__) || defined(__clang__)
|
|
__builtin_unreachable();
|
|
#elif defined(_MSC_VER)
|
|
__assume(0);
|
|
#endif
|
|
}
|
|
/* Outcome v1 used a C bitfield whose values were tracked by compiler optimisers nicely,
|
|
but that produces ICEs when used in constexpr.
|
|
|
|
Outcome v2.0-v2.1 used a 32 bit integer and manually set and cleared bits. Unfortunately
|
|
only GCC's optimiser tracks bit values during constant folding, and only per byte, and
|
|
even then unreliably. https://wg21.link/P1886 "Error speed benchmarking" showed just how
|
|
poorly clang and MSVC fails to optimise outcome-using code, if you manually set bits.
|
|
|
|
Outcome v2.2 therefore uses an enum with fixed values, and constexpr manipulation functions
|
|
to change the value to one of the enum's values. This is stupid to look at in source code,
|
|
but it make clang's optimiser do the right thing, so it's worth it.
|
|
*/
|
|
#define OUTCOME_USE_CONSTEXPR_ENUM_STATUS 0
|
|
enum class status : uint16_t
|
|
{
|
|
// WARNING: These bits are not tracked by abi-dumper, but changing them will break ABI!
|
|
none = 0,
|
|
have_value = (1U << 0U),
|
|
have_error = (1U << 1U),
|
|
have_exception = (2U << 1U),
|
|
have_error_exception = (3U << 1U),
|
|
// failed to complete a strong swap
|
|
have_lost_consistency = (1U << 3U),
|
|
have_value_lost_consistency = (1U << 0U) | (1U << 3U),
|
|
have_error_lost_consistency = (1U << 1U) | (1U << 3U),
|
|
have_exception_lost_consistency = (2U << 1U) | (1U << 3U),
|
|
have_error_exception_lost_consistency = (3U << 1U) | (1U << 3U),
|
|
// can errno be set from this error?
|
|
have_error_is_errno = (1U << 4U),
|
|
have_error_error_is_errno = (1U << 1U) | (1U << 4U),
|
|
have_error_exception_error_is_errno = (3U << 1U) | (1U << 4U),
|
|
have_error_lost_consistency_error_is_errno = (1U << 1U) | (1U << 3U) | (1U << 4U),
|
|
have_error_exception_lost_consistency_error_is_errno = (3U << 1U) | (1U << 3U) | (1U << 4U),
|
|
// value has been moved from
|
|
have_moved_from = (1U << 5U)
|
|
};
|
|
struct status_bitfield_type
|
|
{
|
|
status status_value{status::none};
|
|
uint16_t spare_storage_value{0}; // hooks::spare_storage()
|
|
constexpr status_bitfield_type() = default;
|
|
constexpr status_bitfield_type(status v) noexcept
|
|
: status_value(v)
|
|
{
|
|
} // NOLINT
|
|
constexpr status_bitfield_type(status v, uint16_t s) noexcept
|
|
: status_value(v)
|
|
, spare_storage_value(s)
|
|
{
|
|
}
|
|
constexpr status_bitfield_type(const status_bitfield_type &) = default;
|
|
constexpr status_bitfield_type(status_bitfield_type &&) = default;
|
|
constexpr status_bitfield_type &operator=(const status_bitfield_type &) = default;
|
|
constexpr status_bitfield_type &operator=(status_bitfield_type &&) = default;
|
|
//~status_bitfield_type() = default; // Do NOT uncomment this, it breaks older clangs!
|
|
constexpr bool have_value() const noexcept
|
|
{
|
|
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_value)) != 0;
|
|
}
|
|
constexpr bool have_error() const noexcept
|
|
{
|
|
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error)) != 0;
|
|
}
|
|
constexpr bool have_exception() const noexcept
|
|
{
|
|
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_exception)) != 0;
|
|
}
|
|
constexpr bool have_lost_consistency() const noexcept
|
|
{
|
|
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_lost_consistency)) != 0;
|
|
}
|
|
constexpr bool have_error_is_errno() const noexcept
|
|
{
|
|
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_error_is_errno)) != 0;
|
|
}
|
|
constexpr bool have_moved_from() const noexcept
|
|
{
|
|
return (static_cast<uint16_t>(status_value) & static_cast<uint16_t>(status::have_moved_from)) != 0;
|
|
}
|
|
constexpr status_bitfield_type &set_have_value(bool v) noexcept
|
|
{
|
|
status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_value)) :
|
|
(static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_value)));
|
|
return *this;
|
|
}
|
|
constexpr status_bitfield_type &set_have_error(bool v) noexcept
|
|
{
|
|
status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_error)) :
|
|
(static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_error)));
|
|
return *this;
|
|
}
|
|
constexpr status_bitfield_type &set_have_exception(bool v) noexcept
|
|
{
|
|
status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_exception)) :
|
|
(static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_exception)));
|
|
return *this;
|
|
}
|
|
constexpr status_bitfield_type &set_have_error_is_errno(bool v) noexcept
|
|
{
|
|
status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_error_is_errno)) :
|
|
(static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_error_is_errno)));
|
|
return *this;
|
|
}
|
|
constexpr status_bitfield_type &set_have_lost_consistency(bool v) noexcept
|
|
{
|
|
status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_lost_consistency)) :
|
|
(static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_lost_consistency)));
|
|
return *this;
|
|
}
|
|
constexpr status_bitfield_type &set_have_moved_from(bool v) noexcept
|
|
{
|
|
status_value = static_cast<status>(v ? (static_cast<uint16_t>(status_value) | static_cast<uint16_t>(status::have_moved_from)) :
|
|
(static_cast<uint16_t>(status_value) & ~static_cast<uint16_t>(status::have_moved_from)));
|
|
return *this;
|
|
}
|
|
};
|
|
#if !defined(NDEBUG)
|
|
// Check is trivial in all ways except default constructibility
|
|
static_assert(sizeof(status_bitfield_type) == 4, "status_bitfield_type is not sized 4 bytes!");
|
|
static_assert(std::is_trivially_copyable<status_bitfield_type>::value, "status_bitfield_type is not trivially copyable!");
|
|
static_assert(std::is_trivially_assignable<status_bitfield_type, status_bitfield_type>::value, "status_bitfield_type is not trivially assignable!");
|
|
static_assert(std::is_trivially_destructible<status_bitfield_type>::value, "status_bitfield_type is not trivially destructible!");
|
|
static_assert(std::is_trivially_copy_constructible<status_bitfield_type>::value, "status_bitfield_type is not trivially copy constructible!");
|
|
static_assert(std::is_trivially_move_constructible<status_bitfield_type>::value, "status_bitfield_type is not trivially move constructible!");
|
|
static_assert(std::is_trivially_copy_assignable<status_bitfield_type>::value, "status_bitfield_type is not trivially copy assignable!");
|
|
static_assert(std::is_trivially_move_assignable<status_bitfield_type>::value, "status_bitfield_type is not trivially move assignable!");
|
|
// Also check is standard layout
|
|
static_assert(std::is_standard_layout<status_bitfield_type>::value, "status_bitfield_type is not a standard layout type!");
|
|
#endif
|
|
template <class State> constexpr inline void _set_error_is_errno(State & /*unused*/) {}
|
|
#ifdef _MSC_VER
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 4127) // conditional expression is constant
|
|
#pragma warning(disable : 4624) // destructor was implicitly defined as deleted
|
|
#endif
|
|
// Used if both T and E are trivial
|
|
template <class T, class E> struct value_storage_trivial
|
|
{
|
|
using value_type = T;
|
|
using error_type = E;
|
|
// Disable in place construction if they are the same type
|
|
struct disable_in_place_value_type
|
|
{
|
|
};
|
|
struct disable_in_place_error_type
|
|
{
|
|
};
|
|
using _value_type = std::conditional_t<std::is_same<value_type, error_type>::value, disable_in_place_value_type, value_type>;
|
|
using _error_type = std::conditional_t<std::is_same<value_type, error_type>::value, disable_in_place_error_type, error_type>;
|
|
using _value_type_ = devoid<value_type>;
|
|
using _error_type_ = devoid<error_type>;
|
|
union
|
|
{
|
|
empty_type _empty;
|
|
_value_type_ _value;
|
|
_error_type_ _error;
|
|
};
|
|
status_bitfield_type _status;
|
|
constexpr value_storage_trivial() noexcept
|
|
: _empty{}
|
|
{
|
|
}
|
|
value_storage_trivial(const value_storage_trivial &) = default; // NOLINT
|
|
value_storage_trivial(value_storage_trivial &&) = default; // NOLINT
|
|
value_storage_trivial &operator=(const value_storage_trivial &) = default; // NOLINT
|
|
value_storage_trivial &operator=(value_storage_trivial &&) = default; // NOLINT
|
|
~value_storage_trivial() = default;
|
|
constexpr explicit value_storage_trivial(status_bitfield_type status)
|
|
: _empty()
|
|
, _status(status)
|
|
{
|
|
}
|
|
template <class... Args>
|
|
constexpr explicit value_storage_trivial(in_place_type_t<_value_type> /*unused*/,
|
|
Args &&...args) noexcept(detail::is_nothrow_constructible<_value_type_, Args...>)
|
|
: _value(static_cast<Args &&>(args)...)
|
|
, _status(status::have_value)
|
|
{
|
|
}
|
|
template <class U, class... Args>
|
|
constexpr value_storage_trivial(in_place_type_t<_value_type> /*unused*/, std::initializer_list<U> il,
|
|
Args &&...args) noexcept(detail::is_nothrow_constructible<_value_type_, std::initializer_list<U>, Args...>)
|
|
: _value(il, static_cast<Args &&>(args)...)
|
|
, _status(status::have_value)
|
|
{
|
|
}
|
|
template <class... Args>
|
|
constexpr explicit value_storage_trivial(in_place_type_t<_error_type> /*unused*/,
|
|
Args &&...args) noexcept(detail::is_nothrow_constructible<_error_type_, Args...>)
|
|
: _error(static_cast<Args &&>(args)...)
|
|
, _status(status::have_error)
|
|
{
|
|
_set_error_is_errno(*this);
|
|
}
|
|
template <class U, class... Args>
|
|
constexpr value_storage_trivial(in_place_type_t<_error_type> /*unused*/, std::initializer_list<U> il,
|
|
Args &&...args) noexcept(detail::is_nothrow_constructible<_error_type_, std::initializer_list<U>, Args...>)
|
|
: _error(il, static_cast<Args &&>(args)...)
|
|
, _status(status::have_error)
|
|
{
|
|
_set_error_is_errno(*this);
|
|
}
|
|
struct nonvoid_converting_constructor_tag
|
|
{
|
|
};
|
|
template <class U, class V>
|
|
static constexpr bool enable_nonvoid_converting_constructor =
|
|
!(std::is_same<std::decay_t<U>, value_type>::value && std::is_same<std::decay_t<V>, error_type>::value) //
|
|
&& detail::is_constructible<value_type, U> && detail::is_constructible<error_type, V>;
|
|
OUTCOME_TEMPLATE(class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(enable_nonvoid_converting_constructor<U, V>))
|
|
constexpr explicit value_storage_trivial(const value_storage_trivial<U, V> &o, nonvoid_converting_constructor_tag /*unused*/ = {}) noexcept(
|
|
detail::is_nothrow_constructible<_value_type_, U> &&detail::is_nothrow_constructible<_error_type_, V>)
|
|
: value_storage_trivial(o._status.have_value() ?
|
|
value_storage_trivial(in_place_type<value_type>, o._value) :
|
|
(o._status.have_error() ? value_storage_trivial(in_place_type<error_type>, o._error) : value_storage_trivial())) // NOLINT
|
|
{
|
|
_status = o._status;
|
|
}
|
|
OUTCOME_TEMPLATE(class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(enable_nonvoid_converting_constructor<U, V>))
|
|
constexpr explicit value_storage_trivial(value_storage_trivial<U, V> &&o, nonvoid_converting_constructor_tag /*unused*/ = {}) noexcept(
|
|
detail::is_nothrow_constructible<_value_type_, U> &&detail::is_nothrow_constructible<_error_type_, V>)
|
|
: value_storage_trivial(
|
|
o._status.have_value() ?
|
|
value_storage_trivial(in_place_type<value_type>, static_cast<U &&>(o._value)) :
|
|
(o._status.have_error() ? value_storage_trivial(in_place_type<error_type>, static_cast<V &&>(o._error)) : value_storage_trivial())) // NOLINT
|
|
{
|
|
_status = o._status;
|
|
}
|
|
struct void_value_converting_constructor_tag
|
|
{
|
|
};
|
|
template <class V>
|
|
static constexpr bool enable_void_value_converting_constructor = std::is_default_constructible<value_type>::value &&detail::is_constructible<error_type, V>;
|
|
OUTCOME_TEMPLATE(class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(enable_void_value_converting_constructor<V>))
|
|
constexpr explicit value_storage_trivial(const value_storage_trivial<void, V> &o, void_value_converting_constructor_tag /*unused*/ = {}) noexcept(
|
|
std::is_nothrow_default_constructible<_value_type_>::value &&detail::is_nothrow_constructible<_error_type_, V>)
|
|
: value_storage_trivial(o._status.have_value() ?
|
|
value_storage_trivial(in_place_type<value_type>) :
|
|
(o._status.have_error() ? value_storage_trivial(in_place_type<error_type>, o._error) : value_storage_trivial())) // NOLINT
|
|
{
|
|
_status = o._status;
|
|
}
|
|
OUTCOME_TEMPLATE(class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(enable_void_value_converting_constructor<V>))
|
|
constexpr explicit value_storage_trivial(value_storage_trivial<void, V> &&o, void_value_converting_constructor_tag /*unused*/ = {}) noexcept(
|
|
std::is_nothrow_default_constructible<_value_type_>::value &&detail::is_nothrow_constructible<_error_type_, V>)
|
|
: value_storage_trivial(
|
|
o._status.have_value() ?
|
|
value_storage_trivial(in_place_type<value_type>) :
|
|
(o._status.have_error() ? value_storage_trivial(in_place_type<error_type>, static_cast<V &&>(o._error)) : value_storage_trivial())) // NOLINT
|
|
{
|
|
_status = o._status;
|
|
}
|
|
struct void_error_converting_constructor_tag
|
|
{
|
|
};
|
|
template <class U>
|
|
static constexpr bool enable_void_error_converting_constructor = std::is_default_constructible<error_type>::value &&detail::is_constructible<value_type, U>;
|
|
OUTCOME_TEMPLATE(class U)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(enable_void_error_converting_constructor<U>))
|
|
constexpr explicit value_storage_trivial(const value_storage_trivial<U, void> &o, void_error_converting_constructor_tag /*unused*/ = {}) noexcept(
|
|
detail::is_nothrow_constructible<_value_type_, U> &&std::is_nothrow_default_constructible<_error_type_>::value)
|
|
: value_storage_trivial(o._status.have_value() ?
|
|
value_storage_trivial(in_place_type<value_type>, o._value) :
|
|
(o._status.have_error() ? value_storage_trivial(in_place_type<error_type>) : value_storage_trivial())) // NOLINT
|
|
{
|
|
_status = o._status;
|
|
}
|
|
OUTCOME_TEMPLATE(class U)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(enable_void_error_converting_constructor<U>))
|
|
constexpr explicit value_storage_trivial(value_storage_trivial<U, void> &&o, void_error_converting_constructor_tag /*unused*/ = {}) noexcept(
|
|
detail::is_nothrow_constructible<_value_type_, U> &&std::is_nothrow_default_constructible<_error_type_>::value)
|
|
: value_storage_trivial(o._status.have_value() ?
|
|
value_storage_trivial(in_place_type<value_type>, static_cast<U &&>(o._value)) :
|
|
(o._status.have_error() ? value_storage_trivial(in_place_type<error_type>) : value_storage_trivial())) // NOLINT
|
|
{
|
|
_status = o._status;
|
|
}
|
|
constexpr void swap(value_storage_trivial &o) noexcept
|
|
{
|
|
// storage is trivial, so just use assignment
|
|
auto temp = static_cast<value_storage_trivial &&>(*this);
|
|
*this = static_cast<value_storage_trivial &&>(o);
|
|
o = static_cast<value_storage_trivial &&>(temp);
|
|
}
|
|
};
|
|
/* Used if T or E is non-trivial. The additional constexpr is injected in C++ 20 to enable Outcome to
|
|
work in constexpr evaluation contexts in C++ 20 where non-trivial constexpr destructors are now allowed.
|
|
*/
|
|
template <class T, class E> struct value_storage_nontrivial
|
|
{
|
|
using value_type = T;
|
|
using error_type = E;
|
|
struct disable_in_place_value_type
|
|
{
|
|
};
|
|
struct disable_in_place_error_type
|
|
{
|
|
};
|
|
using _value_type = std::conditional_t<std::is_same<value_type, error_type>::value, disable_in_place_value_type, value_type>;
|
|
using _error_type = std::conditional_t<std::is_same<value_type, error_type>::value, disable_in_place_error_type, error_type>;
|
|
using _value_type_ = devoid<value_type>;
|
|
using _error_type_ = devoid<error_type>;
|
|
union
|
|
{
|
|
empty_type _empty1;
|
|
_value_type_ _value;
|
|
};
|
|
status_bitfield_type _status;
|
|
union
|
|
{
|
|
empty_type _empty2;
|
|
_error_type_ _error;
|
|
};
|
|
#if __cplusplus >= 202000 || _HAS_CXX20
|
|
constexpr
|
|
#endif
|
|
value_storage_nontrivial() noexcept
|
|
: _empty1{}
|
|
, _empty2{}
|
|
{
|
|
}
|
|
value_storage_nontrivial &operator=(const value_storage_nontrivial &) = default; // if reaches here, copy assignment is trivial
|
|
value_storage_nontrivial &operator=(value_storage_nontrivial &&) = default; // NOLINT if reaches here, move assignment is trivial
|
|
#if __cplusplus >= 202000 || _HAS_CXX20
|
|
constexpr
|
|
#endif
|
|
value_storage_nontrivial(value_storage_nontrivial &&o) noexcept(
|
|
std::is_nothrow_move_constructible<_value_type_>::value &&std::is_nothrow_move_constructible<_error_type_>::value) // NOLINT
|
|
{
|
|
if(o._status.have_value())
|
|
{
|
|
new(&_value) _value_type_(static_cast<_value_type_ &&>(o._value)); // NOLINT
|
|
}
|
|
else if(o._status.have_error())
|
|
{
|
|
new(&_error) _error_type_(static_cast<_error_type_ &&>(o._error)); // NOLINT
|
|
}
|
|
_status = o._status;
|
|
o._status.set_have_moved_from(true);
|
|
}
|
|
#if __cplusplus >= 202000 || _HAS_CXX20
|
|
constexpr
|
|
#endif
|
|
value_storage_nontrivial(const value_storage_nontrivial &o) noexcept(
|
|
std::is_nothrow_copy_constructible<_value_type_>::value &&std::is_nothrow_copy_constructible<_error_type_>::value)
|
|
{
|
|
if(o._status.have_value())
|
|
{
|
|
new(&_value) _value_type_(o._value); // NOLINT
|
|
}
|
|
else if(o._status.have_error())
|
|
{
|
|
new(&_error) _error_type_(o._error); // NOLINT
|
|
}
|
|
_status = o._status;
|
|
}
|
|
#if __cplusplus >= 202000 || _HAS_CXX20
|
|
constexpr
|
|
#endif
|
|
explicit value_storage_nontrivial(status_bitfield_type status)
|
|
: _empty1()
|
|
, _status(status)
|
|
, _empty2()
|
|
{
|
|
}
|
|
template <class... Args>
|
|
constexpr explicit value_storage_nontrivial(in_place_type_t<_value_type> /*unused*/,
|
|
Args &&...args) noexcept(detail::is_nothrow_constructible<_value_type_, Args...>)
|
|
: _value(static_cast<Args &&>(args)...) // NOLINT
|
|
, _status(status::have_value)
|
|
{
|
|
}
|
|
template <class U, class... Args>
|
|
constexpr value_storage_nontrivial(in_place_type_t<_value_type> /*unused*/, std::initializer_list<U> il,
|
|
Args &&...args) noexcept(detail::is_nothrow_constructible<_value_type_, std::initializer_list<U>, Args...>)
|
|
: _value(il, static_cast<Args &&>(args)...)
|
|
, _status(status::have_value)
|
|
{
|
|
}
|
|
template <class... Args>
|
|
constexpr explicit value_storage_nontrivial(in_place_type_t<_error_type> /*unused*/,
|
|
Args &&...args) noexcept(detail::is_nothrow_constructible<_error_type_, Args...>)
|
|
: _status(status::have_error)
|
|
, _error(static_cast<Args &&>(args)...) // NOLINT
|
|
{
|
|
_set_error_is_errno(*this);
|
|
}
|
|
template <class U, class... Args>
|
|
constexpr value_storage_nontrivial(in_place_type_t<_error_type> /*unused*/, std::initializer_list<U> il,
|
|
Args &&...args) noexcept(detail::is_nothrow_constructible<_error_type_, std::initializer_list<U>, Args...>)
|
|
: _status(status::have_error)
|
|
, _error(il, static_cast<Args &&>(args)...)
|
|
{
|
|
_set_error_is_errno(*this);
|
|
}
|
|
struct nonvoid_converting_constructor_tag
|
|
{
|
|
};
|
|
template <class U, class V>
|
|
static constexpr bool enable_nonvoid_converting_constructor =
|
|
!(std::is_same<std::decay_t<U>, value_type>::value && std::is_same<std::decay_t<V>, error_type>::value) //
|
|
&& detail::is_constructible<value_type, U> && detail::is_constructible<error_type, V>;
|
|
OUTCOME_TEMPLATE(class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(enable_nonvoid_converting_constructor<U, V>))
|
|
constexpr explicit value_storage_nontrivial(const value_storage_trivial<U, V> &o, nonvoid_converting_constructor_tag /*unused*/ = {}) noexcept(
|
|
detail::is_nothrow_constructible<_value_type_, U> &&detail::is_nothrow_constructible<_error_type_, V>)
|
|
: value_storage_nontrivial(o._status.have_value() ?
|
|
value_storage_nontrivial(in_place_type<value_type>, o._value) :
|
|
(o._status.have_error() ? value_storage_nontrivial(in_place_type<error_type>, o._error) : value_storage_nontrivial()))
|
|
{
|
|
_status = o._status;
|
|
}
|
|
OUTCOME_TEMPLATE(class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(enable_nonvoid_converting_constructor<U, V>))
|
|
constexpr explicit value_storage_nontrivial(value_storage_trivial<U, V> &&o, nonvoid_converting_constructor_tag /*unused*/ = {}) noexcept(
|
|
detail::is_nothrow_constructible<_value_type_, U> &&detail::is_nothrow_constructible<_error_type_, V>)
|
|
: value_storage_nontrivial(
|
|
o._status.have_value() ?
|
|
value_storage_nontrivial(in_place_type<value_type>, static_cast<U &&>(o._value)) :
|
|
(o._status.have_error() ? value_storage_nontrivial(in_place_type<error_type>, static_cast<V &&>(o._error)) : value_storage_nontrivial()))
|
|
{
|
|
_status = o._status;
|
|
}
|
|
OUTCOME_TEMPLATE(class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(enable_nonvoid_converting_constructor<U, V>))
|
|
constexpr explicit value_storage_nontrivial(const value_storage_nontrivial<U, V> &o, nonvoid_converting_constructor_tag /*unused*/ = {}) noexcept(
|
|
detail::is_nothrow_constructible<_value_type_, U> &&detail::is_nothrow_constructible<_error_type_, V>)
|
|
: value_storage_nontrivial(o._status.have_value() ?
|
|
value_storage_nontrivial(in_place_type<value_type>, o._value) :
|
|
(o._status.have_error() ? value_storage_nontrivial(in_place_type<error_type>, o._error) : value_storage_nontrivial()))
|
|
{
|
|
_status = o._status;
|
|
}
|
|
OUTCOME_TEMPLATE(class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(enable_nonvoid_converting_constructor<U, V>))
|
|
constexpr explicit value_storage_nontrivial(value_storage_nontrivial<U, V> &&o, nonvoid_converting_constructor_tag /*unused*/ = {}) noexcept(
|
|
detail::is_nothrow_constructible<_value_type_, U> &&detail::is_nothrow_constructible<_error_type_, V>)
|
|
: value_storage_nontrivial(
|
|
o._status.have_value() ?
|
|
value_storage_nontrivial(in_place_type<value_type>, static_cast<U &&>(o._value)) :
|
|
(o._status.have_error() ? value_storage_nontrivial(in_place_type<error_type>, static_cast<V &&>(o._error)) : value_storage_nontrivial()))
|
|
{
|
|
_status = o._status;
|
|
}
|
|
struct void_value_converting_constructor_tag
|
|
{
|
|
};
|
|
template <class V>
|
|
static constexpr bool enable_void_value_converting_constructor = std::is_default_constructible<value_type>::value &&detail::is_constructible<error_type, V>;
|
|
OUTCOME_TEMPLATE(class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(enable_void_value_converting_constructor<V>))
|
|
constexpr explicit value_storage_nontrivial(const value_storage_trivial<void, V> &o, void_value_converting_constructor_tag /*unused*/ = {}) noexcept(
|
|
std::is_nothrow_default_constructible<_value_type_>::value &&detail::is_nothrow_constructible<_error_type_, V>)
|
|
{
|
|
if(o._status.have_value())
|
|
{
|
|
new(&_value) _value_type_(); // NOLINT
|
|
}
|
|
else if(o._status.have_error())
|
|
{
|
|
new(&_error) _error_type_(o._error); // NOLINT
|
|
}
|
|
_status = o._status;
|
|
}
|
|
OUTCOME_TEMPLATE(class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(enable_void_value_converting_constructor<V>))
|
|
constexpr explicit value_storage_nontrivial(value_storage_trivial<void, V> &&o, void_value_converting_constructor_tag /*unused*/ = {}) noexcept(
|
|
std::is_nothrow_default_constructible<_value_type_>::value &&detail::is_nothrow_constructible<_error_type_, V>)
|
|
{
|
|
if(o._status.have_value())
|
|
{
|
|
new(&_value) _value_type_(); // NOLINT
|
|
}
|
|
else if(o._status.have_error())
|
|
{
|
|
new(&_error) _error_type_(static_cast<_error_type_ &&>(o._error)); // NOLINT
|
|
}
|
|
_status = o._status;
|
|
o._status.set_have_moved_from(true);
|
|
}
|
|
struct void_error_converting_constructor_tag
|
|
{
|
|
};
|
|
template <class U>
|
|
static constexpr bool enable_void_error_converting_constructor = std::is_default_constructible<error_type>::value &&detail::is_constructible<value_type, U>;
|
|
OUTCOME_TEMPLATE(class U)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(enable_void_error_converting_constructor<U>))
|
|
constexpr explicit value_storage_nontrivial(const value_storage_trivial<U, void> &o, void_error_converting_constructor_tag /*unused*/ = {}) noexcept(
|
|
detail::is_nothrow_constructible<_value_type_, U> &&std::is_nothrow_default_constructible<_error_type_>::value)
|
|
{
|
|
if(o._status.have_value())
|
|
{
|
|
new(&_value) _value_type_(o._value); // NOLINT
|
|
}
|
|
else if(o._status.have_error())
|
|
{
|
|
new(&_error) _error_type_(); // NOLINT
|
|
}
|
|
_status = o._status;
|
|
}
|
|
OUTCOME_TEMPLATE(class U)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(enable_void_error_converting_constructor<U>))
|
|
constexpr explicit value_storage_nontrivial(value_storage_trivial<U, void> &&o, void_error_converting_constructor_tag /*unused*/ = {}) noexcept(
|
|
detail::is_nothrow_constructible<_value_type_, U> &&std::is_nothrow_default_constructible<_error_type_>::value)
|
|
{
|
|
if(o._status.have_value())
|
|
{
|
|
new(&_value) _value_type_(static_cast<_value_type_ &&>(o._value)); // NOLINT
|
|
}
|
|
else if(o._status.have_error())
|
|
{
|
|
new(&_error) _error_type_(); // NOLINT
|
|
}
|
|
_status = o._status;
|
|
o._status.set_have_moved_from(true);
|
|
}
|
|
#if __cplusplus >= 202000 || _HAS_CXX20
|
|
constexpr
|
|
#endif
|
|
~value_storage_nontrivial() noexcept(std::is_nothrow_destructible<_value_type_>::value &&std::is_nothrow_destructible<_error_type_>::value)
|
|
{
|
|
if(this->_status.have_value())
|
|
{
|
|
if(!trait::is_move_bitcopying<value_type>::value || !this->_status.have_moved_from())
|
|
{
|
|
this->_value.~_value_type_(); // NOLINT
|
|
}
|
|
this->_status.set_have_value(false);
|
|
}
|
|
else if(this->_status.have_error())
|
|
{
|
|
if(!trait::is_move_bitcopying<error_type>::value || !this->_status.have_moved_from())
|
|
{
|
|
this->_error.~_error_type_(); // NOLINT
|
|
}
|
|
this->_status.set_have_error(false);
|
|
}
|
|
}
|
|
#if __cplusplus >= 202000 || _HAS_CXX20
|
|
constexpr
|
|
#endif
|
|
void
|
|
swap(value_storage_nontrivial &o) noexcept(detail::is_nothrow_swappable<_value_type_>::value &&detail::is_nothrow_swappable<_error_type_>::value)
|
|
{
|
|
using std::swap;
|
|
// empty/empty
|
|
if(!_status.have_value() && !o._status.have_value() && !_status.have_error() && !o._status.have_error())
|
|
{
|
|
swap(_status, o._status);
|
|
return;
|
|
}
|
|
// value/value
|
|
if(_status.have_value() && o._status.have_value())
|
|
{
|
|
struct _
|
|
{
|
|
status_bitfield_type &a, &b;
|
|
bool all_good{false};
|
|
~_()
|
|
{
|
|
if(!all_good)
|
|
{
|
|
// We lost one of the values
|
|
a.set_have_lost_consistency(true);
|
|
b.set_have_lost_consistency(true);
|
|
}
|
|
}
|
|
} _{_status, o._status};
|
|
strong_swap(_.all_good, _value, o._value);
|
|
swap(_status, o._status);
|
|
return;
|
|
}
|
|
// error/error
|
|
if(_status.have_error() && o._status.have_error())
|
|
{
|
|
struct _
|
|
{
|
|
status_bitfield_type &a, &b;
|
|
bool all_good{false};
|
|
~_()
|
|
{
|
|
if(!all_good)
|
|
{
|
|
// We lost one of the values
|
|
a.set_have_lost_consistency(true);
|
|
b.set_have_lost_consistency(true);
|
|
}
|
|
}
|
|
} _{_status, o._status};
|
|
strong_swap(_.all_good, _error, o._error);
|
|
swap(_status, o._status);
|
|
return;
|
|
}
|
|
// Could be value/empty, error/empty, etc
|
|
if(_status.have_value() && !o._status.have_error())
|
|
{
|
|
// Move construct me into other
|
|
new(&o._value) _value_type_(static_cast<_value_type_ &&>(_value)); // NOLINT
|
|
if(!trait::is_move_bitcopying<value_type>::value)
|
|
{
|
|
this->_value.~value_type(); // NOLINT
|
|
}
|
|
swap(_status, o._status);
|
|
return;
|
|
}
|
|
if(o._status.have_value() && !_status.have_error())
|
|
{
|
|
// Move construct other into me
|
|
new(&_value) _value_type_(static_cast<_value_type_ &&>(o._value)); // NOLINT
|
|
if(!trait::is_move_bitcopying<value_type>::value)
|
|
{
|
|
o._value.~value_type(); // NOLINT
|
|
}
|
|
swap(_status, o._status);
|
|
return;
|
|
}
|
|
if(_status.have_error() && !o._status.have_value())
|
|
{
|
|
// Move construct me into other
|
|
new(&o._error) _error_type_(static_cast<_error_type_ &&>(_error)); // NOLINT
|
|
if(!trait::is_move_bitcopying<error_type>::value)
|
|
{
|
|
this->_error.~error_type(); // NOLINT
|
|
}
|
|
swap(_status, o._status);
|
|
return;
|
|
}
|
|
if(o._status.have_error() && !_status.have_value())
|
|
{
|
|
// Move construct other into me
|
|
new(&_error) _error_type_(static_cast<_error_type_ &&>(o._error)); // NOLINT
|
|
if(!trait::is_move_bitcopying<error_type>::value)
|
|
{
|
|
o._error.~error_type(); // NOLINT
|
|
}
|
|
swap(_status, o._status);
|
|
return;
|
|
}
|
|
// It can now only be value/error, or error/value
|
|
struct _
|
|
{
|
|
status_bitfield_type &a, &b;
|
|
_value_type_ *value, *o_value;
|
|
_error_type_ *error, *o_error;
|
|
bool all_good{true};
|
|
~_()
|
|
{
|
|
if(!all_good)
|
|
{
|
|
// We lost one of the values
|
|
a.set_have_lost_consistency(true);
|
|
b.set_have_lost_consistency(true);
|
|
}
|
|
}
|
|
} _{_status, o._status, &_value, &o._value, &_error, &o._error};
|
|
if(_status.have_value() && o._status.have_error())
|
|
{
|
|
strong_placement(_.all_good, _.o_value, _.value, [&_] { //
|
|
strong_placement(_.all_good, _.error, _.o_error, [&_] { //
|
|
swap(_.a, _.b); //
|
|
});
|
|
});
|
|
return;
|
|
}
|
|
if(_status.have_error() && o._status.have_value())
|
|
{
|
|
strong_placement(_.all_good, _.o_error, _.error, [&_] { //
|
|
strong_placement(_.all_good, _.value, _.o_value, [&_] { //
|
|
swap(_.a, _.b); //
|
|
});
|
|
});
|
|
return;
|
|
}
|
|
// Should never reach here
|
|
make_ub(_value);
|
|
}
|
|
};
|
|
template <class Base> struct value_storage_delete_copy_constructor : Base // NOLINT
|
|
{
|
|
using Base::Base;
|
|
using value_type = typename Base::value_type;
|
|
using error_type = typename Base::error_type;
|
|
value_storage_delete_copy_constructor() = default;
|
|
value_storage_delete_copy_constructor(const value_storage_delete_copy_constructor &) = delete;
|
|
value_storage_delete_copy_constructor(value_storage_delete_copy_constructor &&) = default; // NOLINT
|
|
};
|
|
template <class Base> struct value_storage_delete_copy_assignment : Base // NOLINT
|
|
{
|
|
using Base::Base;
|
|
using value_type = typename Base::value_type;
|
|
using error_type = typename Base::error_type;
|
|
value_storage_delete_copy_assignment() = default;
|
|
value_storage_delete_copy_assignment(const value_storage_delete_copy_assignment &) = default;
|
|
value_storage_delete_copy_assignment(value_storage_delete_copy_assignment &&) = default; // NOLINT
|
|
value_storage_delete_copy_assignment &operator=(const value_storage_delete_copy_assignment &o) = delete;
|
|
value_storage_delete_copy_assignment &operator=(value_storage_delete_copy_assignment &&o) = default; // NOLINT
|
|
};
|
|
template <class Base> struct value_storage_delete_move_assignment : Base // NOLINT
|
|
{
|
|
using Base::Base;
|
|
using value_type = typename Base::value_type;
|
|
using error_type = typename Base::error_type;
|
|
value_storage_delete_move_assignment() = default;
|
|
value_storage_delete_move_assignment(const value_storage_delete_move_assignment &) = default;
|
|
value_storage_delete_move_assignment(value_storage_delete_move_assignment &&) = default; // NOLINT
|
|
value_storage_delete_move_assignment &operator=(const value_storage_delete_move_assignment &o) = default;
|
|
value_storage_delete_move_assignment &operator=(value_storage_delete_move_assignment &&o) = delete;
|
|
};
|
|
template <class Base> struct value_storage_delete_move_constructor : Base // NOLINT
|
|
{
|
|
using Base::Base;
|
|
using value_type = typename Base::value_type;
|
|
using error_type = typename Base::error_type;
|
|
value_storage_delete_move_constructor() = default;
|
|
value_storage_delete_move_constructor(const value_storage_delete_move_constructor &) = default;
|
|
value_storage_delete_move_constructor(value_storage_delete_move_constructor &&) = delete;
|
|
};
|
|
template <class Base> struct value_storage_nontrivial_move_assignment : Base // NOLINT
|
|
{
|
|
using Base::Base;
|
|
using value_type = typename Base::value_type;
|
|
using error_type = typename Base::error_type;
|
|
value_storage_nontrivial_move_assignment() = default;
|
|
value_storage_nontrivial_move_assignment(const value_storage_nontrivial_move_assignment &) = default;
|
|
value_storage_nontrivial_move_assignment(value_storage_nontrivial_move_assignment &&) = default; // NOLINT
|
|
value_storage_nontrivial_move_assignment &operator=(const value_storage_nontrivial_move_assignment &o) = default;
|
|
#if __cplusplus >= 202000 || _HAS_CXX20
|
|
constexpr
|
|
#endif
|
|
value_storage_nontrivial_move_assignment &
|
|
operator=(value_storage_nontrivial_move_assignment &&o) noexcept(
|
|
std::is_nothrow_move_assignable<value_type>::value &&std::is_nothrow_move_assignable<error_type>::value) // NOLINT
|
|
{
|
|
using _value_type_ = typename Base::_value_type_;
|
|
using _error_type_ = typename Base::_error_type_;
|
|
if(!this->_status.have_value() && !this->_status.have_error() && !o._status.have_value() && !o._status.have_error())
|
|
{
|
|
this->_status = o._status;
|
|
o._status.set_have_moved_from(true);
|
|
return *this;
|
|
}
|
|
if(this->_status.have_value() && o._status.have_value())
|
|
{
|
|
this->_value = static_cast<_value_type_ &&>(o._value); // NOLINT
|
|
this->_status = o._status;
|
|
o._status.set_have_moved_from(true);
|
|
return *this;
|
|
}
|
|
if(this->_status.have_error() && o._status.have_error())
|
|
{
|
|
this->_error = static_cast<_error_type_ &&>(o._error); // NOLINT
|
|
this->_status = o._status;
|
|
o._status.set_have_moved_from(true);
|
|
return *this;
|
|
}
|
|
if(this->_status.have_value() && !o._status.have_value() && !o._status.have_error())
|
|
{
|
|
if(!trait::is_move_bitcopying<value_type>::value || this->_status.have_moved_from())
|
|
{
|
|
this->_value.~_value_type_(); // NOLINT
|
|
}
|
|
this->_status = o._status;
|
|
o._status.set_have_moved_from(true);
|
|
return *this;
|
|
}
|
|
if(!this->_status.have_value() && !this->_status.have_error() && o._status.have_value())
|
|
{
|
|
new(&this->_value) _value_type_(static_cast<_value_type_ &&>(o._value)); // NOLINT
|
|
this->_status = o._status;
|
|
o._status.set_have_moved_from(true);
|
|
return *this;
|
|
}
|
|
if(this->_status.have_error() && !o._status.have_value() && !o._status.have_error())
|
|
{
|
|
if(!trait::is_move_bitcopying<error_type>::value || this->_status.have_moved_from())
|
|
{
|
|
this->_error.~_error_type_(); // NOLINT
|
|
}
|
|
this->_status = o._status;
|
|
o._status.set_have_moved_from(true);
|
|
return *this;
|
|
}
|
|
if(!this->_status.have_value() && !this->_status.have_error() && o._status.have_error())
|
|
{
|
|
new(&this->_error) _error_type_(static_cast<_error_type_ &&>(o._error)); // NOLINT
|
|
this->_status = o._status;
|
|
o._status.set_have_moved_from(true);
|
|
return *this;
|
|
}
|
|
if(this->_status.have_value() && o._status.have_error())
|
|
{
|
|
if(!trait::is_move_bitcopying<value_type>::value || this->_status.have_moved_from())
|
|
{
|
|
this->_value.~_value_type_(); // NOLINT
|
|
}
|
|
new(&this->_error) _error_type_(static_cast<_error_type_ &&>(o._error)); // NOLINT
|
|
this->_status = o._status;
|
|
o._status.set_have_moved_from(true);
|
|
return *this;
|
|
}
|
|
if(this->_status.have_error() && o._status.have_value())
|
|
{
|
|
if(!trait::is_move_bitcopying<error_type>::value || this->_status.have_moved_from())
|
|
{
|
|
this->_error.~_error_type_(); // NOLINT
|
|
}
|
|
new(&this->_value) _value_type_(static_cast<_value_type_ &&>(o._value)); // NOLINT
|
|
this->_status = o._status;
|
|
o._status.set_have_moved_from(true);
|
|
return *this;
|
|
}
|
|
// Should never reach here
|
|
make_ub(this->_value);
|
|
}
|
|
};
|
|
template <class Base> struct value_storage_nontrivial_copy_assignment : Base // NOLINT
|
|
{
|
|
using Base::Base;
|
|
using value_type = typename Base::value_type;
|
|
using error_type = typename Base::error_type;
|
|
value_storage_nontrivial_copy_assignment() = default;
|
|
value_storage_nontrivial_copy_assignment(const value_storage_nontrivial_copy_assignment &) = default;
|
|
value_storage_nontrivial_copy_assignment(value_storage_nontrivial_copy_assignment &&) = default; // NOLINT
|
|
value_storage_nontrivial_copy_assignment &operator=(value_storage_nontrivial_copy_assignment &&o) = default; // NOLINT
|
|
#if __cplusplus >= 202000 || _HAS_CXX20
|
|
constexpr
|
|
#endif
|
|
value_storage_nontrivial_copy_assignment &
|
|
operator=(const value_storage_nontrivial_copy_assignment &o) noexcept(
|
|
std::is_nothrow_copy_assignable<value_type>::value &&std::is_nothrow_copy_assignable<error_type>::value)
|
|
{
|
|
using _value_type_ = typename Base::_value_type_;
|
|
using _error_type_ = typename Base::_error_type_;
|
|
if(!this->_status.have_value() && !this->_status.have_error() && !o._status.have_value() && !o._status.have_error())
|
|
{
|
|
this->_status = o._status;
|
|
return *this;
|
|
}
|
|
if(this->_status.have_value() && o._status.have_value())
|
|
{
|
|
this->_value = o._value; // NOLINT
|
|
this->_status = o._status;
|
|
return *this;
|
|
}
|
|
if(this->_status.have_error() && o._status.have_error())
|
|
{
|
|
this->_error = o._error; // NOLINT
|
|
this->_status = o._status;
|
|
return *this;
|
|
}
|
|
if(this->_status.have_value() && !o._status.have_value() && !o._status.have_error())
|
|
{
|
|
if(!trait::is_move_bitcopying<value_type>::value || this->_status.have_moved_from())
|
|
{
|
|
this->_value.~_value_type_(); // NOLINT
|
|
}
|
|
this->_status = o._status;
|
|
return *this;
|
|
}
|
|
if(!this->_status.have_value() && !this->_status.have_error() && o._status.have_value())
|
|
{
|
|
new(&this->_value) _value_type_(o._value); // NOLINT
|
|
this->_status = o._status;
|
|
return *this;
|
|
}
|
|
if(this->_status.have_error() && !o._status.have_value() && !o._status.have_error())
|
|
{
|
|
if(!trait::is_move_bitcopying<error_type>::value || this->_status.have_moved_from())
|
|
{
|
|
this->_error.~_error_type_(); // NOLINT
|
|
}
|
|
this->_status = o._status;
|
|
return *this;
|
|
}
|
|
if(!this->_status.have_value() && !this->_status.have_error() && o._status.have_error())
|
|
{
|
|
new(&this->_error) _error_type_(o._error); // NOLINT
|
|
this->_status = o._status;
|
|
return *this;
|
|
}
|
|
if(this->_status.have_value() && o._status.have_error())
|
|
{
|
|
if(!trait::is_move_bitcopying<value_type>::value || this->_status.have_moved_from())
|
|
{
|
|
this->_value.~_value_type_(); // NOLINT
|
|
}
|
|
new(&this->_error) _error_type_(o._error); // NOLINT
|
|
this->_status = o._status;
|
|
return *this;
|
|
}
|
|
if(this->_status.have_error() && o._status.have_value())
|
|
{
|
|
if(!trait::is_move_bitcopying<error_type>::value || this->_status.have_moved_from())
|
|
{
|
|
this->_error.~_error_type_(); // NOLINT
|
|
}
|
|
new(&this->_value) _value_type_(o._value); // NOLINT
|
|
this->_status = o._status;
|
|
return *this;
|
|
}
|
|
// Should never reach here
|
|
make_ub(this->_value);
|
|
}
|
|
};
|
|
#ifdef _MSC_VER
|
|
#pragma warning(pop)
|
|
#endif
|
|
// is_trivially_copyable is true even if type is not copyable, so handle that here
|
|
template <class T> struct is_storage_trivial
|
|
{
|
|
static constexpr bool value = std::is_void<T>::value || (std::is_trivially_copy_constructible<T>::value && std::is_trivially_copyable<T>::value);
|
|
};
|
|
// work around libstdc++ 7 bug
|
|
template <> struct is_storage_trivial<void>
|
|
{
|
|
static constexpr bool value = true;
|
|
};
|
|
template <> struct is_storage_trivial<const void>
|
|
{
|
|
static constexpr bool value = true;
|
|
};
|
|
template <class T, class E>
|
|
using value_storage_select_trivality =
|
|
std::conditional_t<is_storage_trivial<T>::value && is_storage_trivial<E>::value, value_storage_trivial<T, E>, value_storage_nontrivial<T, E>>;
|
|
template <class T, class E>
|
|
using value_storage_select_move_constructor =
|
|
std::conditional_t<std::is_move_constructible<devoid<T>>::value && std::is_move_constructible<devoid<E>>::value, value_storage_select_trivality<T, E>,
|
|
value_storage_delete_move_constructor<value_storage_select_trivality<T, E>>>;
|
|
template <class T, class E>
|
|
using value_storage_select_copy_constructor =
|
|
std::conditional_t<std::is_copy_constructible<devoid<T>>::value && std::is_copy_constructible<devoid<E>>::value, value_storage_select_move_constructor<T, E>,
|
|
value_storage_delete_copy_constructor<value_storage_select_move_constructor<T, E>>>;
|
|
template <class T, class E>
|
|
using value_storage_select_move_assignment =
|
|
std::conditional_t<std::is_trivially_move_assignable<devoid<T>>::value && std::is_trivially_move_assignable<devoid<E>>::value,
|
|
value_storage_select_copy_constructor<T, E>,
|
|
std::conditional_t<std::is_move_assignable<devoid<T>>::value && std::is_move_assignable<devoid<E>>::value,
|
|
value_storage_nontrivial_move_assignment<value_storage_select_copy_constructor<T, E>>,
|
|
value_storage_delete_copy_assignment<value_storage_select_copy_constructor<T, E>>>>;
|
|
template <class T, class E>
|
|
using value_storage_select_copy_assignment =
|
|
std::conditional_t<std::is_trivially_copy_assignable<devoid<T>>::value && std::is_trivially_copy_assignable<devoid<E>>::value,
|
|
value_storage_select_move_assignment<T, E>,
|
|
std::conditional_t<std::is_copy_assignable<devoid<T>>::value && std::is_copy_assignable<devoid<E>>::value,
|
|
value_storage_nontrivial_copy_assignment<value_storage_select_move_assignment<T, E>>,
|
|
value_storage_delete_copy_assignment<value_storage_select_move_assignment<T, E>>>>;
|
|
template <class T, class E> using value_storage_select_impl = value_storage_select_copy_assignment<T, E>;
|
|
#ifndef NDEBUG
|
|
// Check is trivial in all ways except default constructibility
|
|
// static_assert(std::is_trivial<value_storage_select_impl<int, long>>::value, "value_storage_select_impl<int, long> is not trivial!");
|
|
// static_assert(std::is_trivially_default_constructible<value_storage_select_impl<int, long>>::value, "value_storage_select_impl<int, long> is not trivially
|
|
// default constructible!");
|
|
static_assert(std::is_trivially_copyable<value_storage_select_impl<int, long>>::value, "value_storage_select_impl<int, long> is not trivially copyable!");
|
|
static_assert(std::is_trivially_assignable<value_storage_select_impl<int, long>, value_storage_select_impl<int, long>>::value,
|
|
"value_storage_select_impl<int, long> is not trivially assignable!");
|
|
static_assert(std::is_trivially_destructible<value_storage_select_impl<int, long>>::value,
|
|
"value_storage_select_impl<int, long> is not trivially destructible!");
|
|
static_assert(std::is_trivially_copy_constructible<value_storage_select_impl<int, long>>::value,
|
|
"value_storage_select_impl<int, long> is not trivially copy constructible!");
|
|
static_assert(std::is_trivially_move_constructible<value_storage_select_impl<int, long>>::value,
|
|
"value_storage_select_impl<int, long> is not trivially move constructible!");
|
|
static_assert(std::is_trivially_copy_assignable<value_storage_select_impl<int, long>>::value,
|
|
"value_storage_select_impl<int, long> is not trivially copy assignable!");
|
|
static_assert(std::is_trivially_move_assignable<value_storage_select_impl<int, long>>::value,
|
|
"value_storage_select_impl<int, long> is not trivially move assignable!");
|
|
// Also check is standard layout
|
|
static_assert(std::is_standard_layout<value_storage_select_impl<int, long>>::value, "value_storage_select_impl<int, long> is not a standard layout type!");
|
|
#endif
|
|
} // namespace detail
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace detail
|
|
{
|
|
template <class R, class EC, class NoValuePolicy> class basic_result_storage;
|
|
} // namespace detail
|
|
namespace hooks
|
|
{
|
|
template <class R, class S, class NoValuePolicy> constexpr inline uint16_t spare_storage(const detail::basic_result_storage<R, S, NoValuePolicy> *r) noexcept;
|
|
template <class R, class S, class NoValuePolicy>
|
|
constexpr inline void set_spare_storage(detail::basic_result_storage<R, S, NoValuePolicy> *r, uint16_t v) noexcept;
|
|
} // namespace hooks
|
|
namespace policy
|
|
{
|
|
struct base;
|
|
} // namespace policy
|
|
namespace detail
|
|
{
|
|
template <class R, class EC, class NoValuePolicy> //
|
|
class basic_result_storage
|
|
{
|
|
static_assert(trait::type_can_be_used_in_basic_result<R>, "The type R cannot be used in a basic_result");
|
|
static_assert(trait::type_can_be_used_in_basic_result<EC>, "The type S cannot be used in a basic_result");
|
|
friend struct policy::base;
|
|
template <class T, class U, class V> //
|
|
friend class basic_result_storage;
|
|
template <class T, class U, class V> friend class basic_result_final;
|
|
template <class T, class U, class V>
|
|
friend constexpr inline uint16_t hooks::spare_storage(const detail::basic_result_storage<T, U, V> *r) noexcept; // NOLINT
|
|
template <class T, class U, class V>
|
|
friend constexpr inline void hooks::set_spare_storage(detail::basic_result_storage<T, U, V> *r, uint16_t v) noexcept; // NOLINT
|
|
struct disable_in_place_value_type
|
|
{
|
|
};
|
|
struct disable_in_place_error_type
|
|
{
|
|
};
|
|
protected:
|
|
using _value_type = std::conditional_t<std::is_same<R, EC>::value, disable_in_place_value_type, R>;
|
|
using _error_type = std::conditional_t<std::is_same<R, EC>::value, disable_in_place_error_type, EC>;
|
|
using _state_type = value_storage_select_impl<_value_type, _error_type>;
|
|
_state_type _state;
|
|
public:
|
|
// Used by iostream support to access state
|
|
_state_type &_iostreams_state() { return _state; }
|
|
const _state_type &_iostreams_state() const { return _state; }
|
|
protected:
|
|
basic_result_storage() = default;
|
|
basic_result_storage(const basic_result_storage &) = default; // NOLINT
|
|
basic_result_storage(basic_result_storage &&) = default; // NOLINT
|
|
basic_result_storage &operator=(const basic_result_storage &) = default; // NOLINT
|
|
basic_result_storage &operator=(basic_result_storage &&) = default; // NOLINT
|
|
~basic_result_storage() = default;
|
|
template <class... Args>
|
|
constexpr explicit basic_result_storage(in_place_type_t<_value_type> _,
|
|
Args &&... args) noexcept(detail::is_nothrow_constructible<_value_type, Args...>)
|
|
: _state{_, static_cast<Args &&>(args)...}
|
|
{
|
|
}
|
|
template <class U, class... Args>
|
|
constexpr basic_result_storage(in_place_type_t<_value_type> _, std::initializer_list<U> il,
|
|
Args &&... args) noexcept(detail::is_nothrow_constructible<_value_type, std::initializer_list<U>, Args...>)
|
|
: _state{_, il, static_cast<Args &&>(args)...}
|
|
{
|
|
}
|
|
template <class... Args>
|
|
constexpr explicit basic_result_storage(in_place_type_t<_error_type> _,
|
|
Args &&... args) noexcept(detail::is_nothrow_constructible<_error_type, Args...>)
|
|
: _state{_, static_cast<Args &&>(args)...}
|
|
{
|
|
}
|
|
template <class U, class... Args>
|
|
constexpr basic_result_storage(in_place_type_t<_error_type> _, std::initializer_list<U> il,
|
|
Args &&... args) noexcept(detail::is_nothrow_constructible<_error_type, std::initializer_list<U>, Args...>)
|
|
: _state{_, il, static_cast<Args &&>(args)...}
|
|
{
|
|
}
|
|
struct compatible_conversion_tag
|
|
{
|
|
};
|
|
template <class T, class U, class V>
|
|
constexpr basic_result_storage(compatible_conversion_tag /*unused*/, const basic_result_storage<T, U, V> &o) noexcept(
|
|
detail::is_nothrow_constructible<_value_type, T> &&detail::is_nothrow_constructible<_error_type, U>)
|
|
: _state(o._state)
|
|
{
|
|
}
|
|
template <class T, class U, class V>
|
|
constexpr basic_result_storage(compatible_conversion_tag /*unused*/, basic_result_storage<T, U, V> &&o) noexcept(
|
|
detail::is_nothrow_constructible<_value_type, T> &&detail::is_nothrow_constructible<_error_type, U>)
|
|
: _state(static_cast<decltype(o._state) &&>(o._state))
|
|
{
|
|
}
|
|
struct make_error_code_compatible_conversion_tag
|
|
{
|
|
};
|
|
template <class T, class U, class V>
|
|
constexpr basic_result_storage(make_error_code_compatible_conversion_tag /*unused*/, const basic_result_storage<T, U, V> &o) noexcept(
|
|
detail::is_nothrow_constructible<_value_type, T> &&noexcept(make_error_code(std::declval<U>())))
|
|
: _state(o._state._status.have_value() ? _state_type(in_place_type<_value_type>, o._state._value) :
|
|
_state_type(in_place_type<_error_type>, make_error_code(o._state._error)))
|
|
{
|
|
}
|
|
template <class T, class U, class V>
|
|
constexpr basic_result_storage(make_error_code_compatible_conversion_tag /*unused*/, basic_result_storage<T, U, V> &&o) noexcept(
|
|
detail::is_nothrow_constructible<_value_type, T> &&noexcept(make_error_code(std::declval<U>())))
|
|
: _state(o._state._status.have_value() ? _state_type(in_place_type<_value_type>, static_cast<T &&>(o._state._value)) :
|
|
_state_type(in_place_type<_error_type>, make_error_code(static_cast<U &&>(o._state._error))))
|
|
{
|
|
}
|
|
struct make_exception_ptr_compatible_conversion_tag
|
|
{
|
|
};
|
|
template <class T, class U, class V>
|
|
constexpr basic_result_storage(make_exception_ptr_compatible_conversion_tag /*unused*/, const basic_result_storage<T, U, V> &o) noexcept(
|
|
detail::is_nothrow_constructible<_value_type, T> &&noexcept(make_exception_ptr(std::declval<U>())))
|
|
: _state(o._state._status.have_value() ? _state_type(in_place_type<_value_type>, o._state._value) :
|
|
_state_type(in_place_type<_error_type>, make_exception_ptr(o._state._error)))
|
|
{
|
|
}
|
|
template <class T, class U, class V>
|
|
constexpr basic_result_storage(make_exception_ptr_compatible_conversion_tag /*unused*/, basic_result_storage<T, U, V> &&o) noexcept(
|
|
detail::is_nothrow_constructible<_value_type, T> &&noexcept(make_exception_ptr(std::declval<U>())))
|
|
: _state(o._state._status.have_value() ? _state_type(in_place_type<_value_type>, static_cast<T &&>(o._state._value)) :
|
|
_state_type(in_place_type<_error_type>, make_exception_ptr(static_cast<U &&>(o._state._error))))
|
|
{
|
|
}
|
|
};
|
|
} // namespace detail
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace concepts
|
|
{
|
|
#if defined(__cpp_concepts)
|
|
#if (defined(_MSC_VER) || defined(__clang__) || (defined(__GNUC__) && __cpp_concepts >= 201707) || OUTCOME_FORCE_STD_CXX_CONCEPTS) && !OUTCOME_FORCE_LEGACY_GCC_CXX_CONCEPTS
|
|
#define OUTCOME_GCC6_CONCEPT_BOOL
|
|
#else
|
|
#define OUTCOME_GCC6_CONCEPT_BOOL bool
|
|
#endif
|
|
namespace detail
|
|
{
|
|
template <class T, class U> concept OUTCOME_GCC6_CONCEPT_BOOL SameHelper = std::is_same<T, U>::value;
|
|
template <class T, class U> concept OUTCOME_GCC6_CONCEPT_BOOL same_as = detail::SameHelper<T, U> &&detail::SameHelper<U, T>;
|
|
template <class T, class U> concept OUTCOME_GCC6_CONCEPT_BOOL convertible = std::is_convertible<T, U>::value;
|
|
template <class T, class U> concept OUTCOME_GCC6_CONCEPT_BOOL base_of = std::is_base_of<T, U>::value;
|
|
} // namespace detail
|
|
/* The `value_or_none` concept.
|
|
\requires That `U::value_type` exists and that `std::declval<U>().has_value()` returns a `bool` and `std::declval<U>().value()` exists.
|
|
*/
|
|
template <class U> concept OUTCOME_GCC6_CONCEPT_BOOL value_or_none = requires(U a)
|
|
{
|
|
{
|
|
a.has_value()
|
|
}
|
|
->detail::same_as<bool>;
|
|
{a.value()};
|
|
};
|
|
/* The `value_or_error` concept.
|
|
\requires That `U::value_type` and `U::error_type` exist;
|
|
that `std::declval<U>().has_value()` returns a `bool`, `std::declval<U>().value()` and `std::declval<U>().error()` exists.
|
|
*/
|
|
template <class U> concept OUTCOME_GCC6_CONCEPT_BOOL value_or_error = requires(U a)
|
|
{
|
|
{
|
|
a.has_value()
|
|
}
|
|
->detail::same_as<bool>;
|
|
{a.value()};
|
|
{a.error()};
|
|
};
|
|
#else
|
|
namespace detail
|
|
{
|
|
struct no_match
|
|
{
|
|
};
|
|
inline no_match match_value_or_none(...);
|
|
inline no_match match_value_or_error(...);
|
|
OUTCOME_TEMPLATE(class U)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<U>().has_value()), OUTCOME_TEXPR(std::declval<U>().value()))
|
|
inline U match_value_or_none(U &&);
|
|
OUTCOME_TEMPLATE(class U)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<U>().has_value()), OUTCOME_TEXPR(std::declval<U>().value()), OUTCOME_TEXPR(std::declval<U>().error()))
|
|
inline U match_value_or_error(U &&);
|
|
template <class U>
|
|
static constexpr bool value_or_none =
|
|
!std::is_same<no_match, decltype(match_value_or_none(std::declval<OUTCOME_V2_NAMESPACE::detail::devoid<U>>()))>::value;
|
|
template <class U>
|
|
static constexpr bool value_or_error =
|
|
!std::is_same<no_match, decltype(match_value_or_error(std::declval<OUTCOME_V2_NAMESPACE::detail::devoid<U>>()))>::value;
|
|
} // namespace detail
|
|
/* The `value_or_none` concept.
|
|
\requires That `U::value_type` exists and that `std::declval<U>().has_value()` returns a `bool` and `std::declval<U>().value()` exists.
|
|
*/
|
|
template <class U> static constexpr bool value_or_none = detail::value_or_none<U>;
|
|
/* The `value_or_error` concept.
|
|
\requires That `U::value_type` and `U::error_type` exist;
|
|
that `std::declval<U>().has_value()` returns a `bool`, `std::declval<U>().value()` and `std::declval<U>().error()` exists.
|
|
*/
|
|
template <class U> static constexpr bool value_or_error = detail::value_or_error<U>;
|
|
#endif
|
|
} // namespace concepts
|
|
namespace convert
|
|
{
|
|
#if OUTCOME_ENABLE_LEGACY_SUPPORT_FOR < 220
|
|
#if defined(__cpp_concepts)
|
|
template <class U> concept OUTCOME_GCC6_CONCEPT_BOOL ValueOrNone = concepts::value_or_none<U>;
|
|
template <class U> concept OUTCOME_GCC6_CONCEPT_BOOL ValueOrError = concepts::value_or_error<U>;
|
|
#else
|
|
template <class U> static constexpr bool ValueOrNone = concepts::value_or_none<U>;
|
|
template <class U> static constexpr bool ValueOrError = concepts::value_or_error<U>;
|
|
#endif
|
|
#endif
|
|
namespace detail
|
|
{
|
|
template <class T, class X> struct make_type
|
|
{
|
|
template <class U> static constexpr T value(U &&v) { return T{in_place_type<typename T::value_type>, static_cast<U &&>(v).value()}; }
|
|
template <class U> static constexpr T error(U &&v) { return T{in_place_type<typename T::error_type>, static_cast<U &&>(v).error()}; }
|
|
static constexpr T error() { return T{in_place_type<typename T::error_type>}; }
|
|
};
|
|
template <class T> struct make_type<T, void>
|
|
{
|
|
template <class U> static constexpr T value(U && /*unused*/) { return T{in_place_type<typename T::value_type>}; }
|
|
template <class U> static constexpr T error(U && /*unused*/) { return T{in_place_type<typename T::error_type>}; }
|
|
static constexpr T error() { return T{in_place_type<typename T::error_type>}; }
|
|
};
|
|
} // namespace detail
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition value_or_error. Potential doc page: NOT FOUND
|
|
*/
|
|
template <class T, class U> struct value_or_error
|
|
{
|
|
static constexpr bool enable_result_inputs = false;
|
|
static constexpr bool enable_outcome_inputs = false;
|
|
OUTCOME_TEMPLATE(class X)
|
|
OUTCOME_TREQUIRES(
|
|
OUTCOME_TPRED(std::is_same<U, std::decay_t<X>>::value //
|
|
&&concepts::value_or_error<U> //
|
|
&& (std::is_void<typename std::decay_t<X>::value_type>::value ||
|
|
OUTCOME_V2_NAMESPACE::detail::is_explicitly_constructible<typename T::value_type, typename std::decay_t<X>::value_type>) //
|
|
&&(std::is_void<typename std::decay_t<X>::error_type>::value ||
|
|
OUTCOME_V2_NAMESPACE::detail::is_explicitly_constructible<typename T::error_type, typename std::decay_t<X>::error_type>) ))
|
|
constexpr T operator()(X &&v)
|
|
{
|
|
return v.has_value() ? detail::make_type<T, typename T::value_type>::value(static_cast<X &&>(v)) :
|
|
detail::make_type<T, typename U::error_type>::error(static_cast<X &&>(v));
|
|
}
|
|
};
|
|
} // namespace convert
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* Finaliser for a very simple result type
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_BASIC_RESULT_FINAL_HPP
|
|
#define OUTCOME_BASIC_RESULT_FINAL_HPP
|
|
/* Error observers for a very simple basic_result type
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (2 commits)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_BASIC_RESULT_ERROR_OBSERVERS_HPP
|
|
#define OUTCOME_BASIC_RESULT_ERROR_OBSERVERS_HPP
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace detail
|
|
{
|
|
template <class Base, class EC, class NoValuePolicy> class basic_result_error_observers : public Base
|
|
{
|
|
public:
|
|
using error_type = EC;
|
|
using Base::Base;
|
|
constexpr error_type &assume_error() & noexcept
|
|
{
|
|
NoValuePolicy::narrow_error_check(static_cast<basic_result_error_observers &>(*this));
|
|
return this->_state._error;
|
|
}
|
|
constexpr const error_type &assume_error() const &noexcept
|
|
{
|
|
NoValuePolicy::narrow_error_check(static_cast<const basic_result_error_observers &>(*this));
|
|
return this->_state._error;
|
|
}
|
|
constexpr error_type &&assume_error() && noexcept
|
|
{
|
|
NoValuePolicy::narrow_error_check(static_cast<basic_result_error_observers &&>(*this));
|
|
return static_cast<error_type &&>(this->_state._error);
|
|
}
|
|
constexpr const error_type &&assume_error() const &&noexcept
|
|
{
|
|
NoValuePolicy::narrow_error_check(static_cast<const basic_result_error_observers &&>(*this));
|
|
return static_cast<const error_type &&>(this->_state._error);
|
|
}
|
|
constexpr error_type &error() &
|
|
{
|
|
NoValuePolicy::wide_error_check(static_cast<basic_result_error_observers &>(*this));
|
|
return this->_state._error;
|
|
}
|
|
constexpr const error_type &error() const &
|
|
{
|
|
NoValuePolicy::wide_error_check(static_cast<const basic_result_error_observers &>(*this));
|
|
return this->_state._error;
|
|
}
|
|
constexpr error_type &&error() &&
|
|
{
|
|
NoValuePolicy::wide_error_check(static_cast<basic_result_error_observers &&>(*this));
|
|
return static_cast<error_type &&>(this->_state._error);
|
|
}
|
|
constexpr const error_type &&error() const &&
|
|
{
|
|
NoValuePolicy::wide_error_check(static_cast<const basic_result_error_observers &&>(*this));
|
|
return static_cast<const error_type &&>(this->_state._error);
|
|
}
|
|
};
|
|
template <class Base, class NoValuePolicy> class basic_result_error_observers<Base, void, NoValuePolicy> : public Base
|
|
{
|
|
public:
|
|
using Base::Base;
|
|
constexpr void assume_error() const noexcept { NoValuePolicy::narrow_error_check(*this); }
|
|
constexpr void error() const { NoValuePolicy::wide_error_check(*this); }
|
|
};
|
|
} // namespace detail
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* Value observers for a very simple basic_result type
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (2 commits)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_RESULT_VALUE_OBSERVERS_HPP
|
|
#define OUTCOME_RESULT_VALUE_OBSERVERS_HPP
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace detail
|
|
{
|
|
template <class Base, class R, class NoValuePolicy> class basic_result_value_observers : public Base
|
|
{
|
|
public:
|
|
using value_type = R;
|
|
using Base::Base;
|
|
constexpr value_type &assume_value() & noexcept
|
|
{
|
|
NoValuePolicy::narrow_value_check(static_cast<basic_result_value_observers &>(*this));
|
|
return this->_state._value; // NOLINT
|
|
}
|
|
constexpr const value_type &assume_value() const &noexcept
|
|
{
|
|
NoValuePolicy::narrow_value_check(static_cast<const basic_result_value_observers &>(*this));
|
|
return this->_state._value; // NOLINT
|
|
}
|
|
constexpr value_type &&assume_value() && noexcept
|
|
{
|
|
NoValuePolicy::narrow_value_check(static_cast<basic_result_value_observers &&>(*this));
|
|
return static_cast<value_type &&>(this->_state._value); // NOLINT
|
|
}
|
|
constexpr const value_type &&assume_value() const &&noexcept
|
|
{
|
|
NoValuePolicy::narrow_value_check(static_cast<const basic_result_value_observers &&>(*this));
|
|
return static_cast<const value_type &&>(this->_state._value); // NOLINT
|
|
}
|
|
constexpr value_type &value() &
|
|
{
|
|
NoValuePolicy::wide_value_check(static_cast<basic_result_value_observers &>(*this));
|
|
return this->_state._value; // NOLINT
|
|
}
|
|
constexpr const value_type &value() const &
|
|
{
|
|
NoValuePolicy::wide_value_check(static_cast<const basic_result_value_observers &>(*this));
|
|
return this->_state._value; // NOLINT
|
|
}
|
|
constexpr value_type &&value() &&
|
|
{
|
|
NoValuePolicy::wide_value_check(static_cast<basic_result_value_observers &&>(*this));
|
|
return static_cast<value_type &&>(this->_state._value); // NOLINT
|
|
}
|
|
constexpr const value_type &&value() const &&
|
|
{
|
|
NoValuePolicy::wide_value_check(static_cast<const basic_result_value_observers &&>(*this));
|
|
return static_cast<const value_type &&>(this->_state._value); // NOLINT
|
|
}
|
|
};
|
|
template <class Base, class NoValuePolicy> class basic_result_value_observers<Base, void, NoValuePolicy> : public Base
|
|
{
|
|
public:
|
|
using Base::Base;
|
|
constexpr void assume_value() const noexcept { NoValuePolicy::narrow_value_check(*this); }
|
|
constexpr void value() const { NoValuePolicy::wide_value_check(*this); }
|
|
};
|
|
} // namespace detail
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace detail
|
|
{
|
|
template <class R, class EC, class NoValuePolicy> using select_basic_result_impl = basic_result_error_observers<basic_result_value_observers<basic_result_storage<R, EC, NoValuePolicy>, R, NoValuePolicy>, EC, NoValuePolicy>;
|
|
template <class R, class S, class NoValuePolicy>
|
|
class basic_result_final
|
|
: public select_basic_result_impl<R, S, NoValuePolicy>
|
|
{
|
|
using base = select_basic_result_impl<R, S, NoValuePolicy>;
|
|
public:
|
|
using base::base;
|
|
constexpr explicit operator bool() const noexcept { return this->_state._status.have_value(); }
|
|
constexpr bool has_value() const noexcept { return this->_state._status.have_value(); }
|
|
constexpr bool has_error() const noexcept { return this->_state._status.have_error(); }
|
|
constexpr bool has_exception() const noexcept { return this->_state._status.have_exception(); }
|
|
constexpr bool has_lost_consistency() const noexcept { return this->_state._status.have_lost_consistency(); }
|
|
constexpr bool has_failure() const noexcept { return this->_state._status.have_error() || this->_state._status.have_exception(); }
|
|
OUTCOME_TEMPLATE(class T, class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<detail::devoid<R>>() == std::declval<detail::devoid<T>>()), //
|
|
OUTCOME_TEXPR(std::declval<detail::devoid<S>>() == std::declval<detail::devoid<U>>()))
|
|
constexpr bool operator==(const basic_result_final<T, U, V> &o) const noexcept( //
|
|
noexcept(std::declval<detail::devoid<R>>() == std::declval<detail::devoid<T>>()) && noexcept(std::declval<detail::devoid<S>>() == std::declval<detail::devoid<U>>()))
|
|
{
|
|
if(this->_state._status.have_value() && o._state._status.have_value())
|
|
{
|
|
return this->_state._value == o._state._value; // NOLINT
|
|
}
|
|
if(this->_state._status.have_error() && o._state._status.have_error())
|
|
{
|
|
return this->_state._error == o._state._error;
|
|
}
|
|
return false;
|
|
}
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<R>() == std::declval<T>()))
|
|
constexpr bool operator==(const success_type<T> &o) const noexcept( //
|
|
noexcept(std::declval<R>() == std::declval<T>()))
|
|
{
|
|
if(this->_state._status.have_value())
|
|
{
|
|
return this->_state._value == o.value();
|
|
}
|
|
return false;
|
|
}
|
|
constexpr bool operator==(const success_type<void> &o) const noexcept
|
|
{
|
|
(void) o;
|
|
return this->_state._status.have_value();
|
|
}
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<S>() == std::declval<T>()))
|
|
constexpr bool operator==(const failure_type<T, void> &o) const noexcept( //
|
|
noexcept(std::declval<S>() == std::declval<T>()))
|
|
{
|
|
if(this->_state._status.have_error())
|
|
{
|
|
return this->_state._error == o.error();
|
|
}
|
|
return false;
|
|
}
|
|
OUTCOME_TEMPLATE(class T, class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<detail::devoid<R>>() != std::declval<detail::devoid<T>>()), //
|
|
OUTCOME_TEXPR(std::declval<detail::devoid<S>>() != std::declval<detail::devoid<U>>()))
|
|
constexpr bool operator!=(const basic_result_final<T, U, V> &o) const noexcept( //
|
|
noexcept(std::declval<detail::devoid<R>>() != std::declval<detail::devoid<T>>()) && noexcept(std::declval<detail::devoid<S>>() != std::declval<detail::devoid<U>>()))
|
|
{
|
|
if(this->_state._status.have_value() && o._state._status.have_value())
|
|
{
|
|
return this->_state._value != o._state._value;
|
|
}
|
|
if(this->_state._status.have_error() && o._state._status.have_error())
|
|
{
|
|
return this->_state._error != o._state._error;
|
|
}
|
|
return true;
|
|
}
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<R>() != std::declval<T>()))
|
|
constexpr bool operator!=(const success_type<T> &o) const noexcept( //
|
|
noexcept(std::declval<R>() != std::declval<T>()))
|
|
{
|
|
if(this->_state._status.have_value())
|
|
{
|
|
return this->_state._value != o.value();
|
|
}
|
|
return false;
|
|
}
|
|
constexpr bool operator!=(const success_type<void> &o) const noexcept
|
|
{
|
|
(void) o;
|
|
return !this->_state._status.have_value();
|
|
}
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<S>() != std::declval<T>()))
|
|
constexpr bool operator!=(const failure_type<T, void> &o) const noexcept( //
|
|
noexcept(std::declval<S>() != std::declval<T>()))
|
|
{
|
|
if(this->_state._status.have_error())
|
|
{
|
|
return this->_state._error != o.error();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
template <class T, class U, class V, class W> constexpr inline bool operator==(const success_type<W> &a, const basic_result_final<T, U, V> &b) noexcept(noexcept(b == a)) { return b == a; }
|
|
template <class T, class U, class V, class W> constexpr inline bool operator==(const failure_type<W, void> &a, const basic_result_final<T, U, V> &b) noexcept(noexcept(b == a)) { return b == a; }
|
|
template <class T, class U, class V, class W> constexpr inline bool operator!=(const success_type<W> &a, const basic_result_final<T, U, V> &b) noexcept(noexcept(b == a)) { return b != a; }
|
|
template <class T, class U, class V, class W> constexpr inline bool operator!=(const failure_type<W, void> &a, const basic_result_final<T, U, V> &b) noexcept(noexcept(b == a)) { return b != a; }
|
|
} // namespace detail
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* Policies for result and outcome
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (13 commits)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_POLICY_ALL_NARROW_HPP
|
|
#define OUTCOME_POLICY_ALL_NARROW_HPP
|
|
/* Policies for result and outcome
|
|
(C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (6 commits) and Andrzej Krzemieński <akrzemi1@gmail.com> (1 commit)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_POLICY_BASE_HPP
|
|
#define OUTCOME_POLICY_BASE_HPP
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
#if OUTCOME_ENABLE_LEGACY_SUPPORT_FOR < 220
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
namespace hooks
|
|
{
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T, class U> constexpr inline void hook_result_construction(T * /*unused*/, U && /*unused*/) noexcept {}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T, class U> constexpr inline void hook_result_copy_construction(T * /*unused*/, U && /*unused*/) noexcept {}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T, class U> constexpr inline void hook_result_move_construction(T * /*unused*/, U && /*unused*/) noexcept {}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T, class U, class... Args>
|
|
constexpr inline void hook_result_in_place_construction(T * /*unused*/, in_place_type_t<U> /*unused*/, Args &&... /*unused*/) noexcept
|
|
{
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T, class... U> constexpr inline void hook_outcome_construction(T * /*unused*/, U &&... /*unused*/) noexcept {}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T, class U> constexpr inline void hook_outcome_copy_construction(T * /*unused*/, U && /*unused*/) noexcept {}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T, class U> constexpr inline void hook_outcome_move_construction(T * /*unused*/, U && /*unused*/) noexcept {}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T, class U, class... Args>
|
|
constexpr inline void hook_outcome_in_place_construction(T * /*unused*/, in_place_type_t<U> /*unused*/, Args &&... /*unused*/) noexcept
|
|
{
|
|
}
|
|
} // namespace hooks
|
|
#endif
|
|
namespace policy
|
|
{
|
|
namespace detail
|
|
{
|
|
using OUTCOME_V2_NAMESPACE::detail::make_ub;
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
struct base
|
|
{
|
|
template <class... Args> static constexpr void _silence_unused(Args &&... /*unused*/) noexcept {}
|
|
protected:
|
|
template <class Impl> static constexpr void _make_ub(Impl &&self) noexcept { return detail::make_ub(static_cast<Impl &&>(self)); }
|
|
template <class Impl> static constexpr bool _has_value(Impl &&self) noexcept { return self._state._status.have_value(); }
|
|
template <class Impl> static constexpr bool _has_error(Impl &&self) noexcept { return self._state._status.have_error(); }
|
|
template <class Impl> static constexpr bool _has_exception(Impl &&self) noexcept { return self._state._status.have_exception(); }
|
|
template <class Impl> static constexpr bool _has_error_is_errno(Impl &&self) noexcept { return self._state._status.have_error_is_errno(); }
|
|
template <class Impl> static constexpr void _set_has_value(Impl &&self, bool v) noexcept { self._state._status.set_have_value(v); }
|
|
template <class Impl> static constexpr void _set_has_error(Impl &&self, bool v) noexcept { self._state._status.set_have_error(v); }
|
|
template <class Impl> static constexpr void _set_has_exception(Impl &&self, bool v) noexcept { self._state._status.set_have_exception(v); }
|
|
template <class Impl> static constexpr void _set_has_error_is_errno(Impl &&self, bool v) noexcept { self._state._status.set_have_error_is_errno(v); }
|
|
template <class Impl> static constexpr auto &&_value(Impl &&self) noexcept { return static_cast<Impl &&>(self)._state._value; }
|
|
template <class Impl> static constexpr auto &&_error(Impl &&self) noexcept { return static_cast<Impl &&>(self)._state._error; }
|
|
public:
|
|
template <class R, class S, class P, class NoValuePolicy, class Impl> static inline constexpr auto &&_exception(Impl &&self) noexcept;
|
|
template <class T, class U> static constexpr inline void on_result_construction(T *inst, U &&v) noexcept
|
|
{
|
|
#if OUTCOME_ENABLE_LEGACY_SUPPORT_FOR < 220
|
|
using namespace hooks;
|
|
hook_result_construction(inst, static_cast<U &&>(v));
|
|
#else
|
|
(void) inst;
|
|
(void) v;
|
|
#endif
|
|
}
|
|
template <class T, class U> static constexpr inline void on_result_copy_construction(T *inst, U &&v) noexcept
|
|
{
|
|
#if OUTCOME_ENABLE_LEGACY_SUPPORT_FOR < 220
|
|
using namespace hooks;
|
|
hook_result_copy_construction(inst, static_cast<U &&>(v));
|
|
#else
|
|
(void) inst;
|
|
(void) v;
|
|
#endif
|
|
}
|
|
template <class T, class U> static constexpr inline void on_result_move_construction(T *inst, U &&v) noexcept
|
|
{
|
|
#if OUTCOME_ENABLE_LEGACY_SUPPORT_FOR < 220
|
|
using namespace hooks;
|
|
hook_result_move_construction(inst, static_cast<U &&>(v));
|
|
#else
|
|
(void) inst;
|
|
(void) v;
|
|
#endif
|
|
}
|
|
template <class T, class U, class... Args>
|
|
static constexpr inline void on_result_in_place_construction(T *inst, in_place_type_t<U> _, Args &&... args) noexcept
|
|
{
|
|
#if OUTCOME_ENABLE_LEGACY_SUPPORT_FOR < 220
|
|
using namespace hooks;
|
|
hook_result_in_place_construction(inst, _, static_cast<Args &&>(args)...);
|
|
#else
|
|
(void) inst;
|
|
(void) _;
|
|
_silence_unused(static_cast<Args &&>(args)...);
|
|
#endif
|
|
}
|
|
template <class T, class... U> static constexpr inline void on_outcome_construction(T *inst, U &&... args) noexcept
|
|
{
|
|
#if OUTCOME_ENABLE_LEGACY_SUPPORT_FOR < 220
|
|
using namespace hooks;
|
|
hook_outcome_construction(inst, static_cast<U &&>(args)...);
|
|
#else
|
|
(void) inst;
|
|
_silence_unused(static_cast<U &&>(args)...);
|
|
#endif
|
|
}
|
|
template <class T, class U> static constexpr inline void on_outcome_copy_construction(T *inst, U &&v) noexcept
|
|
{
|
|
#if OUTCOME_ENABLE_LEGACY_SUPPORT_FOR < 220
|
|
using namespace hooks;
|
|
hook_outcome_copy_construction(inst, static_cast<U &&>(v));
|
|
#else
|
|
(void) inst;
|
|
(void) v;
|
|
#endif
|
|
}
|
|
template <class T, class U> static constexpr inline void on_outcome_move_construction(T *inst, U &&v) noexcept
|
|
{
|
|
#if OUTCOME_ENABLE_LEGACY_SUPPORT_FOR < 220
|
|
using namespace hooks;
|
|
hook_outcome_move_construction(inst, static_cast<U &&>(v));
|
|
#else
|
|
(void) inst;
|
|
(void) v;
|
|
#endif
|
|
}
|
|
template <class T, class U, class... Args>
|
|
static constexpr inline void on_outcome_in_place_construction(T *inst, in_place_type_t<U> _, Args &&... args) noexcept
|
|
{
|
|
#if OUTCOME_ENABLE_LEGACY_SUPPORT_FOR < 220
|
|
using namespace hooks;
|
|
hook_outcome_in_place_construction(inst, _, static_cast<Args &&>(args)...);
|
|
#else
|
|
(void) inst;
|
|
(void) _;
|
|
_silence_unused(static_cast<Args &&>(args)...);
|
|
#endif
|
|
}
|
|
template <class Impl> static constexpr void narrow_value_check(Impl &&self) noexcept
|
|
{
|
|
if(!_has_value(self))
|
|
{
|
|
_make_ub(self);
|
|
}
|
|
}
|
|
template <class Impl> static constexpr void narrow_error_check(Impl &&self) noexcept
|
|
{
|
|
if(!_has_error(self))
|
|
{
|
|
_make_ub(self);
|
|
}
|
|
}
|
|
template <class Impl> static constexpr void narrow_exception_check(Impl &&self) noexcept
|
|
{
|
|
if(!_has_exception(self))
|
|
{
|
|
_make_ub(self);
|
|
}
|
|
}
|
|
};
|
|
} // namespace policy
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace policy
|
|
{
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition all_narrow. Potential doc page: `all_narrow`
|
|
*/
|
|
struct all_narrow : base
|
|
{
|
|
template <class Impl> static constexpr void wide_value_check(Impl &&self) { base::narrow_value_check(static_cast<Impl &&>(self)); }
|
|
template <class Impl> static constexpr void wide_error_check(Impl &&self) { base::narrow_error_check(static_cast<Impl &&>(self)); }
|
|
template <class Impl> static constexpr void wide_exception_check(Impl &&self) { base::narrow_exception_check(static_cast<Impl &&>(self)); }
|
|
};
|
|
} // namespace policy
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* Policies for result and outcome
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (12 commits)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_POLICY_TERMINATE_HPP
|
|
#define OUTCOME_POLICY_TERMINATE_HPP
|
|
#include <cstdlib>
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace policy
|
|
{
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition terminate. Potential doc page: `terminate`
|
|
*/
|
|
struct terminate : base
|
|
{
|
|
template <class Impl> static constexpr void wide_value_check(Impl &&self)
|
|
{
|
|
if(!base::_has_value(static_cast<Impl &&>(self)))
|
|
{
|
|
std::abort();
|
|
}
|
|
}
|
|
template <class Impl> static constexpr void wide_error_check(Impl &&self) noexcept
|
|
{
|
|
if(!base::_has_error(static_cast<Impl &&>(self)))
|
|
{
|
|
std::abort();
|
|
}
|
|
}
|
|
template <class Impl> static constexpr void wide_exception_check(Impl &&self)
|
|
{
|
|
if(!base::_has_exception(static_cast<Impl &&>(self)))
|
|
{
|
|
std::abort();
|
|
}
|
|
}
|
|
};
|
|
} // namespace policy
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
#ifdef __clang__
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wdocumentation" // Standardese markup confuses clang
|
|
#endif
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
template <class R, class S, class NoValuePolicy> //
|
|
class basic_result;
|
|
namespace detail
|
|
{
|
|
// These are reused by basic_outcome to save load on the compiler
|
|
template <class value_type, class error_type> struct result_predicates
|
|
{
|
|
// Predicate for the implicit constructors to be available. Weakened to allow result<int, C enum>.
|
|
static constexpr bool implicit_constructors_enabled = //
|
|
!(trait::is_error_type<std::decay_t<value_type>>::value &&
|
|
trait::is_error_type<std::decay_t<error_type>>::value) // both value and error types are not whitelisted error types
|
|
&& ((!detail::is_implicitly_constructible<value_type, error_type> &&
|
|
!detail::is_implicitly_constructible<error_type, value_type>) // if value and error types cannot be constructed into one another
|
|
|| (trait::is_error_type<std::decay_t<error_type>>::value // if error type is a whitelisted error type
|
|
&& !detail::is_implicitly_constructible<error_type, value_type> // AND which cannot be constructed from the value type
|
|
&& std::is_integral<value_type>::value)); // AND the value type is some integral type
|
|
// Predicate for the value converting constructor to be available. Weakened to allow result<int, C enum>.
|
|
template <class T>
|
|
static constexpr bool enable_value_converting_constructor = //
|
|
implicit_constructors_enabled //
|
|
&& !is_in_place_type_t<std::decay_t<T>>::value // not in place construction
|
|
&& !trait::is_error_type_enum<error_type, std::decay_t<T>>::value // not an enum valid for my error type
|
|
&& ((detail::is_implicitly_constructible<value_type, T> && !detail::is_implicitly_constructible<error_type, T>) // is unambiguously for value type
|
|
|| (std::is_same<value_type, std::decay_t<T>>::value // OR is my value type exactly
|
|
&& detail::is_implicitly_constructible<value_type, T>) ); // and my value type is constructible from this ref form of T
|
|
// Predicate for the error converting constructor to be available. Weakened to allow result<int, C enum>.
|
|
template <class T>
|
|
static constexpr bool enable_error_converting_constructor = //
|
|
implicit_constructors_enabled //
|
|
&& !is_in_place_type_t<std::decay_t<T>>::value // not in place construction
|
|
&& !trait::is_error_type_enum<error_type, std::decay_t<T>>::value // not an enum valid for my error type
|
|
&& ((!detail::is_implicitly_constructible<value_type, T> && detail::is_implicitly_constructible<error_type, T>) // is unambiguously for error type
|
|
|| (std::is_same<error_type, std::decay_t<T>>::value // OR is my error type exactly
|
|
&& detail::is_implicitly_constructible<error_type, T>) ); // and my error type is constructible from this ref form of T
|
|
// Predicate for the error condition converting constructor to be available.
|
|
template <class ErrorCondEnum>
|
|
static constexpr bool enable_error_condition_converting_constructor = //
|
|
!is_in_place_type_t<std::decay_t<ErrorCondEnum>>::value // not in place construction
|
|
&& trait::is_error_type_enum<error_type, std::decay_t<ErrorCondEnum>>::value // is an error condition enum
|
|
/*&& !detail::is_implicitly_constructible<value_type, ErrorCondEnum> && !detail::is_implicitly_constructible<error_type, ErrorCondEnum>*/; // not
|
|
// constructible
|
|
// via any other
|
|
// means
|
|
// Predicate for the converting constructor from a compatible input to be available.
|
|
template <class T, class U, class V>
|
|
static constexpr bool enable_compatible_conversion = //
|
|
(std::is_void<T>::value ||
|
|
detail::is_explicitly_constructible<value_type, typename basic_result<T, U, V>::value_type>) // if our value types are constructible
|
|
&&(std::is_void<U>::value ||
|
|
detail::is_explicitly_constructible<error_type, typename basic_result<T, U, V>::error_type>) // if our error types are constructible
|
|
;
|
|
// Predicate for the converting constructor from a make_error_code() of the input to be available.
|
|
template <class T, class U, class V>
|
|
static constexpr bool enable_make_error_code_compatible_conversion = //
|
|
trait::is_error_code_available<std::decay_t<error_type>>::value // if error type has an error code
|
|
&& !enable_compatible_conversion<T, U, V> // and the normal compatible conversion is not available
|
|
&& (std::is_void<T>::value ||
|
|
detail::is_explicitly_constructible<value_type, typename basic_result<T, U, V>::value_type>) // and if our value types are constructible
|
|
&&detail::is_explicitly_constructible<error_type,
|
|
typename trait::is_error_code_available<U>::type>; // and our error type is constructible from a make_error_code()
|
|
// Predicate for the converting constructor from a make_exception_ptr() of the input to be available.
|
|
template <class T, class U, class V>
|
|
static constexpr bool enable_make_exception_ptr_compatible_conversion = //
|
|
trait::is_exception_ptr_available<std::decay_t<error_type>>::value // if error type has an exception ptr
|
|
&& !enable_compatible_conversion<T, U, V> // and the normal compatible conversion is not available
|
|
&& (std::is_void<T>::value ||
|
|
detail::is_explicitly_constructible<value_type, typename basic_result<T, U, V>::value_type>) // and if our value types are constructible
|
|
&&detail::is_explicitly_constructible<error_type, typename trait::is_exception_ptr_available<U>::type>; // and our error type is constructible from a
|
|
// make_exception_ptr()
|
|
// Predicate for the implicit converting inplace constructor from a compatible input to be available.
|
|
struct disable_inplace_value_error_constructor;
|
|
template <class... Args>
|
|
using choose_inplace_value_error_constructor = std::conditional_t< //
|
|
detail::is_constructible<value_type, Args...> && detail::is_constructible<error_type, Args...>, //
|
|
disable_inplace_value_error_constructor, //
|
|
std::conditional_t< //
|
|
detail::is_constructible<value_type, Args...>, //
|
|
value_type, //
|
|
std::conditional_t< //
|
|
detail::is_constructible<error_type, Args...>, //
|
|
error_type, //
|
|
disable_inplace_value_error_constructor>>>;
|
|
template <class... Args>
|
|
static constexpr bool enable_inplace_value_error_constructor =
|
|
implicit_constructors_enabled //
|
|
&& !std::is_same<choose_inplace_value_error_constructor<Args...>, disable_inplace_value_error_constructor>::value;
|
|
};
|
|
template <class T, class U> constexpr inline const U &extract_value_from_success(const success_type<U> &v) { return v.value(); }
|
|
template <class T, class U> constexpr inline U &&extract_value_from_success(success_type<U> &&v) { return static_cast<success_type<U> &&>(v).value(); }
|
|
template <class T> constexpr inline T extract_value_from_success(const success_type<void> & /*unused*/) { return T{}; }
|
|
template <class T, class U, class V> constexpr inline const U &extract_error_from_failure(const failure_type<U, V> &v) { return v.error(); }
|
|
template <class T, class U, class V> constexpr inline U &&extract_error_from_failure(failure_type<U, V> &&v)
|
|
{
|
|
return static_cast<failure_type<U, V> &&>(v).error();
|
|
}
|
|
template <class T, class V> constexpr inline T extract_error_from_failure(const failure_type<void, V> & /*unused*/) { return T{}; }
|
|
template <class T> struct is_basic_result
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
template <class R, class S, class T> struct is_basic_result<basic_result<R, S, T>>
|
|
{
|
|
static constexpr bool value = true;
|
|
};
|
|
} // namespace detail
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type alias template <class T> is_basic_result. Potential doc page: `is_basic_result<T>`
|
|
*/
|
|
template <class T> using is_basic_result = detail::is_basic_result<std::decay_t<T>>;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T> static constexpr bool is_basic_result_v = detail::is_basic_result<std::decay_t<T>>::value;
|
|
namespace concepts
|
|
{
|
|
#if defined(__cpp_concepts)
|
|
/* The `basic_result` concept.
|
|
\requires That `U` matches a `basic_result`.
|
|
*/
|
|
template <class U>
|
|
concept OUTCOME_GCC6_CONCEPT_BOOL basic_result =
|
|
OUTCOME_V2_NAMESPACE::is_basic_result<U>::value ||
|
|
(requires(U v) { OUTCOME_V2_NAMESPACE::basic_result<typename U::value_type, typename U::error_type, typename U::no_value_policy_type>(v); } && //
|
|
detail::convertible<U, OUTCOME_V2_NAMESPACE::basic_result<typename U::value_type, typename U::error_type, typename U::no_value_policy_type>> && //
|
|
detail::base_of<OUTCOME_V2_NAMESPACE::basic_result<typename U::value_type, typename U::error_type, typename U::no_value_policy_type>, U>);
|
|
#else
|
|
namespace detail
|
|
{
|
|
inline no_match match_basic_result(...);
|
|
template <class R, class S, class NVP, class T, //
|
|
typename = typename T::value_type, //
|
|
typename = typename T::error_type, //
|
|
typename = typename T::no_value_policy_type, //
|
|
typename std::enable_if_t<std::is_convertible<T, OUTCOME_V2_NAMESPACE::basic_result<R, S, NVP>>::value && //
|
|
std::is_base_of<OUTCOME_V2_NAMESPACE::basic_result<R, S, NVP>, T>::value,
|
|
bool> = true>
|
|
inline OUTCOME_V2_NAMESPACE::basic_result<R, S, NVP> match_basic_result(OUTCOME_V2_NAMESPACE::basic_result<R, S, NVP> &&, T &&);
|
|
template <class U>
|
|
static constexpr bool basic_result = OUTCOME_V2_NAMESPACE::is_basic_result<U>::value ||
|
|
!std::is_same<no_match, decltype(match_basic_result(std::declval<OUTCOME_V2_NAMESPACE::detail::devoid<U>>(),
|
|
std::declval<OUTCOME_V2_NAMESPACE::detail::devoid<U>>()))>::value;
|
|
} // namespace detail
|
|
/* The `basic_result` concept.
|
|
\requires That `U` matches a `basic_result`.
|
|
*/
|
|
template <class U> static constexpr bool basic_result = detail::basic_result<U>;
|
|
#endif
|
|
} // namespace concepts
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
namespace hooks
|
|
{
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class R, class S, class NoValuePolicy> constexpr inline uint16_t spare_storage(const detail::basic_result_storage<R, S, NoValuePolicy> *r) noexcept
|
|
{
|
|
return r->_state._status.spare_storage_value;
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class R, class S, class NoValuePolicy>
|
|
constexpr inline void set_spare_storage(detail::basic_result_storage<R, S, NoValuePolicy> *r, uint16_t v) noexcept
|
|
{
|
|
r->_state._status.spare_storage_value = v;
|
|
}
|
|
} // namespace hooks
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition template <class R, class S, class NoValuePolicy> basic_result. Potential doc page: `basic_result<T, E, NoValuePolicy>`
|
|
*/
|
|
template <class R, class S, class NoValuePolicy> //
|
|
class OUTCOME_NODISCARD basic_result : public detail::basic_result_final<R, S, NoValuePolicy>
|
|
{
|
|
static_assert(trait::type_can_be_used_in_basic_result<R>, "The type R cannot be used in a basic_result");
|
|
static_assert(trait::type_can_be_used_in_basic_result<S>, "The type S cannot be used in a basic_result");
|
|
using base = detail::basic_result_final<R, S, NoValuePolicy>;
|
|
struct implicit_constructors_disabled_tag
|
|
{
|
|
};
|
|
struct value_converting_constructor_tag
|
|
{
|
|
};
|
|
struct error_converting_constructor_tag
|
|
{
|
|
};
|
|
struct error_condition_converting_constructor_tag
|
|
{
|
|
};
|
|
struct explicit_valueornone_converting_constructor_tag
|
|
{
|
|
};
|
|
struct explicit_valueorerror_converting_constructor_tag
|
|
{
|
|
};
|
|
struct explicit_compatible_copy_conversion_tag
|
|
{
|
|
};
|
|
struct explicit_compatible_move_conversion_tag
|
|
{
|
|
};
|
|
struct explicit_make_error_code_compatible_copy_conversion_tag
|
|
{
|
|
};
|
|
struct explicit_make_error_code_compatible_move_conversion_tag
|
|
{
|
|
};
|
|
struct explicit_make_exception_ptr_compatible_copy_conversion_tag
|
|
{
|
|
};
|
|
struct explicit_make_exception_ptr_compatible_move_conversion_tag
|
|
{
|
|
};
|
|
public:
|
|
using value_type = R;
|
|
using error_type = S;
|
|
using no_value_policy_type = NoValuePolicy;
|
|
using value_type_if_enabled = typename base::_value_type;
|
|
using error_type_if_enabled = typename base::_error_type;
|
|
template <class T, class U = S, class V = NoValuePolicy> using rebind = basic_result<T, U, V>;
|
|
protected:
|
|
// Requirement predicates for result.
|
|
struct predicate
|
|
{
|
|
using base = detail::result_predicates<value_type, error_type>;
|
|
// Predicate for any constructors to be available at all
|
|
static constexpr bool constructors_enabled = !std::is_same<std::decay_t<value_type>, std::decay_t<error_type>>::value;
|
|
// Predicate for implicit constructors to be available at all
|
|
static constexpr bool implicit_constructors_enabled = constructors_enabled && base::implicit_constructors_enabled;
|
|
// Predicate for the value converting constructor to be available.
|
|
template <class T>
|
|
static constexpr bool enable_value_converting_constructor = //
|
|
constructors_enabled //
|
|
&& !std::is_same<std::decay_t<T>, basic_result>::value // not my type
|
|
&& base::template enable_value_converting_constructor<T>;
|
|
// Predicate for the error converting constructor to be available.
|
|
template <class T>
|
|
static constexpr bool enable_error_converting_constructor = //
|
|
constructors_enabled //
|
|
&& !std::is_same<std::decay_t<T>, basic_result>::value // not my type
|
|
&& base::template enable_error_converting_constructor<T>;
|
|
// Predicate for the error condition converting constructor to be available.
|
|
template <class ErrorCondEnum>
|
|
static constexpr bool enable_error_condition_converting_constructor = //
|
|
constructors_enabled //
|
|
&& !std::is_same<std::decay_t<ErrorCondEnum>, basic_result>::value // not my type
|
|
&& base::template enable_error_condition_converting_constructor<ErrorCondEnum>;
|
|
// Predicate for the converting constructor from a compatible input to be available.
|
|
template <class T, class U, class V>
|
|
static constexpr bool enable_compatible_conversion = //
|
|
constructors_enabled //
|
|
&& !std::is_same<basic_result<T, U, V>, basic_result>::value // not my type
|
|
&& base::template enable_compatible_conversion<T, U, V>;
|
|
// Predicate for the converting constructor from a make_error_code() of the input to be available.
|
|
template <class T, class U, class V>
|
|
static constexpr bool enable_make_error_code_compatible_conversion = //
|
|
constructors_enabled //
|
|
&& !std::is_same<basic_result<T, U, V>, basic_result>::value // not my type
|
|
&& base::template enable_make_error_code_compatible_conversion<T, U, V>;
|
|
// Predicate for the converting constructor from a make_exception_ptr() of the input to be available.
|
|
template <class T, class U, class V>
|
|
static constexpr bool enable_make_exception_ptr_compatible_conversion = //
|
|
constructors_enabled //
|
|
&& !std::is_same<basic_result<T, U, V>, basic_result>::value // not my type
|
|
&& base::template enable_make_exception_ptr_compatible_conversion<T, U, V>;
|
|
// Predicate for the inplace construction of value to be available.
|
|
template <class... Args>
|
|
static constexpr bool enable_inplace_value_constructor = //
|
|
constructors_enabled //
|
|
&& (std::is_void<value_type>::value //
|
|
|| detail::is_constructible<value_type, Args...>);
|
|
// Predicate for the inplace construction of error to be available.
|
|
template <class... Args>
|
|
static constexpr bool enable_inplace_error_constructor = //
|
|
constructors_enabled //
|
|
&& (std::is_void<error_type>::value //
|
|
|| detail::is_constructible<error_type, Args...>);
|
|
// Predicate for the implicit converting inplace constructor to be available.
|
|
template <class... Args>
|
|
static constexpr bool enable_inplace_value_error_constructor = //
|
|
constructors_enabled //
|
|
&&base::template enable_inplace_value_error_constructor<Args...>;
|
|
template <class... Args> using choose_inplace_value_error_constructor = typename base::template choose_inplace_value_error_constructor<Args...>;
|
|
};
|
|
public:
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
basic_result() = delete;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
basic_result(basic_result && /*unused*/) = default; // NOLINT
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
basic_result(const basic_result & /*unused*/) = default;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
basic_result &operator=(basic_result && /*unused*/) = default; // NOLINT
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
basic_result &operator=(const basic_result & /*unused*/) = default;
|
|
~basic_result() = default;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class Arg, class... Args)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!predicate::constructors_enabled && (sizeof...(Args) >= 0)))
|
|
basic_result(Arg && /*unused*/, Args &&... /*unused*/) = delete; // NOLINT basic_result<T, T> is NOT SUPPORTED, see docs!
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED((predicate::constructors_enabled && !predicate::implicit_constructors_enabled //
|
|
&& (detail::is_implicitly_constructible<value_type, T> || detail::is_implicitly_constructible<error_type, T>) )))
|
|
basic_result(T && /*unused*/, implicit_constructors_disabled_tag /*unused*/ = implicit_constructors_disabled_tag()) =
|
|
delete; // NOLINT Implicit constructors disabled, use explicit in_place_type<T>, success() or failure(). see docs!
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_value_converting_constructor<T>))
|
|
constexpr basic_result(T &&t, value_converting_constructor_tag /*unused*/ = value_converting_constructor_tag()) noexcept(
|
|
detail::is_nothrow_constructible<value_type, T>) // NOLINT
|
|
: base{in_place_type<typename base::value_type>, static_cast<T &&>(t)}
|
|
{
|
|
no_value_policy_type::on_result_construction(this, static_cast<T &&>(t));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_error_converting_constructor<T>))
|
|
constexpr basic_result(T &&t, error_converting_constructor_tag /*unused*/ = error_converting_constructor_tag()) noexcept(
|
|
detail::is_nothrow_constructible<error_type, T>) // NOLINT
|
|
: base{in_place_type<typename base::error_type>, static_cast<T &&>(t)}
|
|
{
|
|
no_value_policy_type::on_result_construction(this, static_cast<T &&>(t));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class ErrorCondEnum)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(error_type(make_error_code(ErrorCondEnum()))), //
|
|
OUTCOME_TPRED(predicate::template enable_error_condition_converting_constructor<ErrorCondEnum>))
|
|
constexpr basic_result(ErrorCondEnum &&t, error_condition_converting_constructor_tag /*unused*/ = error_condition_converting_constructor_tag()) noexcept(
|
|
noexcept(error_type(make_error_code(static_cast<ErrorCondEnum &&>(t))))) // NOLINT
|
|
: base{in_place_type<typename base::error_type>, make_error_code(t)}
|
|
{
|
|
no_value_policy_type::on_result_construction(this, static_cast<ErrorCondEnum &&>(t));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(convert::value_or_error<basic_result, std::decay_t<T>>::enable_result_inputs || !concepts::basic_result<T>), //
|
|
OUTCOME_TEXPR(convert::value_or_error<basic_result, std::decay_t<T>>{}(std::declval<T>())))
|
|
constexpr explicit basic_result(T &&o,
|
|
explicit_valueorerror_converting_constructor_tag /*unused*/ = explicit_valueorerror_converting_constructor_tag()) // NOLINT
|
|
: basic_result{convert::value_or_error<basic_result, std::decay_t<T>>{}(static_cast<T &&>(o))}
|
|
{
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V>))
|
|
constexpr explicit basic_result(
|
|
const basic_result<T, U, V> &o,
|
|
explicit_compatible_copy_conversion_tag /*unused*/ =
|
|
explicit_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U>)
|
|
: base{typename base::compatible_conversion_tag(), o}
|
|
{
|
|
no_value_policy_type::on_result_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V>))
|
|
constexpr explicit basic_result(
|
|
basic_result<T, U, V> &&o,
|
|
explicit_compatible_move_conversion_tag /*unused*/ =
|
|
explicit_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U>)
|
|
: base{typename base::compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
|
|
{
|
|
no_value_policy_type::on_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<T, U, V>))
|
|
constexpr explicit basic_result(const basic_result<T, U, V> &o,
|
|
explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ =
|
|
explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T>
|
|
&&noexcept(make_error_code(std::declval<U>())))
|
|
: base{typename base::make_error_code_compatible_conversion_tag(), o}
|
|
{
|
|
no_value_policy_type::on_result_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<T, U, V>))
|
|
constexpr explicit basic_result(basic_result<T, U, V> &&o,
|
|
explicit_make_error_code_compatible_move_conversion_tag /*unused*/ =
|
|
explicit_make_error_code_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T>
|
|
&&noexcept(make_error_code(std::declval<U>())))
|
|
: base{typename base::make_error_code_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
|
|
{
|
|
no_value_policy_type::on_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<T, U, V>))
|
|
constexpr explicit basic_result(const basic_result<T, U, V> &o,
|
|
explicit_make_exception_ptr_compatible_copy_conversion_tag /*unused*/ =
|
|
explicit_make_exception_ptr_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T>
|
|
&&noexcept(make_exception_ptr(std::declval<U>())))
|
|
: base{typename base::make_exception_ptr_compatible_conversion_tag(), o}
|
|
{
|
|
no_value_policy_type::on_result_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<T, U, V>))
|
|
constexpr explicit basic_result(basic_result<T, U, V> &&o,
|
|
explicit_make_exception_ptr_compatible_move_conversion_tag /*unused*/ =
|
|
explicit_make_exception_ptr_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T>
|
|
&&noexcept(make_exception_ptr(std::declval<U>())))
|
|
: base{typename base::make_exception_ptr_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
|
|
{
|
|
no_value_policy_type::on_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class... Args)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<Args...>))
|
|
constexpr explicit basic_result(in_place_type_t<value_type_if_enabled> _, Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, Args...>)
|
|
: base{_, static_cast<Args &&>(args)...}
|
|
{
|
|
no_value_policy_type::on_result_in_place_construction(this, in_place_type<value_type>, static_cast<Args &&>(args)...);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class U, class... Args)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<std::initializer_list<U>, Args...>))
|
|
constexpr explicit basic_result(in_place_type_t<value_type_if_enabled> _, std::initializer_list<U> il,
|
|
Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, std::initializer_list<U>, Args...>)
|
|
: base{_, il, static_cast<Args &&>(args)...}
|
|
{
|
|
no_value_policy_type::on_result_in_place_construction(this, in_place_type<value_type>, il, static_cast<Args &&>(args)...);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class... Args)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<Args...>))
|
|
constexpr explicit basic_result(in_place_type_t<error_type_if_enabled> _, Args &&... args) noexcept(detail::is_nothrow_constructible<error_type, Args...>)
|
|
: base{_, static_cast<Args &&>(args)...}
|
|
{
|
|
no_value_policy_type::on_result_in_place_construction(this, in_place_type<error_type>, static_cast<Args &&>(args)...);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class U, class... Args)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<std::initializer_list<U>, Args...>))
|
|
constexpr explicit basic_result(in_place_type_t<error_type_if_enabled> _, std::initializer_list<U> il,
|
|
Args &&... args) noexcept(detail::is_nothrow_constructible<error_type, std::initializer_list<U>, Args...>)
|
|
: base{_, il, static_cast<Args &&>(args)...}
|
|
{
|
|
no_value_policy_type::on_result_in_place_construction(this, in_place_type<error_type>, il, static_cast<Args &&>(args)...);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class A1, class A2, class... Args)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_inplace_value_error_constructor<A1, A2, Args...>))
|
|
constexpr basic_result(A1 &&a1, A2 &&a2, Args &&... args) noexcept(noexcept(
|
|
typename predicate::template choose_inplace_value_error_constructor<A1, A2, Args...>(std::declval<A1>(), std::declval<A2>(), std::declval<Args>()...)))
|
|
: basic_result(in_place_type<typename predicate::template choose_inplace_value_error_constructor<A1, A2, Args...>>, static_cast<A1 &&>(a1),
|
|
static_cast<A2 &&>(a2), static_cast<Args &&>(args)...)
|
|
{
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
constexpr basic_result(const success_type<void> &o) noexcept(std::is_nothrow_default_constructible<value_type>::value) // NOLINT
|
|
: base{in_place_type<value_type_if_enabled>}
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_result_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, void, void>))
|
|
constexpr basic_result(const success_type<T> &o) noexcept(detail::is_nothrow_constructible<value_type, T>) // NOLINT
|
|
: base{in_place_type<value_type_if_enabled>, detail::extract_value_from_success<value_type>(o)}
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_result_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void>))
|
|
constexpr basic_result(success_type<T> &&o) noexcept(detail::is_nothrow_constructible<value_type, T>) // NOLINT
|
|
: base{in_place_type<value_type_if_enabled>, detail::extract_value_from_success<value_type>(static_cast<success_type<T> &&>(o))}
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_result_move_construction(this, static_cast<success_type<T> &&>(o));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_compatible_conversion<void, T, void>))
|
|
constexpr basic_result(const failure_type<T> &o, explicit_compatible_copy_conversion_tag /*unused*/ = explicit_compatible_copy_conversion_tag()) noexcept(
|
|
detail::is_nothrow_constructible<error_type, T>) // NOLINT
|
|
: base{in_place_type<error_type_if_enabled>, detail::extract_error_from_failure<error_type>(o)}
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_result_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_compatible_conversion<void, T, void>))
|
|
constexpr basic_result(failure_type<T> &&o, explicit_compatible_move_conversion_tag /*unused*/ = explicit_compatible_move_conversion_tag()) noexcept(
|
|
detail::is_nothrow_constructible<error_type, T>) // NOLINT
|
|
: base{in_place_type<error_type_if_enabled>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o))}
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_result_move_construction(this, static_cast<failure_type<T> &&>(o));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<void, T, void>))
|
|
constexpr basic_result(const failure_type<T> &o,
|
|
explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ =
|
|
explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT
|
|
: base{in_place_type<error_type_if_enabled>, make_error_code(detail::extract_error_from_failure<error_type>(o))}
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_result_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<void, T, void>))
|
|
constexpr basic_result(failure_type<T> &&o,
|
|
explicit_make_error_code_compatible_move_conversion_tag /*unused*/ =
|
|
explicit_make_error_code_compatible_move_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT
|
|
: base{in_place_type<error_type_if_enabled>, make_error_code(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))}
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_result_move_construction(this, static_cast<failure_type<T> &&>(o));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<void, T, void>))
|
|
constexpr basic_result(const failure_type<T> &o,
|
|
explicit_make_exception_ptr_compatible_copy_conversion_tag /*unused*/ =
|
|
explicit_make_exception_ptr_compatible_copy_conversion_tag()) noexcept(noexcept(make_exception_ptr(std::declval<T>()))) // NOLINT
|
|
: base{in_place_type<error_type_if_enabled>, make_exception_ptr(detail::extract_error_from_failure<error_type>(o))}
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_result_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<void, T, void>))
|
|
constexpr basic_result(failure_type<T> &&o,
|
|
explicit_make_exception_ptr_compatible_move_conversion_tag /*unused*/ =
|
|
explicit_make_exception_ptr_compatible_move_conversion_tag()) noexcept(noexcept(make_exception_ptr(std::declval<T>()))) // NOLINT
|
|
: base{in_place_type<error_type_if_enabled>, make_exception_ptr(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))}
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_result_move_construction(this, static_cast<failure_type<T> &&>(o));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
constexpr void swap(basic_result &o) noexcept((std::is_void<value_type>::value || detail::is_nothrow_swappable<value_type>::value) //
|
|
&& (std::is_void<error_type>::value || detail::is_nothrow_swappable<error_type>::value))
|
|
{
|
|
this->_state.swap(o._state);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
auto as_failure() const & { return failure(this->assume_error(), hooks::spare_storage(this)); }
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
auto as_failure() &&
|
|
{
|
|
this->_state._status.set_have_moved_from(true);
|
|
return failure(static_cast<basic_result &&>(*this).assume_error(), hooks::spare_storage(this));
|
|
}
|
|
#ifdef __APPLE__
|
|
failure_type<error_type> _xcode_workaround_as_failure() &&;
|
|
#endif
|
|
};
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class R, class S, class P> inline void swap(basic_result<R, S, P> &a, basic_result<R, S, P> &b) noexcept(noexcept(a.swap(b)))
|
|
{
|
|
a.swap(b);
|
|
}
|
|
#if !defined(NDEBUG)
|
|
// Check is trivial in all ways except default constructibility
|
|
// static_assert(std::is_trivial<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivial!");
|
|
// static_assert(std::is_trivially_default_constructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially default
|
|
// constructible!");
|
|
static_assert(std::is_trivially_copyable<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially copyable!");
|
|
static_assert(std::is_trivially_assignable<basic_result<int, long, policy::all_narrow>, basic_result<int, long, policy::all_narrow>>::value,
|
|
"result<int> is not trivially assignable!");
|
|
static_assert(std::is_trivially_destructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially destructible!");
|
|
static_assert(std::is_trivially_copy_constructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially copy constructible!");
|
|
static_assert(std::is_trivially_move_constructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially move constructible!");
|
|
static_assert(std::is_trivially_copy_assignable<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially copy assignable!");
|
|
static_assert(std::is_trivially_move_assignable<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially move assignable!");
|
|
// Also check is standard layout
|
|
static_assert(std::is_standard_layout<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not a standard layout type!");
|
|
#endif
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#ifdef __clang__
|
|
#pragma clang diagnostic pop
|
|
#endif
|
|
#endif
|
|
/* Traits for Outcome
|
|
(C) 2018-2019 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
|
|
File Created: March 2018
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_TRAIT_STD_ERROR_CODE_HPP
|
|
#define OUTCOME_TRAIT_STD_ERROR_CODE_HPP
|
|
#include <system_error>
|
|
OUTCOME_V2_NAMESPACE_BEGIN
|
|
namespace detail
|
|
{
|
|
// Customise _set_error_is_errno
|
|
template <class State> constexpr inline void _set_error_is_errno(State &state, const std::error_code &error)
|
|
{
|
|
if(error.category() == std::generic_category()
|
|
#ifndef _WIN32
|
|
|| error.category() == std::system_category()
|
|
#endif
|
|
)
|
|
{
|
|
state._status.set_have_error_is_errno(true);
|
|
}
|
|
}
|
|
template <class State> constexpr inline void _set_error_is_errno(State &state, const std::error_condition &error)
|
|
{
|
|
if(error.category() == std::generic_category()
|
|
#ifndef _WIN32
|
|
|| error.category() == std::system_category()
|
|
#endif
|
|
)
|
|
{
|
|
state._status.set_have_error_is_errno(true);
|
|
}
|
|
}
|
|
template <class State> constexpr inline void _set_error_is_errno(State &state, const std::errc & /*unused*/) {
|
|
state._status.set_have_error_is_errno(true);
|
|
}
|
|
} // namespace detail
|
|
namespace policy
|
|
{
|
|
namespace detail
|
|
{
|
|
/* Pass through `make_error_code` function for `std::error_code`.
|
|
*/
|
|
inline std::error_code make_error_code(std::error_code v) { return v; }
|
|
// Try ADL, if not use fall backs above
|
|
template <class T> constexpr inline decltype(auto) error_code(T &&v) { return make_error_code(std::forward<T>(v)); }
|
|
struct std_enum_overload_tag
|
|
{
|
|
};
|
|
} // namespace detail
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T> constexpr inline decltype(auto) error_code(T &&v) { return detail::error_code(std::forward<T>(v)); }
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
// inline void outcome_throw_as_system_error_with_payload(...) = delete; // To use the error_code_throw_as_system_error policy with a custom Error type, you must define a outcome_throw_as_system_error_with_payload() free function to say how to handle the payload
|
|
inline void outcome_throw_as_system_error_with_payload(const std::error_code &error) { OUTCOME_THROW_EXCEPTION(std::system_error(error)); } // NOLINT
|
|
OUTCOME_TEMPLATE(class Error)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(std::is_error_code_enum<std::decay_t<Error>>::value || std::is_error_condition_enum<std::decay_t<Error>>::value))
|
|
inline void outcome_throw_as_system_error_with_payload(Error &&error, detail::std_enum_overload_tag /*unused*/ = detail::std_enum_overload_tag()) { OUTCOME_THROW_EXCEPTION(std::system_error(make_error_code(error))); } // NOLINT
|
|
} // namespace policy
|
|
namespace trait
|
|
{
|
|
namespace detail
|
|
{
|
|
template <> struct _is_error_code_available<std::error_code>
|
|
{
|
|
// Shortcut this for lower build impact
|
|
static constexpr bool value = true;
|
|
using type = std::error_code;
|
|
};
|
|
} // namespace detail
|
|
// std::error_code is an error type
|
|
template <> struct is_error_type<std::error_code>
|
|
{
|
|
static constexpr bool value = true;
|
|
};
|
|
// For std::error_code, std::is_error_condition_enum<> is the trait we want.
|
|
template <class Enum> struct is_error_type_enum<std::error_code, Enum>
|
|
{
|
|
static constexpr bool value = std::is_error_condition_enum<Enum>::value;
|
|
};
|
|
} // namespace trait
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* Traits for Outcome
|
|
(C) 2018-2019 Niall Douglas <http://www.nedproductions.biz/> (3 commits)
|
|
File Created: March 2018
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_TRAIT_STD_EXCEPTION_HPP
|
|
#define OUTCOME_TRAIT_STD_EXCEPTION_HPP
|
|
#include <exception>
|
|
OUTCOME_V2_NAMESPACE_BEGIN
|
|
namespace policy
|
|
{
|
|
namespace detail
|
|
{
|
|
/* Pass through `make_exception_ptr` function for `std::exception_ptr`.
|
|
*/
|
|
inline std::exception_ptr make_exception_ptr(std::exception_ptr v) { return v; }
|
|
// Try ADL, if not use fall backs above
|
|
template <class T> constexpr inline decltype(auto) exception_ptr(T &&v) { return make_exception_ptr(std::forward<T>(v)); }
|
|
} // namespace detail
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T> constexpr inline decltype(auto) exception_ptr(T &&v) { return detail::exception_ptr(std::forward<T>(v)); }
|
|
namespace detail
|
|
{
|
|
template <bool has_error_payload> struct _rethrow_exception
|
|
{
|
|
template <class Exception> explicit _rethrow_exception(Exception && /*unused*/) // NOLINT
|
|
{
|
|
}
|
|
};
|
|
template <> struct _rethrow_exception<true>
|
|
{
|
|
template <class Exception> explicit _rethrow_exception(Exception &&excpt) // NOLINT
|
|
{
|
|
// ADL
|
|
rethrow_exception(policy::exception_ptr(std::forward<Exception>(excpt)));
|
|
}
|
|
};
|
|
} // namespace detail
|
|
} // namespace policy
|
|
namespace trait
|
|
{
|
|
namespace detail
|
|
{
|
|
// Shortcut this for lower build impact
|
|
template <> struct _is_exception_ptr_available<std::exception_ptr>
|
|
{
|
|
static constexpr bool value = true;
|
|
using type = std::exception_ptr;
|
|
};
|
|
} // namespace detail
|
|
// std::exception_ptr is an error type
|
|
template <> struct is_error_type<std::exception_ptr>
|
|
{
|
|
static constexpr bool value = true;
|
|
};
|
|
} // namespace trait
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* Policies for result and outcome
|
|
(C) 2018-2019 Niall Douglas <http://www.nedproductions.biz/> (4 commits)
|
|
File Created: Sep 2018
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_POLICY_FAIL_TO_COMPILE_OBSERVERS_HPP
|
|
#define OUTCOME_POLICY_FAIL_TO_COMPILE_OBSERVERS_HPP
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
#define OUTCOME_FAIL_TO_COMPILE_OBSERVERS_MESSAGE "Attempt to wide observe value, error or " "exception for a basic_result/basic_outcome given an EC or EP type which is not void, and for whom " "trait::is_error_code_available<EC>, trait::is_exception_ptr_available<EC>, and trait::is_exception_ptr_available<EP> " "are all false. Please specify a NoValuePolicy to tell basic_result/basic_outcome what to do, or else use " "a more specific convenience type alias such as unchecked<T, E> to indicate you want the wide " "observers to be narrow, or checked<T, E> to indicate you always want an exception throw etc."
|
|
namespace policy
|
|
{
|
|
struct fail_to_compile_observers : base
|
|
{
|
|
template <class Impl> static constexpr void wide_value_check(Impl && /* unused */) { static_assert(!std::is_same<Impl, Impl>::value, "Attempt to wide observe value, error or " "exception for a basic_result/basic_outcome given an EC or EP type which is not void, and for whom " "trait::is_error_code_available<EC>, trait::is_exception_ptr_available<EC>, and trait::is_exception_ptr_available<EP> " "are all false. Please specify a NoValuePolicy to tell basic_result/basic_outcome what to do, or else use " "a more specific convenience type alias such as unchecked<T, E> to indicate you want the wide " "observers to be narrow, or checked<T, E> to indicate you always want an exception throw etc."); }
|
|
template <class Impl> static constexpr void wide_error_check(Impl && /* unused */) { static_assert(!std::is_same<Impl, Impl>::value, "Attempt to wide observe value, error or " "exception for a basic_result/basic_outcome given an EC or EP type which is not void, and for whom " "trait::is_error_code_available<EC>, trait::is_exception_ptr_available<EC>, and trait::is_exception_ptr_available<EP> " "are all false. Please specify a NoValuePolicy to tell basic_result/basic_outcome what to do, or else use " "a more specific convenience type alias such as unchecked<T, E> to indicate you want the wide " "observers to be narrow, or checked<T, E> to indicate you always want an exception throw etc."); }
|
|
template <class Impl> static constexpr void wide_exception_check(Impl && /* unused */) { static_assert(!std::is_same<Impl, Impl>::value, "Attempt to wide observe value, error or " "exception for a basic_result/basic_outcome given an EC or EP type which is not void, and for whom " "trait::is_error_code_available<EC>, trait::is_exception_ptr_available<EC>, and trait::is_exception_ptr_available<EP> " "are all false. Please specify a NoValuePolicy to tell basic_result/basic_outcome what to do, or else use " "a more specific convenience type alias such as unchecked<T, E> to indicate you want the wide " "observers to be narrow, or checked<T, E> to indicate you always want an exception throw etc."); }
|
|
};
|
|
} // namespace policy
|
|
#undef OUTCOME_FAIL_TO_COMPILE_OBSERVERS_MESSAGE
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* Policies for result and outcome
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (8 commits)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_POLICY_RESULT_ERROR_CODE_THROW_AS_SYSTEM_ERROR_HPP
|
|
#define OUTCOME_POLICY_RESULT_ERROR_CODE_THROW_AS_SYSTEM_ERROR_HPP
|
|
/* Exception types throwable
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (9 commits)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_BAD_ACCESS_HPP
|
|
#define OUTCOME_BAD_ACCESS_HPP
|
|
#include <stdexcept>
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition bad_result_access. Potential doc page: `bad_result_access`
|
|
*/
|
|
class OUTCOME_SYMBOL_VISIBLE bad_result_access : public std::logic_error
|
|
{
|
|
public:
|
|
explicit bad_result_access(const char *what)
|
|
: std::logic_error(what)
|
|
{
|
|
}
|
|
};
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition template <class S> bad_result_access_with. Potential doc page: `bad_result_access_with<EC>`
|
|
*/
|
|
template <class S> class OUTCOME_SYMBOL_VISIBLE bad_result_access_with : public bad_result_access
|
|
{
|
|
S _error;
|
|
public:
|
|
explicit bad_result_access_with(S v)
|
|
: bad_result_access("no value")
|
|
, _error(std::move(v))
|
|
{
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
const S &error() const & { return _error; }
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
S &error() & { return _error; }
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
const S &&error() const && { return _error; }
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
S &&error() && { return _error; }
|
|
};
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition bad_outcome_access. Potential doc page: `bad_outcome_access`
|
|
*/
|
|
class OUTCOME_SYMBOL_VISIBLE bad_outcome_access : public std::logic_error
|
|
{
|
|
public:
|
|
explicit bad_outcome_access(const char *what)
|
|
: std::logic_error(what)
|
|
{
|
|
}
|
|
};
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
#include <system_error>
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace policy
|
|
{
|
|
template <class T, class EC, class E> struct error_code_throw_as_system_error;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T, class EC> struct error_code_throw_as_system_error<T, EC, void> : base
|
|
{
|
|
template <class Impl> static constexpr void wide_value_check(Impl &&self)
|
|
{
|
|
if(!base::_has_value(std::forward<Impl>(self)))
|
|
{
|
|
if(base::_has_error(std::forward<Impl>(self)))
|
|
{
|
|
// ADL discovered
|
|
outcome_throw_as_system_error_with_payload(base::_error(std::forward<Impl>(self)));
|
|
}
|
|
OUTCOME_THROW_EXCEPTION(bad_result_access("no value")); // NOLINT
|
|
}
|
|
}
|
|
template <class Impl> static constexpr void wide_error_check(Impl &&self)
|
|
{
|
|
if(!base::_has_error(std::forward<Impl>(self)))
|
|
{
|
|
OUTCOME_THROW_EXCEPTION(bad_result_access("no error")); // NOLINT
|
|
}
|
|
}
|
|
};
|
|
} // namespace policy
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* Policies for result and outcome
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_POLICY_RESULT_EXCEPTION_PTR_RETHROW_HPP
|
|
#define OUTCOME_POLICY_RESULT_EXCEPTION_PTR_RETHROW_HPP
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace policy
|
|
{
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T, class EC, class E> struct exception_ptr_rethrow;
|
|
template <class T, class EC> struct exception_ptr_rethrow<T, EC, void> : base
|
|
{
|
|
template <class Impl> static constexpr void wide_value_check(Impl &&self)
|
|
{
|
|
if(!base::_has_value(std::forward<Impl>(self)))
|
|
{
|
|
if(base::_has_error(std::forward<Impl>(self)))
|
|
{
|
|
// ADL
|
|
rethrow_exception(policy::exception_ptr(base::_error(std::forward<Impl>(self))));
|
|
}
|
|
OUTCOME_THROW_EXCEPTION(bad_result_access("no value")); // NOLINT
|
|
}
|
|
}
|
|
template <class Impl> static constexpr void wide_error_check(Impl &&self)
|
|
{
|
|
if(!base::_has_error(std::forward<Impl>(self)))
|
|
{
|
|
OUTCOME_THROW_EXCEPTION(bad_result_access("no error")); // NOLINT
|
|
}
|
|
}
|
|
};
|
|
} // namespace policy
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* Policies for result and outcome
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (13 commits)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_POLICY_THROW_BAD_RESULT_ACCESS_HPP
|
|
#define OUTCOME_POLICY_THROW_BAD_RESULT_ACCESS_HPP
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace policy
|
|
{
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition throw_bad_result_access. Potential doc page: NOT FOUND
|
|
*/
|
|
template <class EC, class EP> struct throw_bad_result_access : base
|
|
{
|
|
template <class Impl> static constexpr void wide_value_check(Impl &&self)
|
|
{
|
|
if(!base::_has_value(std::forward<Impl>(self)))
|
|
{
|
|
OUTCOME_THROW_EXCEPTION(bad_outcome_access("no value")); // NOLINT
|
|
}
|
|
}
|
|
template <class Impl> static constexpr void wide_error_check(Impl &&self)
|
|
{
|
|
if(!base::_has_error(std::forward<Impl>(self)))
|
|
{
|
|
OUTCOME_THROW_EXCEPTION(bad_outcome_access("no error")); // NOLINT
|
|
}
|
|
}
|
|
template <class Impl> static constexpr void wide_exception_check(Impl &&self)
|
|
{
|
|
if(!base::_has_exception(std::forward<Impl>(self)))
|
|
{
|
|
OUTCOME_THROW_EXCEPTION(bad_outcome_access("no exception")); // NOLINT
|
|
}
|
|
}
|
|
};
|
|
template <class EC> struct throw_bad_result_access<EC, void> : base
|
|
{
|
|
template <class Impl> static constexpr void wide_value_check(Impl &&self)
|
|
{
|
|
if(!base::_has_value(std::forward<Impl>(self)))
|
|
{
|
|
if(base::_has_error(std::forward<Impl>(self)))
|
|
{
|
|
OUTCOME_THROW_EXCEPTION(bad_result_access_with<EC>(base::_error(std::forward<Impl>(self))));
|
|
}
|
|
OUTCOME_THROW_EXCEPTION(bad_result_access("no value")); // NOLINT
|
|
}
|
|
}
|
|
template <class Impl> static constexpr void wide_error_check(Impl &&self)
|
|
{
|
|
if(!base::_has_error(std::forward<Impl>(self)))
|
|
{
|
|
OUTCOME_THROW_EXCEPTION(bad_result_access("no error")); // NOLINT
|
|
}
|
|
}
|
|
};
|
|
} // namespace policy
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
namespace policy
|
|
{
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T, class EC, class E>
|
|
using default_policy = std::conditional_t< //
|
|
std::is_void<EC>::value && std::is_void<E>::value,
|
|
terminate, //
|
|
std::conditional_t< //
|
|
trait::is_error_code_available<EC>::value, error_code_throw_as_system_error<T, EC, E>, //
|
|
std::conditional_t< //
|
|
trait::is_exception_ptr_available<EC>::value || trait::is_exception_ptr_available<E>::value, exception_ptr_rethrow<T, EC, E>, //
|
|
fail_to_compile_observers //
|
|
>>>;
|
|
} // namespace policy
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class R, class S = std::error_code, class NoValuePolicy = policy::default_policy<R, S, void>> //
|
|
using std_result = basic_result<R, S, NoValuePolicy>;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type alias template <class R, class S = std::error_code> std_unchecked. Potential doc page: `std_unchecked<T, E = std::error_code>`
|
|
*/
|
|
template <class R, class S = std::error_code> using std_unchecked = std_result<R, S, policy::all_narrow>;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type alias template <class R, class S = std::error_code> std_checked. Potential doc page: `std_checked<T, E = std::error_code>`
|
|
*/
|
|
template <class R, class S = std::error_code> using std_checked = std_result<R, S, policy::throw_bad_result_access<S, void>>;
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class R, class S = std::error_code, class NoValuePolicy = policy::default_policy<R, S, void>> //
|
|
using result = std_result<R, S, NoValuePolicy>;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type alias template <class R, class S = std::error_code> unchecked. Potential doc page: `unchecked<T, E = varies>`
|
|
*/
|
|
template <class R, class S = std::error_code> using unchecked = result<R, S, policy::all_narrow>;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type alias template <class R, class S = std::error_code> checked. Potential doc page: `checked<T, E = varies>`
|
|
*/
|
|
template <class R, class S = std::error_code> using checked = result<R, S, policy::throw_bad_result_access<S, void>>;
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* A less simple result type
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
|
|
File Created: June 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_STD_OUTCOME_HPP
|
|
#define OUTCOME_STD_OUTCOME_HPP
|
|
/* A less simple result type
|
|
(C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (20 commits)
|
|
File Created: June 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_BASIC_OUTCOME_HPP
|
|
#define OUTCOME_BASIC_OUTCOME_HPP
|
|
/* Exception observers for outcome type
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (3 commits)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_BASIC_OUTCOME_EXCEPTION_OBSERVERS_HPP
|
|
#define OUTCOME_BASIC_OUTCOME_EXCEPTION_OBSERVERS_HPP
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace detail
|
|
{
|
|
template <class Base, class R, class S, class P, class NoValuePolicy> class basic_outcome_exception_observers : public Base
|
|
{
|
|
public:
|
|
using exception_type = P;
|
|
using Base::Base;
|
|
constexpr inline exception_type &assume_exception() & noexcept;
|
|
constexpr inline const exception_type &assume_exception() const &noexcept;
|
|
constexpr inline exception_type &&assume_exception() && noexcept;
|
|
constexpr inline const exception_type &&assume_exception() const &&noexcept;
|
|
constexpr inline exception_type &exception() &;
|
|
constexpr inline const exception_type &exception() const &;
|
|
constexpr inline exception_type &&exception() &&;
|
|
constexpr inline const exception_type &&exception() const &&;
|
|
};
|
|
// Exception observers not present
|
|
template <class Base, class R, class S, class NoValuePolicy> class basic_outcome_exception_observers<Base, R, S, void, NoValuePolicy> : public Base
|
|
{
|
|
public:
|
|
using Base::Base;
|
|
constexpr void assume_exception() const noexcept { NoValuePolicy::narrow_exception_check(this); }
|
|
constexpr void exception() const { NoValuePolicy::wide_exception_check(this); }
|
|
};
|
|
} // namespace detail
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* Failure observers for outcome type
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (7 commits)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_BASIC_OUTCOME_FAILURE_OBSERVERS_HPP
|
|
#define OUTCOME_BASIC_OUTCOME_FAILURE_OBSERVERS_HPP
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace detail
|
|
{
|
|
namespace adl
|
|
{
|
|
struct search_detail_adl
|
|
{
|
|
};
|
|
// Do NOT use template requirements here!
|
|
template <class S, typename = decltype(basic_outcome_failure_exception_from_error(std::declval<S>()))>
|
|
inline auto _delayed_lookup_basic_outcome_failure_exception_from_error(const S &ec, search_detail_adl /*unused*/)
|
|
{
|
|
// ADL discovered
|
|
return basic_outcome_failure_exception_from_error(ec);
|
|
}
|
|
} // namespace adl
|
|
#if defined(_MSC_VER) && _MSC_VER <= 1923 // VS2019
|
|
// VS2017 and VS2019 with /permissive- chokes on the correct form due to over eager early instantiation.
|
|
template <class S, class P> inline void _delayed_lookup_basic_outcome_failure_exception_from_error(...) { static_assert(sizeof(S) == 0, "No specialisation for these error and exception types available!"); }
|
|
#else
|
|
template <class S, class P> inline void _delayed_lookup_basic_outcome_failure_exception_from_error(...) = delete; // NOLINT No specialisation for these error and exception types available!
|
|
#endif
|
|
template <class exception_type> inline exception_type current_exception_or_fatal(std::exception_ptr e) { std::rethrow_exception(e); }
|
|
template <> inline std::exception_ptr current_exception_or_fatal<std::exception_ptr>(std::exception_ptr e) { return e; }
|
|
template <class Base, class R, class S, class P, class NoValuePolicy> class basic_outcome_failure_observers : public Base
|
|
{
|
|
public:
|
|
using exception_type = P;
|
|
using Base::Base;
|
|
exception_type failure() const noexcept
|
|
{
|
|
#ifdef __cpp_exceptions
|
|
try
|
|
#endif
|
|
{
|
|
if(this->_state._status.have_exception())
|
|
{
|
|
return this->assume_exception();
|
|
}
|
|
if(this->_state._status.have_error())
|
|
{
|
|
return _delayed_lookup_basic_outcome_failure_exception_from_error(this->assume_error(), adl::search_detail_adl());
|
|
}
|
|
return exception_type();
|
|
}
|
|
#ifdef __cpp_exceptions
|
|
catch(...)
|
|
{
|
|
// Return the failure if exception_type is std::exception_ptr,
|
|
// otherwise terminate same as throwing an exception inside noexcept
|
|
return current_exception_or_fatal<exception_type>(std::current_exception());
|
|
}
|
|
#endif
|
|
}
|
|
};
|
|
} // namespace detail
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
#ifdef __clang__
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wdocumentation" // Standardese markup confuses clang
|
|
#endif
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
template <class R, class S, class P, class NoValuePolicy> //
|
|
class basic_outcome;
|
|
namespace detail
|
|
{
|
|
// May be reused by basic_outcome subclasses to save load on the compiler
|
|
template <class value_type, class error_type, class exception_type> struct outcome_predicates
|
|
{
|
|
using result = result_predicates<value_type, error_type>;
|
|
// Predicate for the implicit constructors to be available
|
|
static constexpr bool implicit_constructors_enabled = //
|
|
result::implicit_constructors_enabled //
|
|
&& !detail::is_implicitly_constructible<value_type, exception_type> //
|
|
&& !detail::is_implicitly_constructible<error_type, exception_type> //
|
|
&& !detail::is_implicitly_constructible<exception_type, value_type> //
|
|
&& !detail::is_implicitly_constructible<exception_type, error_type>;
|
|
// Predicate for the value converting constructor to be available.
|
|
template <class T>
|
|
static constexpr bool enable_value_converting_constructor = //
|
|
implicit_constructors_enabled //
|
|
&&result::template enable_value_converting_constructor<T> //
|
|
&& !detail::is_implicitly_constructible<exception_type, T>; // deliberately less tolerant of ambiguity than result's edition
|
|
// Predicate for the error converting constructor to be available.
|
|
template <class T>
|
|
static constexpr bool enable_error_converting_constructor = //
|
|
implicit_constructors_enabled //
|
|
&&result::template enable_error_converting_constructor<T> //
|
|
&& !detail::is_implicitly_constructible<exception_type, T>; // deliberately less tolerant of ambiguity than result's edition
|
|
// Predicate for the error condition converting constructor to be available.
|
|
template <class ErrorCondEnum>
|
|
static constexpr bool enable_error_condition_converting_constructor = result::template enable_error_condition_converting_constructor<ErrorCondEnum> //
|
|
&& !detail::is_implicitly_constructible<exception_type, ErrorCondEnum>;
|
|
// Predicate for the exception converting constructor to be available.
|
|
template <class T>
|
|
static constexpr bool enable_exception_converting_constructor = //
|
|
implicit_constructors_enabled //
|
|
&& !is_in_place_type_t<std::decay_t<T>>::value // not in place construction
|
|
&& !detail::is_implicitly_constructible<value_type, T> && !detail::is_implicitly_constructible<error_type, T> &&
|
|
detail::is_implicitly_constructible<exception_type, T>;
|
|
// Predicate for the error + exception converting constructor to be available.
|
|
template <class T, class U>
|
|
static constexpr bool enable_error_exception_converting_constructor = //
|
|
implicit_constructors_enabled //
|
|
&& !is_in_place_type_t<std::decay_t<T>>::value // not in place construction
|
|
&& !detail::is_implicitly_constructible<value_type, T> && detail::is_implicitly_constructible<error_type, T> //
|
|
&& !detail::is_implicitly_constructible<value_type, U> && detail::is_implicitly_constructible<exception_type, U>;
|
|
// Predicate for the converting copy constructor from a compatible outcome to be available.
|
|
template <class T, class U, class V, class W>
|
|
static constexpr bool enable_compatible_conversion = //
|
|
(std::is_void<T>::value ||
|
|
detail::is_explicitly_constructible<value_type, typename basic_outcome<T, U, V, W>::value_type>) // if our value types are constructible
|
|
&&(std::is_void<U>::value ||
|
|
detail::is_explicitly_constructible<error_type, typename basic_outcome<T, U, V, W>::error_type>) // if our error types are constructible
|
|
&&(std::is_void<V>::value ||
|
|
detail::is_explicitly_constructible<exception_type, typename basic_outcome<T, U, V, W>::exception_type>) // if our exception types are constructible
|
|
;
|
|
// Predicate for the converting constructor from a make_error_code() of the input to be available.
|
|
template <class T, class U, class V, class W>
|
|
static constexpr bool enable_make_error_code_compatible_conversion = //
|
|
trait::is_error_code_available<std::decay_t<error_type>>::value // if error type has an error code
|
|
&& !enable_compatible_conversion<T, U, V, W> // and the normal compatible conversion is not available
|
|
&& (std::is_void<T>::value ||
|
|
detail::is_explicitly_constructible<value_type, typename basic_outcome<T, U, V, W>::value_type>) // and if our value types are constructible
|
|
&&detail::is_explicitly_constructible<error_type,
|
|
typename trait::is_error_code_available<U>::type> // and our error type is constructible from a make_error_code()
|
|
&& (std::is_void<V>::value ||
|
|
detail::is_explicitly_constructible<exception_type, typename basic_outcome<T, U, V, W>::exception_type>); // and our exception types are constructible
|
|
// Predicate for the implicit converting inplace constructor from a compatible input to be available.
|
|
struct disable_inplace_value_error_exception_constructor;
|
|
template <class... Args>
|
|
using choose_inplace_value_error_exception_constructor = std::conditional_t< //
|
|
((static_cast<int>(detail::is_constructible<value_type, Args...>) + static_cast<int>(detail::is_constructible<error_type, Args...>) +
|
|
static_cast<int>(detail::is_constructible<exception_type, Args...>)) > 1), //
|
|
disable_inplace_value_error_exception_constructor, //
|
|
std::conditional_t< //
|
|
detail::is_constructible<value_type, Args...>, //
|
|
value_type, //
|
|
std::conditional_t< //
|
|
detail::is_constructible<error_type, Args...>, //
|
|
error_type, //
|
|
std::conditional_t< //
|
|
detail::is_constructible<exception_type, Args...>, //
|
|
exception_type, //
|
|
disable_inplace_value_error_exception_constructor>>>>;
|
|
template <class... Args>
|
|
static constexpr bool enable_inplace_value_error_exception_constructor = //
|
|
implicit_constructors_enabled &&
|
|
!std::is_same<choose_inplace_value_error_exception_constructor<Args...>, disable_inplace_value_error_exception_constructor>::value;
|
|
};
|
|
// Select whether to use basic_outcome_failure_observers or not
|
|
template <class Base, class R, class S, class P, class NoValuePolicy>
|
|
using select_basic_outcome_failure_observers = //
|
|
std::conditional_t<trait::is_error_code_available<S>::value && trait::is_exception_ptr_available<P>::value,
|
|
basic_outcome_failure_observers<Base, R, S, P, NoValuePolicy>, Base>;
|
|
template <class T, class U, class V> constexpr inline const V &extract_exception_from_failure(const failure_type<U, V> &v) { return v.exception(); }
|
|
template <class T, class U, class V> constexpr inline V &&extract_exception_from_failure(failure_type<U, V> &&v)
|
|
{
|
|
return static_cast<failure_type<U, V> &&>(v).exception();
|
|
}
|
|
template <class T, class U> constexpr inline const U &extract_exception_from_failure(const failure_type<U, void> &v) { return v.error(); }
|
|
template <class T, class U> constexpr inline U &&extract_exception_from_failure(failure_type<U, void> &&v)
|
|
{
|
|
return static_cast<failure_type<U, void> &&>(v).error();
|
|
}
|
|
template <class T> struct is_basic_outcome
|
|
{
|
|
static constexpr bool value = false;
|
|
};
|
|
template <class R, class S, class T, class N> struct is_basic_outcome<basic_outcome<R, S, T, N>>
|
|
{
|
|
static constexpr bool value = true;
|
|
};
|
|
} // namespace detail
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type alias template <class T> is_basic_outcome. Potential doc page: `is_basic_outcome<T>`
|
|
*/
|
|
template <class T> using is_basic_outcome = detail::is_basic_outcome<std::decay_t<T>>;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class T> static constexpr bool is_basic_outcome_v = detail::is_basic_outcome<std::decay_t<T>>::value;
|
|
namespace concepts
|
|
{
|
|
#if defined(__cpp_concepts)
|
|
/* The `basic_outcome` concept.
|
|
\requires That `U` matches a `basic_outcome`.
|
|
*/
|
|
template <class U>
|
|
concept OUTCOME_GCC6_CONCEPT_BOOL basic_outcome =
|
|
OUTCOME_V2_NAMESPACE::is_basic_outcome<U>::value ||
|
|
(requires(U v) {
|
|
OUTCOME_V2_NAMESPACE::basic_outcome<typename U::value_type, typename U::error_type, typename U::exception_type, typename U::no_value_policy_type>(v);
|
|
} && //
|
|
detail::convertible<
|
|
U, OUTCOME_V2_NAMESPACE::basic_outcome<typename U::value_type, typename U::error_type, typename U::exception_type, typename U::no_value_policy_type>> && //
|
|
detail::base_of<
|
|
OUTCOME_V2_NAMESPACE::basic_outcome<typename U::value_type, typename U::error_type, typename U::exception_type, typename U::no_value_policy_type>, U>);
|
|
#else
|
|
namespace detail
|
|
{
|
|
inline no_match match_basic_outcome(...);
|
|
template <class R, class S, class P, class NVP, class T, //
|
|
typename = typename T::value_type, //
|
|
typename = typename T::error_type, //
|
|
typename = typename T::exception_type, //
|
|
typename = typename T::no_value_policy_type, //
|
|
typename std::enable_if_t<std::is_convertible<T, OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP>>::value && //
|
|
std::is_base_of<OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP>, T>::value,
|
|
bool> = true>
|
|
inline OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP> match_basic_outcome(OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP> &&, T &&);
|
|
template <class U>
|
|
static constexpr bool basic_outcome =
|
|
OUTCOME_V2_NAMESPACE::is_basic_outcome<U>::value ||
|
|
!std::is_same<no_match, decltype(match_basic_outcome(std::declval<OUTCOME_V2_NAMESPACE::detail::devoid<U>>(),
|
|
std::declval<OUTCOME_V2_NAMESPACE::detail::devoid<U>>()))>::value;
|
|
} // namespace detail
|
|
/* The `basic_outcome` concept.
|
|
\requires That `U` matches a `basic_outcome`.
|
|
*/
|
|
template <class U> static constexpr bool basic_outcome = detail::basic_outcome<U>;
|
|
#endif
|
|
} // namespace concepts
|
|
namespace hooks
|
|
{
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class R, class S, class P, class NoValuePolicy, class U>
|
|
constexpr inline void override_outcome_exception(basic_outcome<R, S, P, NoValuePolicy> *o, U &&v) noexcept;
|
|
} // namespace hooks
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition template <class R, class S, class P, class NoValuePolicy> basic_outcome. Potential doc page: `basic_outcome<T, EC, EP, NoValuePolicy>`
|
|
*/
|
|
template <class R, class S, class P, class NoValuePolicy> //
|
|
class OUTCOME_NODISCARD basic_outcome
|
|
: public detail::select_basic_outcome_failure_observers<
|
|
detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy>
|
|
{
|
|
static_assert(trait::type_can_be_used_in_basic_result<P>, "The exception_type cannot be used");
|
|
static_assert(std::is_void<P>::value || std::is_default_constructible<P>::value, "exception_type must be void or default constructible");
|
|
using base = detail::select_basic_outcome_failure_observers<
|
|
detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy>;
|
|
friend struct policy::base;
|
|
template <class T, class U, class V, class W> //
|
|
friend class basic_outcome;
|
|
template <class T, class U, class V, class W, class X>
|
|
friend constexpr inline void hooks::override_outcome_exception(basic_outcome<T, U, V, W> *o, X &&v) noexcept; // NOLINT
|
|
struct implicit_constructors_disabled_tag
|
|
{
|
|
};
|
|
struct value_converting_constructor_tag
|
|
{
|
|
};
|
|
struct error_converting_constructor_tag
|
|
{
|
|
};
|
|
struct error_condition_converting_constructor_tag
|
|
{
|
|
};
|
|
struct exception_converting_constructor_tag
|
|
{
|
|
};
|
|
struct error_exception_converting_constructor_tag
|
|
{
|
|
};
|
|
struct explicit_valueorerror_converting_constructor_tag
|
|
{
|
|
};
|
|
struct explicit_compatible_copy_conversion_tag
|
|
{
|
|
};
|
|
struct explicit_compatible_move_conversion_tag
|
|
{
|
|
};
|
|
struct explicit_make_error_code_compatible_copy_conversion_tag
|
|
{
|
|
};
|
|
struct explicit_make_error_code_compatible_move_conversion_tag
|
|
{
|
|
};
|
|
struct error_failure_tag
|
|
{
|
|
};
|
|
struct exception_failure_tag
|
|
{
|
|
};
|
|
struct disable_in_place_value_type
|
|
{
|
|
};
|
|
struct disable_in_place_error_type
|
|
{
|
|
};
|
|
struct disable_in_place_exception_type
|
|
{
|
|
};
|
|
public:
|
|
using value_type = R;
|
|
using error_type = S;
|
|
using exception_type = P;
|
|
using no_value_policy_type = NoValuePolicy;
|
|
template <class T, class U = S, class V = P, class W = NoValuePolicy> using rebind = basic_outcome<T, U, V, W>;
|
|
protected:
|
|
// Requirement predicates for outcome.
|
|
struct predicate
|
|
{
|
|
using base = detail::outcome_predicates<value_type, error_type, exception_type>;
|
|
// Predicate for any constructors to be available at all
|
|
static constexpr bool constructors_enabled =
|
|
(!std::is_same<std::decay_t<value_type>, std::decay_t<error_type>>::value || (std::is_void<value_type>::value && std::is_void<error_type>::value)) //
|
|
&& (!std::is_same<std::decay_t<value_type>, std::decay_t<exception_type>>::value ||
|
|
(std::is_void<value_type>::value && std::is_void<exception_type>::value)) //
|
|
&& (!std::is_same<std::decay_t<error_type>, std::decay_t<exception_type>>::value ||
|
|
(std::is_void<error_type>::value && std::is_void<exception_type>::value)) //
|
|
;
|
|
// Predicate for implicit constructors to be available at all
|
|
static constexpr bool implicit_constructors_enabled = constructors_enabled && base::implicit_constructors_enabled;
|
|
// Predicate for the value converting constructor to be available.
|
|
template <class T>
|
|
static constexpr bool enable_value_converting_constructor = //
|
|
constructors_enabled //
|
|
&& !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type
|
|
&& base::template enable_value_converting_constructor<T>;
|
|
// Predicate for the error converting constructor to be available.
|
|
template <class T>
|
|
static constexpr bool enable_error_converting_constructor = //
|
|
constructors_enabled //
|
|
&& !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type
|
|
&& base::template enable_error_converting_constructor<T>;
|
|
// Predicate for the error condition converting constructor to be available.
|
|
template <class ErrorCondEnum>
|
|
static constexpr bool enable_error_condition_converting_constructor = //
|
|
constructors_enabled //
|
|
&& !std::is_same<std::decay_t<ErrorCondEnum>, basic_outcome>::value // not my type
|
|
&& base::template enable_error_condition_converting_constructor<ErrorCondEnum>;
|
|
// Predicate for the exception converting constructor to be available.
|
|
template <class T>
|
|
static constexpr bool enable_exception_converting_constructor = //
|
|
constructors_enabled //
|
|
&& !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type
|
|
&& base::template enable_exception_converting_constructor<T>;
|
|
// Predicate for the error + exception converting constructor to be available.
|
|
template <class T, class U>
|
|
static constexpr bool enable_error_exception_converting_constructor = //
|
|
constructors_enabled //
|
|
&& !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type
|
|
&& base::template enable_error_exception_converting_constructor<T, U>;
|
|
// Predicate for the converting constructor from a compatible input to be available.
|
|
template <class T, class U, class V, class W>
|
|
static constexpr bool enable_compatible_conversion = //
|
|
constructors_enabled //
|
|
&& !std::is_same<basic_outcome<T, U, V, W>, basic_outcome>::value // not my type
|
|
&& base::template enable_compatible_conversion<T, U, V, W>;
|
|
// Predicate for the converting constructor from a make_error_code() of the input to be available.
|
|
template <class T, class U, class V, class W>
|
|
static constexpr bool enable_make_error_code_compatible_conversion = //
|
|
constructors_enabled //
|
|
&& !std::is_same<basic_outcome<T, U, V, W>, basic_outcome>::value // not my type
|
|
&& base::template enable_make_error_code_compatible_conversion<T, U, V, W>;
|
|
// Predicate for the inplace construction of value to be available.
|
|
template <class... Args>
|
|
static constexpr bool enable_inplace_value_constructor = //
|
|
constructors_enabled //
|
|
&& (std::is_void<value_type>::value //
|
|
|| detail::is_constructible<value_type, Args...>);
|
|
// Predicate for the inplace construction of error to be available.
|
|
template <class... Args>
|
|
static constexpr bool enable_inplace_error_constructor = //
|
|
constructors_enabled //
|
|
&& (std::is_void<error_type>::value //
|
|
|| detail::is_constructible<error_type, Args...>);
|
|
// Predicate for the inplace construction of exception to be available.
|
|
template <class... Args>
|
|
static constexpr bool enable_inplace_exception_constructor = //
|
|
constructors_enabled //
|
|
&& (std::is_void<exception_type>::value //
|
|
|| detail::is_constructible<exception_type, Args...>);
|
|
// Predicate for the implicit converting inplace constructor to be available.
|
|
template <class... Args>
|
|
static constexpr bool enable_inplace_value_error_exception_constructor = //
|
|
constructors_enabled //
|
|
&&base::template enable_inplace_value_error_exception_constructor<Args...>;
|
|
template <class... Args>
|
|
using choose_inplace_value_error_exception_constructor = typename base::template choose_inplace_value_error_exception_constructor<Args...>;
|
|
};
|
|
public:
|
|
using value_type_if_enabled =
|
|
std::conditional_t<std::is_same<value_type, error_type>::value || std::is_same<value_type, exception_type>::value, disable_in_place_value_type, value_type>;
|
|
using error_type_if_enabled =
|
|
std::conditional_t<std::is_same<error_type, value_type>::value || std::is_same<error_type, exception_type>::value, disable_in_place_error_type, error_type>;
|
|
using exception_type_if_enabled = std::conditional_t<std::is_same<exception_type, value_type>::value || std::is_same<exception_type, error_type>::value,
|
|
disable_in_place_exception_type, exception_type>;
|
|
protected:
|
|
detail::devoid<exception_type> _ptr;
|
|
public:
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class Arg, class... Args)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED((!predicate::constructors_enabled && sizeof...(Args) >= 0)))
|
|
basic_outcome(Arg && /*unused*/, Args &&... /*unused*/) = delete; // NOLINT basic_outcome<> with any of the same type is NOT SUPPORTED, see docs!
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED((predicate::constructors_enabled && !predicate::implicit_constructors_enabled //
|
|
&& (detail::is_implicitly_constructible<value_type, T> || detail::is_implicitly_constructible<error_type, T> ||
|
|
detail::is_implicitly_constructible<exception_type, T>) )))
|
|
basic_outcome(T && /*unused*/, implicit_constructors_disabled_tag /*unused*/ = implicit_constructors_disabled_tag()) =
|
|
delete; // NOLINT Implicit constructors disabled, use explicit in_place_type<T>, success() or failure(). see docs!
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_value_converting_constructor<T>))
|
|
constexpr basic_outcome(T &&t, value_converting_constructor_tag /*unused*/ = value_converting_constructor_tag()) noexcept(
|
|
detail::is_nothrow_constructible<value_type, T>) // NOLINT
|
|
: base{in_place_type<typename base::_value_type>, static_cast<T &&>(t)}
|
|
, _ptr()
|
|
{
|
|
no_value_policy_type::on_outcome_construction(this, static_cast<T &&>(t));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_error_converting_constructor<T>))
|
|
constexpr basic_outcome(T &&t, error_converting_constructor_tag /*unused*/ = error_converting_constructor_tag()) noexcept(
|
|
detail::is_nothrow_constructible<error_type, T>) // NOLINT
|
|
: base{in_place_type<typename base::_error_type>, static_cast<T &&>(t)}
|
|
, _ptr()
|
|
{
|
|
no_value_policy_type::on_outcome_construction(this, static_cast<T &&>(t));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class ErrorCondEnum)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(error_type(make_error_code(ErrorCondEnum()))), //
|
|
OUTCOME_TPRED(predicate::template enable_error_condition_converting_constructor<ErrorCondEnum>))
|
|
constexpr basic_outcome(ErrorCondEnum &&t, error_condition_converting_constructor_tag /*unused*/ = error_condition_converting_constructor_tag()) noexcept(
|
|
noexcept(error_type(make_error_code(static_cast<ErrorCondEnum &&>(t))))) // NOLINT
|
|
: base{in_place_type<typename base::_error_type>, make_error_code(t)}
|
|
{
|
|
no_value_policy_type::on_outcome_construction(this, static_cast<ErrorCondEnum &&>(t));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_exception_converting_constructor<T>))
|
|
constexpr basic_outcome(T &&t, exception_converting_constructor_tag /*unused*/ = exception_converting_constructor_tag()) noexcept(
|
|
detail::is_nothrow_constructible<exception_type, T>) // NOLINT
|
|
: base()
|
|
, _ptr(static_cast<T &&>(t))
|
|
{
|
|
this->_state._status.set_have_exception(true);
|
|
no_value_policy_type::on_outcome_construction(this, static_cast<T &&>(t));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_error_exception_converting_constructor<T, U>))
|
|
constexpr basic_outcome(T &&a, U &&b, error_exception_converting_constructor_tag /*unused*/ = error_exception_converting_constructor_tag()) noexcept(
|
|
detail::is_nothrow_constructible<error_type, T> &&detail::is_nothrow_constructible<exception_type, U>) // NOLINT
|
|
: base{in_place_type<typename base::_error_type>, static_cast<T &&>(a)}
|
|
, _ptr(static_cast<U &&>(b))
|
|
{
|
|
this->_state._status.set_have_exception(true);
|
|
no_value_policy_type::on_outcome_construction(this, static_cast<T &&>(a), static_cast<U &&>(b));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(convert::value_or_error<basic_outcome, std::decay_t<T>>::enable_result_inputs || !concepts::basic_result<T>), //
|
|
OUTCOME_TPRED(convert::value_or_error<basic_outcome, std::decay_t<T>>::enable_outcome_inputs || !concepts::basic_outcome<T>), //
|
|
OUTCOME_TEXPR(convert::value_or_error<basic_outcome, std::decay_t<T>>{}(std::declval<T>())))
|
|
constexpr explicit basic_outcome(T &&o,
|
|
explicit_valueorerror_converting_constructor_tag /*unused*/ = explicit_valueorerror_converting_constructor_tag()) // NOLINT
|
|
: basic_outcome{convert::value_or_error<basic_outcome, std::decay_t<T>>{}(static_cast<T &&>(o))}
|
|
{
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V, class W)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V, W>))
|
|
constexpr explicit basic_outcome(
|
|
const basic_outcome<T, U, V, W> &o,
|
|
explicit_compatible_copy_conversion_tag /*unused*/ =
|
|
explicit_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U>
|
|
&&detail::is_nothrow_constructible<exception_type, V>)
|
|
: base{typename base::compatible_conversion_tag(), o}
|
|
, _ptr(o._ptr)
|
|
{
|
|
no_value_policy_type::on_outcome_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V, class W)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V, W>))
|
|
constexpr explicit basic_outcome(
|
|
basic_outcome<T, U, V, W> &&o,
|
|
explicit_compatible_move_conversion_tag /*unused*/ =
|
|
explicit_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U>
|
|
&&detail::is_nothrow_constructible<exception_type, V>)
|
|
: base{typename base::compatible_conversion_tag(), static_cast<basic_outcome<T, U, V, W> &&>(o)}
|
|
, _ptr(static_cast<typename basic_outcome<T, U, V, W>::exception_type &&>(o._ptr))
|
|
{
|
|
no_value_policy_type::on_outcome_move_construction(this, static_cast<basic_outcome<T, U, V, W> &&>(o));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_compatible_conversion<T, U, V>))
|
|
constexpr explicit basic_outcome(
|
|
const basic_result<T, U, V> &o,
|
|
explicit_compatible_copy_conversion_tag /*unused*/ =
|
|
explicit_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U>
|
|
&&detail::is_nothrow_constructible<exception_type>)
|
|
: base{typename base::compatible_conversion_tag(), o}
|
|
, _ptr()
|
|
{
|
|
no_value_policy_type::on_outcome_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_compatible_conversion<T, U, V>))
|
|
constexpr explicit basic_outcome(
|
|
basic_result<T, U, V> &&o,
|
|
explicit_compatible_move_conversion_tag /*unused*/ =
|
|
explicit_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U>
|
|
&&detail::is_nothrow_constructible<exception_type>)
|
|
: base{typename base::compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
|
|
, _ptr()
|
|
{
|
|
no_value_policy_type::on_outcome_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_make_error_code_compatible_conversion<T, U, V>))
|
|
constexpr explicit basic_outcome(const basic_result<T, U, V> &o,
|
|
explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ =
|
|
explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T>
|
|
&&noexcept(make_error_code(std::declval<U>())) &&
|
|
detail::is_nothrow_constructible<exception_type>)
|
|
: base{typename base::make_error_code_compatible_conversion_tag(), o}
|
|
, _ptr()
|
|
{
|
|
no_value_policy_type::on_outcome_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_make_error_code_compatible_conversion<T, U, V>))
|
|
constexpr explicit basic_outcome(basic_result<T, U, V> &&o,
|
|
explicit_make_error_code_compatible_move_conversion_tag /*unused*/ =
|
|
explicit_make_error_code_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T>
|
|
&&noexcept(make_error_code(std::declval<U>())) &&
|
|
detail::is_nothrow_constructible<exception_type>)
|
|
: base{typename base::make_error_code_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
|
|
, _ptr()
|
|
{
|
|
no_value_policy_type::on_outcome_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class... Args)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<Args...>))
|
|
constexpr explicit basic_outcome(in_place_type_t<value_type_if_enabled> _, Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, Args...>)
|
|
: base{_, static_cast<Args &&>(args)...}
|
|
, _ptr()
|
|
{
|
|
no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<value_type>, static_cast<Args &&>(args)...);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class U, class... Args)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<std::initializer_list<U>, Args...>))
|
|
constexpr explicit basic_outcome(in_place_type_t<value_type_if_enabled> _, std::initializer_list<U> il,
|
|
Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, std::initializer_list<U>, Args...>)
|
|
: base{_, il, static_cast<Args &&>(args)...}
|
|
, _ptr()
|
|
{
|
|
no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<value_type>, il, static_cast<Args &&>(args)...);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class... Args)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<Args...>))
|
|
constexpr explicit basic_outcome(in_place_type_t<error_type_if_enabled> _, Args &&... args) noexcept(detail::is_nothrow_constructible<error_type, Args...>)
|
|
: base{_, static_cast<Args &&>(args)...}
|
|
, _ptr()
|
|
{
|
|
no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<error_type>, static_cast<Args &&>(args)...);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class U, class... Args)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<std::initializer_list<U>, Args...>))
|
|
constexpr explicit basic_outcome(in_place_type_t<error_type_if_enabled> _, std::initializer_list<U> il,
|
|
Args &&... args) noexcept(detail::is_nothrow_constructible<error_type, std::initializer_list<U>, Args...>)
|
|
: base{_, il, static_cast<Args &&>(args)...}
|
|
, _ptr()
|
|
{
|
|
no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<error_type>, il, static_cast<Args &&>(args)...);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class... Args)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_inplace_exception_constructor<Args...>))
|
|
constexpr explicit basic_outcome(in_place_type_t<exception_type_if_enabled> /*unused*/,
|
|
Args &&... args) noexcept(detail::is_nothrow_constructible<exception_type, Args...>)
|
|
: base()
|
|
, _ptr(static_cast<Args &&>(args)...)
|
|
{
|
|
this->_state._status.set_have_exception(true);
|
|
no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<exception_type>, static_cast<Args &&>(args)...);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class U, class... Args)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_inplace_exception_constructor<std::initializer_list<U>, Args...>))
|
|
constexpr explicit basic_outcome(in_place_type_t<exception_type_if_enabled> /*unused*/, std::initializer_list<U> il,
|
|
Args &&... args) noexcept(detail::is_nothrow_constructible<exception_type, std::initializer_list<U>, Args...>)
|
|
: base()
|
|
, _ptr(il, static_cast<Args &&>(args)...)
|
|
{
|
|
this->_state._status.set_have_exception(true);
|
|
no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<exception_type>, il, static_cast<Args &&>(args)...);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class A1, class A2, class... Args)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(predicate::template enable_inplace_value_error_exception_constructor<A1, A2, Args...>))
|
|
constexpr basic_outcome(A1 &&a1, A2 &&a2, Args &&... args) noexcept(
|
|
noexcept(typename predicate::template choose_inplace_value_error_exception_constructor<A1, A2, Args...>(std::declval<A1>(), std::declval<A2>(),
|
|
std::declval<Args>()...)))
|
|
: basic_outcome(in_place_type<typename predicate::template choose_inplace_value_error_exception_constructor<A1, A2, Args...>>, static_cast<A1 &&>(a1),
|
|
static_cast<A2 &&>(a2), static_cast<Args &&>(args)...)
|
|
{
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
constexpr basic_outcome(const success_type<void> &o) noexcept(std::is_nothrow_default_constructible<value_type>::value) // NOLINT
|
|
: base{in_place_type<typename base::_value_type>}
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_outcome_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void, void>))
|
|
constexpr basic_outcome(const success_type<T> &o) noexcept(detail::is_nothrow_constructible<value_type, T>) // NOLINT
|
|
: base{in_place_type<typename base::_value_type>, detail::extract_value_from_success<value_type>(o)}
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_outcome_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void, void>))
|
|
constexpr basic_outcome(success_type<T> &&o) noexcept(detail::is_nothrow_constructible<value_type, T>) // NOLINT
|
|
: base{in_place_type<typename base::_value_type>, detail::extract_value_from_success<value_type>(static_cast<success_type<T> &&>(o))}
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_outcome_move_construction(this, static_cast<success_type<T> &&>(o));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, T, void, void>))
|
|
constexpr basic_outcome(const failure_type<T> &o,
|
|
error_failure_tag /*unused*/ = error_failure_tag()) noexcept(detail::is_nothrow_constructible<error_type, T>) // NOLINT
|
|
: base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(o)}
|
|
, _ptr()
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_outcome_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, void, T, void>))
|
|
constexpr basic_outcome(const failure_type<T> &o,
|
|
exception_failure_tag /*unused*/ = exception_failure_tag()) noexcept(detail::is_nothrow_constructible<exception_type, T>) // NOLINT
|
|
: base()
|
|
, _ptr(detail::extract_exception_from_failure<exception_type>(o))
|
|
{
|
|
this->_state._status.set_have_exception(true);
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_outcome_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_make_error_code_compatible_conversion<void, T, void, void>))
|
|
constexpr basic_outcome(const failure_type<T> &o,
|
|
explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ =
|
|
explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT
|
|
: base{in_place_type<typename base::_error_type>, make_error_code(detail::extract_error_from_failure<error_type>(o))}
|
|
, _ptr()
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_outcome_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!std::is_void<U>::value && predicate::template enable_compatible_conversion<void, T, U, void>))
|
|
constexpr basic_outcome(const failure_type<T, U> &o, explicit_compatible_copy_conversion_tag /*unused*/ = explicit_compatible_copy_conversion_tag()) noexcept(
|
|
detail::is_nothrow_constructible<error_type, T> &&detail::is_nothrow_constructible<exception_type, U>) // NOLINT
|
|
: base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(o)}
|
|
, _ptr(detail::extract_exception_from_failure<exception_type>(o))
|
|
{
|
|
if(!o.has_error())
|
|
{
|
|
this->_state._status.set_have_error(false);
|
|
}
|
|
if(o.has_exception())
|
|
{
|
|
this->_state._status.set_have_exception(true);
|
|
}
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_outcome_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, T, void, void>))
|
|
constexpr basic_outcome(failure_type<T> &&o,
|
|
error_failure_tag /*unused*/ = error_failure_tag()) noexcept(detail::is_nothrow_constructible<error_type, T>) // NOLINT
|
|
: base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o))}
|
|
, _ptr()
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_outcome_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, void, T, void>))
|
|
constexpr basic_outcome(failure_type<T> &&o,
|
|
exception_failure_tag /*unused*/ = exception_failure_tag()) noexcept(detail::is_nothrow_constructible<exception_type, T>) // NOLINT
|
|
: base()
|
|
, _ptr(detail::extract_exception_from_failure<exception_type>(static_cast<failure_type<T> &&>(o)))
|
|
{
|
|
this->_state._status.set_have_exception(true);
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_outcome_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_make_error_code_compatible_conversion<void, T, void, void>))
|
|
constexpr basic_outcome(failure_type<T> &&o,
|
|
explicit_make_error_code_compatible_move_conversion_tag /*unused*/ =
|
|
explicit_make_error_code_compatible_move_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT
|
|
: base{in_place_type<typename base::_error_type>, make_error_code(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))}
|
|
, _ptr()
|
|
{
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_outcome_copy_construction(this, o);
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!std::is_void<U>::value && predicate::template enable_compatible_conversion<void, T, U, void>))
|
|
constexpr basic_outcome(failure_type<T, U> &&o, explicit_compatible_move_conversion_tag /*unused*/ = explicit_compatible_move_conversion_tag()) noexcept(
|
|
detail::is_nothrow_constructible<error_type, T> &&detail::is_nothrow_constructible<exception_type, U>) // NOLINT
|
|
: base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T, U> &&>(o))}
|
|
, _ptr(detail::extract_exception_from_failure<exception_type>(static_cast<failure_type<T, U> &&>(o)))
|
|
{
|
|
if(!o.has_error())
|
|
{
|
|
this->_state._status.set_have_error(false);
|
|
}
|
|
if(o.has_exception())
|
|
{
|
|
this->_state._status.set_have_exception(true);
|
|
}
|
|
hooks::set_spare_storage(this, o.spare_storage());
|
|
no_value_policy_type::on_outcome_move_construction(this, static_cast<failure_type<T, U> &&>(o));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
using base::operator==;
|
|
using base::operator!=;
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V, class W)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<detail::devoid<value_type>>() == std::declval<detail::devoid<T>>()), //
|
|
OUTCOME_TEXPR(std::declval<detail::devoid<error_type>>() == std::declval<detail::devoid<U>>()), //
|
|
OUTCOME_TEXPR(std::declval<detail::devoid<exception_type>>() == std::declval<detail::devoid<V>>()))
|
|
constexpr bool operator==(const basic_outcome<T, U, V, W> &o) const noexcept( //
|
|
noexcept(std::declval<detail::devoid<value_type>>() == std::declval<detail::devoid<T>>()) //
|
|
&&noexcept(std::declval<detail::devoid<error_type>>() == std::declval<detail::devoid<U>>()) //
|
|
&&noexcept(std::declval<detail::devoid<exception_type>>() == std::declval<detail::devoid<V>>()))
|
|
{
|
|
if(this->_state._status.have_value() && o._state._status.have_value())
|
|
{
|
|
return this->_state._value == o._state._value; // NOLINT
|
|
}
|
|
if(this->_state._status.have_error() && o._state._status.have_error() //
|
|
&& this->_state._status.have_exception() && o._state._status.have_exception())
|
|
{
|
|
return this->_state._error == o._state._error && this->_ptr == o._ptr;
|
|
}
|
|
if(this->_state._status.have_error() && o._state._status.have_error())
|
|
{
|
|
return this->_state._error == o._state._error;
|
|
}
|
|
if(this->_state._status.have_exception() && o._state._status.have_exception())
|
|
{
|
|
return this->_ptr == o._ptr;
|
|
}
|
|
return false;
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<error_type>() == std::declval<T>()), //
|
|
OUTCOME_TEXPR(std::declval<exception_type>() == std::declval<U>()))
|
|
constexpr bool operator==(const failure_type<T, U> &o) const noexcept( //
|
|
noexcept(std::declval<error_type>() == std::declval<T>()) &&noexcept(std::declval<exception_type>() == std::declval<U>()))
|
|
{
|
|
if(this->_state._status.have_error() && o._state._status.have_error() //
|
|
&& this->_state._status.have_exception() && o._state._status.have_exception())
|
|
{
|
|
return this->_state._error == o.error() && this->_ptr == o.exception();
|
|
}
|
|
if(this->_state._status.have_error() && o._state._status.have_error())
|
|
{
|
|
return this->_state._error == o.error();
|
|
}
|
|
if(this->_state._status.have_exception() && o._state._status.have_exception())
|
|
{
|
|
return this->_ptr == o.exception();
|
|
}
|
|
return false;
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V, class W)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<detail::devoid<value_type>>() != std::declval<detail::devoid<T>>()), //
|
|
OUTCOME_TEXPR(std::declval<detail::devoid<error_type>>() != std::declval<detail::devoid<U>>()), //
|
|
OUTCOME_TEXPR(std::declval<detail::devoid<exception_type>>() != std::declval<detail::devoid<V>>()))
|
|
constexpr bool operator!=(const basic_outcome<T, U, V, W> &o) const noexcept( //
|
|
noexcept(std::declval<detail::devoid<value_type>>() != std::declval<detail::devoid<T>>()) //
|
|
&&noexcept(std::declval<detail::devoid<error_type>>() != std::declval<detail::devoid<U>>()) //
|
|
&&noexcept(std::declval<detail::devoid<exception_type>>() != std::declval<detail::devoid<V>>()))
|
|
{
|
|
if(this->_state._status.have_value() && o._state._status.have_value())
|
|
{
|
|
return this->_state._value != o._state._value; // NOLINT
|
|
}
|
|
if(this->_state._status.have_error() && o._state._status.have_error() //
|
|
&& this->_state._status.have_exception() && o._state._status.have_exception())
|
|
{
|
|
return this->_state._error != o._state._error || this->_ptr != o._ptr;
|
|
}
|
|
if(this->_state._status.have_error() && o._state._status.have_error())
|
|
{
|
|
return this->_state._error != o._state._error;
|
|
}
|
|
if(this->_state._status.have_exception() && o._state._status.have_exception())
|
|
{
|
|
return this->_ptr != o._ptr;
|
|
}
|
|
return true;
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<error_type>() != std::declval<T>()), //
|
|
OUTCOME_TEXPR(std::declval<exception_type>() != std::declval<U>()))
|
|
constexpr bool operator!=(const failure_type<T, U> &o) const noexcept( //
|
|
noexcept(std::declval<error_type>() == std::declval<T>()) &&noexcept(std::declval<exception_type>() == std::declval<U>()))
|
|
{
|
|
if(this->_state._status.have_error() && o._state._status.have_error() //
|
|
&& this->_state._status.have_exception() && o._state._status.have_exception())
|
|
{
|
|
return this->_state._error != o.error() || this->_ptr != o.exception();
|
|
}
|
|
if(this->_state._status.have_error() && o._state._status.have_error())
|
|
{
|
|
return this->_state._error != o.error();
|
|
}
|
|
if(this->_state._status.have_exception() && o._state._status.have_exception())
|
|
{
|
|
return this->_ptr != o.exception();
|
|
}
|
|
return true;
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
constexpr void swap(basic_outcome &o) noexcept((std::is_void<value_type>::value || detail::is_nothrow_swappable<value_type>::value) //
|
|
&& (std::is_void<error_type>::value || detail::is_nothrow_swappable<error_type>::value) //
|
|
&& (std::is_void<exception_type>::value || detail::is_nothrow_swappable<exception_type>::value))
|
|
{
|
|
#ifdef __cpp_exceptions
|
|
constexpr bool value_throws = !std::is_void<value_type>::value && !detail::is_nothrow_swappable<value_type>::value;
|
|
constexpr bool error_throws = !std::is_void<error_type>::value && !detail::is_nothrow_swappable<error_type>::value;
|
|
constexpr bool exception_throws = !std::is_void<exception_type>::value && !detail::is_nothrow_swappable<exception_type>::value;
|
|
#ifdef _MSC_VER
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 4127) // conditional expression is constant
|
|
#endif
|
|
if(!exception_throws && !value_throws && !error_throws)
|
|
{
|
|
// Simples
|
|
this->_state.swap(o._state);
|
|
using std::swap;
|
|
swap(this->_ptr, o._ptr);
|
|
return;
|
|
}
|
|
struct _
|
|
{
|
|
basic_outcome &a, &b;
|
|
bool exceptioned{false};
|
|
bool all_good{false};
|
|
~_()
|
|
{
|
|
if(!all_good)
|
|
{
|
|
// We lost one of the values
|
|
a._state._status.set_have_lost_consistency(true);
|
|
b._state._status.set_have_lost_consistency(true);
|
|
return;
|
|
}
|
|
if(exceptioned)
|
|
{
|
|
// The value + error swap threw an exception. Try to swap back _ptr
|
|
try
|
|
{
|
|
strong_swap(all_good, a._ptr, b._ptr);
|
|
}
|
|
catch(...)
|
|
{
|
|
// We lost one of the values
|
|
a._state._status.set_have_lost_consistency(true);
|
|
b._state._status.set_have_lost_consistency(true);
|
|
// throw away second exception
|
|
}
|
|
// Prevent has_value() == has_error() or has_value() == has_exception()
|
|
auto check = [](basic_outcome *t) {
|
|
if(t->has_value() && (t->has_error() || t->has_exception()))
|
|
{
|
|
t->_state._status.set_have_error(false).set_have_exception(false);
|
|
t->_state._status.set_have_lost_consistency(true);
|
|
}
|
|
if(!t->has_value() && !(t->has_error() || t->has_exception()))
|
|
{
|
|
// Choose error, for no particular reason
|
|
t->_state._status.set_have_error(true).set_have_lost_consistency(true);
|
|
}
|
|
};
|
|
check(&a);
|
|
check(&b);
|
|
}
|
|
}
|
|
} _{*this, o};
|
|
strong_swap(_.all_good, this->_ptr, o._ptr);
|
|
_.exceptioned = true;
|
|
this->_state.swap(o._state);
|
|
_.exceptioned = false;
|
|
#ifdef _MSC_VER
|
|
#pragma warning(pop)
|
|
#endif
|
|
#else
|
|
this->_state.swap(o._state);
|
|
using std::swap;
|
|
swap(this->_ptr, o._ptr);
|
|
#endif
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
failure_type<error_type, exception_type> as_failure() const &
|
|
{
|
|
if(this->has_error() && this->has_exception())
|
|
{
|
|
return failure_type<error_type, exception_type>(this->assume_error(), this->assume_exception(), hooks::spare_storage(this));
|
|
}
|
|
if(this->has_exception())
|
|
{
|
|
return failure_type<error_type, exception_type>(in_place_type<exception_type>, this->assume_exception(), hooks::spare_storage(this));
|
|
}
|
|
return failure_type<error_type, exception_type>(in_place_type<error_type>, this->assume_error(), hooks::spare_storage(this));
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
failure_type<error_type, exception_type> as_failure() &&
|
|
{
|
|
this->_state._status.set_have_moved_from(true);
|
|
if(this->has_error() && this->has_exception())
|
|
{
|
|
return failure_type<error_type, exception_type>(static_cast<S &&>(this->assume_error()), static_cast<P &&>(this->assume_exception()),
|
|
hooks::spare_storage(this));
|
|
}
|
|
if(this->has_exception())
|
|
{
|
|
return failure_type<error_type, exception_type>(in_place_type<exception_type>, static_cast<P &&>(this->assume_exception()), hooks::spare_storage(this));
|
|
}
|
|
return failure_type<error_type, exception_type>(in_place_type<error_type>, static_cast<S &&>(this->assume_error()), hooks::spare_storage(this));
|
|
}
|
|
#ifdef __APPLE__
|
|
failure_type<error_type, exception_type> _xcode_workaround_as_failure() &&;
|
|
#endif
|
|
};
|
|
// C++ 20 operator== rewriting should take care of this for us, indeed
|
|
// if we don't disable it, we cause Concept recursion to infinity!
|
|
#if __cplusplus < 202000 && !_HAS_CXX20
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V, //
|
|
class R, class S, class P, class N)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<basic_outcome<R, S, P, N>>() == std::declval<basic_result<T, U, V>>()))
|
|
constexpr inline bool operator==(const basic_result<T, U, V> &a, const basic_outcome<R, S, P, N> &b) noexcept( //
|
|
noexcept(std::declval<basic_outcome<R, S, P, N>>() == std::declval<basic_result<T, U, V>>()))
|
|
{
|
|
return b == a;
|
|
}
|
|
#endif
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T, class U, class V, //
|
|
class R, class S, class P, class N)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<basic_outcome<R, S, P, N>>() != std::declval<basic_result<T, U, V>>()))
|
|
constexpr inline bool operator!=(const basic_result<T, U, V> &a, const basic_outcome<R, S, P, N> &b) noexcept( //
|
|
noexcept(std::declval<basic_outcome<R, S, P, N>>() != std::declval<basic_result<T, U, V>>()))
|
|
{
|
|
return b != a;
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class R, class S, class P, class N> inline void swap(basic_outcome<R, S, P, N> &a, basic_outcome<R, S, P, N> &b) noexcept(noexcept(a.swap(b)))
|
|
{
|
|
a.swap(b);
|
|
}
|
|
namespace hooks
|
|
{
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class R, class S, class P, class NoValuePolicy, class U>
|
|
constexpr inline void override_outcome_exception(basic_outcome<R, S, P, NoValuePolicy> *o, U &&v) noexcept
|
|
{
|
|
o->_ptr = static_cast<U &&>(v); // NOLINT
|
|
o->_state._status.set_have_exception(true);
|
|
}
|
|
} // namespace hooks
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#ifdef __clang__
|
|
#pragma clang diagnostic pop
|
|
#endif
|
|
/* Exception observers for outcome type
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_BASIC_OUTCOME_EXCEPTION_OBSERVERS_IMPL_HPP
|
|
#define OUTCOME_BASIC_OUTCOME_EXCEPTION_OBSERVERS_IMPL_HPP
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace policy
|
|
{
|
|
template <class R, class S, class P, class NoValuePolicy, class Impl> inline constexpr auto &&base::_exception(Impl &&self) noexcept
|
|
{
|
|
// Impl will be some internal implementation class which has no knowledge of the _ptr stored
|
|
// beneath it. So statically cast, preserving rvalue and constness, to the derived class.
|
|
using Outcome = OUTCOME_V2_NAMESPACE::detail::rebind_type<basic_outcome<R, S, P, NoValuePolicy>, decltype(self)>;
|
|
#if defined(_MSC_VER) && _MSC_VER < 1920
|
|
// VS2017 tries a copy construction in the correct implementation despite that Outcome is always a rvalue or lvalue ref! :(
|
|
basic_outcome<R, S, P, NoValuePolicy> &_self = (basic_outcome<R, S, P, NoValuePolicy> &) (self); // NOLINT
|
|
#else
|
|
Outcome _self = static_cast<Outcome>(self); // NOLINT
|
|
#endif
|
|
return static_cast<Outcome>(_self)._ptr;
|
|
}
|
|
} // namespace policy
|
|
namespace detail
|
|
{
|
|
template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::assume_exception() & noexcept
|
|
{
|
|
NoValuePolicy::narrow_exception_check(*this);
|
|
return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(*this);
|
|
}
|
|
template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr const typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::assume_exception() const &noexcept
|
|
{
|
|
NoValuePolicy::narrow_exception_check(*this);
|
|
return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(*this);
|
|
}
|
|
template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &&basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::assume_exception() && noexcept
|
|
{
|
|
NoValuePolicy::narrow_exception_check(std::move(*this));
|
|
return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(std::move(*this));
|
|
}
|
|
template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr const typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &&basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::assume_exception() const &&noexcept
|
|
{
|
|
NoValuePolicy::narrow_exception_check(std::move(*this));
|
|
return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(std::move(*this));
|
|
}
|
|
template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception() &
|
|
{
|
|
NoValuePolicy::wide_exception_check(*this);
|
|
return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(*this);
|
|
}
|
|
template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr const typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception() const &
|
|
{
|
|
NoValuePolicy::wide_exception_check(*this);
|
|
return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(*this);
|
|
}
|
|
template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &&basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception() &&
|
|
{
|
|
NoValuePolicy::wide_exception_check(std::move(*this));
|
|
return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(std::move(*this));
|
|
}
|
|
template <class Base, class R, class S, class P, class NoValuePolicy> inline constexpr const typename basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception_type &&basic_outcome_exception_observers<Base, R, S, P, NoValuePolicy>::exception() const &&
|
|
{
|
|
NoValuePolicy::wide_exception_check(std::move(*this));
|
|
return NoValuePolicy::template _exception<R, S, P, NoValuePolicy>(std::move(*this));
|
|
}
|
|
} // namespace detail
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
#if !defined(NDEBUG)
|
|
OUTCOME_V2_NAMESPACE_BEGIN
|
|
// Check is trivial in all ways except default constructibility and standard layout
|
|
// static_assert(std::is_trivial<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivial!");
|
|
// static_assert(std::is_trivially_default_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially default
|
|
// constructible!");
|
|
static_assert(std::is_trivially_copyable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially copyable!");
|
|
static_assert(std::is_trivially_assignable<basic_outcome<int, long, double, policy::all_narrow>, basic_outcome<int, long, double, policy::all_narrow>>::value,
|
|
"outcome<int> is not trivially assignable!");
|
|
static_assert(std::is_trivially_destructible<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially destructible!");
|
|
static_assert(std::is_trivially_copy_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value,
|
|
"outcome<int> is not trivially copy constructible!");
|
|
static_assert(std::is_trivially_move_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value,
|
|
"outcome<int> is not trivially move constructible!");
|
|
static_assert(std::is_trivially_copy_assignable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially copy assignable!");
|
|
static_assert(std::is_trivially_move_assignable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially move assignable!");
|
|
// Can't be standard layout as non-static member data is defined in more than one inherited class
|
|
// static_assert(std::is_standard_layout<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not a standard layout type!");
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
#endif
|
|
#ifndef STD_BASIC_OUTCOME_FAILURE_EXCEPTION_FROM_ERROR
|
|
#define STD_BASIC_OUTCOME_FAILURE_EXCEPTION_FROM_ERROR
|
|
namespace std // NOLINT
|
|
{
|
|
inline exception_ptr basic_outcome_failure_exception_from_error(const error_code &ec) { return make_exception_ptr(system_error(ec)); }
|
|
} // namespace std
|
|
#endif
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class R, class S = std::error_code, class P = std::exception_ptr, class NoValuePolicy = policy::default_policy<R, S, P>> //
|
|
using std_outcome = basic_outcome<R, S, P, NoValuePolicy>;
|
|
OUTCOME_V2_NAMESPACE_END
|
|
/* Policies for result and outcome
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (12 commits)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_POLICY_OUTCOME_ERROR_CODE_THROW_AS_SYSTEM_ERROR_HPP
|
|
#define OUTCOME_POLICY_OUTCOME_ERROR_CODE_THROW_AS_SYSTEM_ERROR_HPP
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace policy
|
|
{
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition error_code_throw_as_system_error. Potential doc page: NOT FOUND
|
|
*/
|
|
template <class T, class EC, class E> struct error_code_throw_as_system_error : base
|
|
{
|
|
template <class Impl> static constexpr void wide_value_check(Impl &&self)
|
|
{
|
|
if(!base::_has_value(std::forward<Impl>(self)))
|
|
{
|
|
if(base::_has_exception(std::forward<Impl>(self)))
|
|
{
|
|
detail::_rethrow_exception<trait::is_exception_ptr_available<E>::value>{base::_exception<T, EC, E, error_code_throw_as_system_error>(std::forward<Impl>(self))}; // NOLINT
|
|
}
|
|
if(base::_has_error(std::forward<Impl>(self)))
|
|
{
|
|
// ADL discovered
|
|
outcome_throw_as_system_error_with_payload(base::_error(std::forward<Impl>(self)));
|
|
}
|
|
OUTCOME_THROW_EXCEPTION(bad_outcome_access("no value")); // NOLINT
|
|
}
|
|
}
|
|
template <class Impl> static constexpr void wide_error_check(Impl &&self)
|
|
{
|
|
if(!base::_has_error(std::forward<Impl>(self)))
|
|
{
|
|
OUTCOME_THROW_EXCEPTION(bad_outcome_access("no error")); // NOLINT
|
|
}
|
|
}
|
|
template <class Impl> static constexpr void wide_exception_check(Impl &&self)
|
|
{
|
|
if(!base::_has_exception(std::forward<Impl>(self)))
|
|
{
|
|
OUTCOME_THROW_EXCEPTION(bad_outcome_access("no exception")); // NOLINT
|
|
}
|
|
}
|
|
};
|
|
} // namespace policy
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* Policies for result and outcome
|
|
(C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (10 commits)
|
|
File Created: Oct 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_POLICY_OUTCOME_EXCEPTION_PTR_RETHROW_HPP
|
|
#define OUTCOME_POLICY_OUTCOME_EXCEPTION_PTR_RETHROW_HPP
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
namespace policy
|
|
{
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
type definition exception_ptr_rethrow. Potential doc page: NOT FOUND
|
|
*/
|
|
template <class T, class EC, class E> struct exception_ptr_rethrow : base
|
|
{
|
|
template <class Impl> static constexpr void wide_value_check(Impl &&self)
|
|
{
|
|
if(!base::_has_value(std::forward<Impl>(self)))
|
|
{
|
|
if(base::_has_exception(std::forward<Impl>(self)))
|
|
{
|
|
detail::_rethrow_exception<trait::is_exception_ptr_available<E>::value>{base::_exception<T, EC, E, exception_ptr_rethrow>(std::forward<Impl>(self))};
|
|
}
|
|
if(base::_has_error(std::forward<Impl>(self)))
|
|
{
|
|
detail::_rethrow_exception<trait::is_exception_ptr_available<EC>::value>{base::_error(std::forward<Impl>(self))};
|
|
}
|
|
OUTCOME_THROW_EXCEPTION(bad_outcome_access("no value")); // NOLINT
|
|
}
|
|
}
|
|
template <class Impl> static constexpr void wide_error_check(Impl &&self)
|
|
{
|
|
if(!base::_has_error(std::forward<Impl>(self)))
|
|
{
|
|
OUTCOME_THROW_EXCEPTION(bad_outcome_access("no error")); // NOLINT
|
|
}
|
|
}
|
|
template <class Impl> static constexpr void wide_exception_check(Impl &&self)
|
|
{
|
|
if(!base::_has_exception(std::forward<Impl>(self)))
|
|
{
|
|
OUTCOME_THROW_EXCEPTION(bad_outcome_access("no exception")); // NOLINT
|
|
}
|
|
}
|
|
};
|
|
} // namespace policy
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
#endif
|
|
OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class R, class S = std::error_code, class P = std::exception_ptr, class NoValuePolicy = policy::default_policy<R, S, P>> //
|
|
using outcome = std_outcome<R, S, P, NoValuePolicy>;
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
#include <iostream>
|
|
#include <sstream>
|
|
OUTCOME_V2_NAMESPACE_BEGIN
|
|
namespace detail
|
|
{
|
|
template <class T> typename std::add_lvalue_reference<T>::type lvalueref() noexcept;
|
|
template <template <class, class> class ValueStorage, class T, class E> inline std::ostream &value_storage_out(std::ostream &s, const ValueStorage<T, E> &v)
|
|
{
|
|
s << static_cast<uint16_t>(v._status.status_value) << " " << v._status.spare_storage_value << " ";
|
|
if(v._status.have_value())
|
|
{
|
|
s << v._value; // NOLINT
|
|
}
|
|
if(v._status.have_error())
|
|
{
|
|
s << v._error; // NOLINT
|
|
}
|
|
return s;
|
|
}
|
|
template <template <class, class> class ValueStorage, class E> inline std::ostream &value_storage_out(std::ostream &s, const ValueStorage<void, E> &v)
|
|
{
|
|
s << static_cast<uint16_t>(v._status.status_value) << " " << v._status.spare_storage_value << " ";
|
|
if(v._status.have_error())
|
|
{
|
|
s << v._error; // NOLINT
|
|
}
|
|
return s;
|
|
}
|
|
template <template <class, class> class ValueStorage, class T> inline std::ostream &value_storage_out(std::ostream &s, const ValueStorage<T, void> &v)
|
|
{
|
|
s << static_cast<uint16_t>(v._status.status_value) << " " << v._status.spare_storage_value << " ";
|
|
if(v._status.have_value())
|
|
{
|
|
s << v._value; // NOLINT
|
|
}
|
|
return s;
|
|
}
|
|
template <class T, class E> inline std::ostream &operator<<(std::ostream &s, const value_storage_trivial<T, E> &v) { return value_storage_out(s, v); }
|
|
template <class T, class E> inline std::ostream &operator<<(std::ostream &s, const value_storage_nontrivial<T, E> &v) { return value_storage_out(s, v); }
|
|
template <template <class, class> class ValueStorage, class T, class E> inline std::istream &value_storage_in(std::istream &s, ValueStorage<T, E> &v)
|
|
{
|
|
using type = ValueStorage<T, E>;
|
|
v.~type();
|
|
new(&v) type;
|
|
uint16_t x, y;
|
|
s >> x >> y;
|
|
v._status.status_value = static_cast<detail::status>(x);
|
|
v._status.spare_storage_value = y;
|
|
if(v._status.have_value())
|
|
{
|
|
new(&v._value) decltype(v._value)(); // NOLINT
|
|
s >> v._value; // NOLINT
|
|
}
|
|
if(v._status.have_error())
|
|
{
|
|
new(&v._error) decltype(v._error)(); // NOLINT
|
|
s >> v._error; // NOLINT
|
|
}
|
|
return s;
|
|
}
|
|
template <template <class, class> class ValueStorage, class E> inline std::istream &value_storage_in(std::istream &s, ValueStorage<void, E> &v)
|
|
{
|
|
using type = ValueStorage<void, E>;
|
|
v.~type();
|
|
new(&v) type;
|
|
uint16_t x, y;
|
|
s >> x >> y;
|
|
v._status.status_value = static_cast<detail::status>(x);
|
|
v._status.spare_storage_value = y;
|
|
if(v._status.have_error())
|
|
{
|
|
new(&v._error) decltype(v._error)(); // NOLINT
|
|
s >> v._error; // NOLINT
|
|
}
|
|
return s;
|
|
}
|
|
template <template <class, class> class ValueStorage, class T> inline std::istream &value_storage_in(std::istream &s, ValueStorage<T, void> &v)
|
|
{
|
|
using type = ValueStorage<T, void>;
|
|
v.~type();
|
|
new(&v) type;
|
|
uint16_t x, y;
|
|
s >> x >> y;
|
|
v._status.status_value = static_cast<detail::status>(x);
|
|
v._status.spare_storage_value = y;
|
|
if(v._status.have_value())
|
|
{
|
|
new(&v._value) decltype(v._value)(); // NOLINT
|
|
s >> v._value; // NOLINT
|
|
}
|
|
return s;
|
|
}
|
|
template <class T, class E> inline std::istream &operator>>(std::istream &s, value_storage_trivial<T, E> &v) { return value_storage_in(s, v); }
|
|
template <class T, class E> inline std::istream &operator>>(std::istream &s, value_storage_nontrivial<T, E> &v) { return value_storage_in(s, v); }
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!std::is_constructible<std::error_code, T>::value))
|
|
inline std::string safe_message(T && /*unused*/) { return {}; }
|
|
inline std::string safe_message(const std::error_code &ec) { return " (" + ec.message() + ")"; }
|
|
} // namespace detail
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class R, class S, class P)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(detail::lvalueref<std::istream>() >> detail::lvalueref<R>()), OUTCOME_TEXPR(detail::lvalueref<std::istream>() >> detail::lvalueref<S>()))
|
|
inline std::istream &operator>>(std::istream &s, basic_result<R, S, P> &v)
|
|
{
|
|
s >> v._iostreams_state();
|
|
if(v.has_error())
|
|
{
|
|
s >> v.assume_error();
|
|
}
|
|
return s;
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class R, class S, class P)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(detail::lvalueref<std::ostream>() << detail::lvalueref<R>()), OUTCOME_TEXPR(detail::lvalueref<std::ostream>() << detail::lvalueref<S>()))
|
|
inline std::ostream &operator<<(std::ostream &s, const basic_result<R, S, P> &v)
|
|
{
|
|
s << v._iostreams_state();
|
|
if(v.has_error())
|
|
{
|
|
s << v.assume_error();
|
|
}
|
|
return s;
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class R, class S, class P> inline std::string print(const basic_result<R, S, P> &v)
|
|
{
|
|
std::stringstream s;
|
|
if(v.has_value())
|
|
{
|
|
s << v.value();
|
|
}
|
|
if(v.has_error())
|
|
{
|
|
s << v.error() << detail::safe_message(v.error());
|
|
}
|
|
return s.str();
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class S, class P> inline std::string print(const basic_result<void, S, P> &v)
|
|
{
|
|
std::stringstream s;
|
|
if(v.has_value())
|
|
{
|
|
s << "(+void)";
|
|
}
|
|
if(v.has_error())
|
|
{
|
|
s << v.error() << detail::safe_message(v.error());
|
|
}
|
|
return s.str();
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class R, class P> inline std::string print(const basic_result<R, void, P> &v)
|
|
{
|
|
std::stringstream s;
|
|
if(v.has_value())
|
|
{
|
|
s << v.value();
|
|
}
|
|
if(v.has_error())
|
|
{
|
|
s << "(-void)";
|
|
}
|
|
return s.str();
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class P> inline std::string print(const basic_result<void, void, P> &v)
|
|
{
|
|
std::stringstream s;
|
|
if(v.has_value())
|
|
{
|
|
s << "(+void)";
|
|
}
|
|
if(v.has_error())
|
|
{
|
|
s << "(-void)";
|
|
}
|
|
return s.str();
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class R, class S, class P, class N)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(detail::lvalueref<std::istream>() >> detail::lvalueref<R>()), OUTCOME_TEXPR(detail::lvalueref<std::istream>() >> detail::lvalueref<S>()), OUTCOME_TEXPR(detail::lvalueref<std::istream>() >> detail::lvalueref<P>()))
|
|
inline std::istream &operator>>(std::istream &s, outcome<R, S, P, N> &v)
|
|
{
|
|
s >> v._iostreams_state();
|
|
if(v.has_error())
|
|
{
|
|
s >> v.assume_error();
|
|
}
|
|
if(v.has_exception())
|
|
{
|
|
s >> v.assume_exception();
|
|
}
|
|
return s;
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class R, class S, class P, class N)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(detail::lvalueref<std::ostream>() << detail::lvalueref<R>()), OUTCOME_TEXPR(detail::lvalueref<std::ostream>() << detail::lvalueref<S>()), OUTCOME_TEXPR(detail::lvalueref<std::ostream>() << detail::lvalueref<P>()))
|
|
inline std::ostream &operator<<(std::ostream &s, const outcome<R, S, P, N> &v)
|
|
{
|
|
s << v._iostreams_state();
|
|
if(v.has_error())
|
|
{
|
|
s << v.assume_error();
|
|
}
|
|
if(v.has_exception())
|
|
{
|
|
s << v.assume_exception();
|
|
}
|
|
return s;
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
template <class R, class S, class P, class N> inline std::string print(const outcome<R, S, P, N> &v)
|
|
{
|
|
std::stringstream s;
|
|
int total = static_cast<int>(v.has_value()) + static_cast<int>(v.has_error()) + static_cast<int>(v.has_exception());
|
|
if(total > 1)
|
|
{
|
|
s << "{ ";
|
|
}
|
|
s << print(static_cast<const basic_result<R, S, N> &>(static_cast<const detail::basic_result_final<R, S, N> &>(v))); // NOLINT
|
|
if(total > 1)
|
|
{
|
|
s << ", ";
|
|
}
|
|
if(v.has_exception())
|
|
{
|
|
#ifdef __cpp_exceptions
|
|
try
|
|
{
|
|
rethrow_exception(v.exception());
|
|
}
|
|
catch(const std::system_error &e)
|
|
{
|
|
s << "std::system_error code " << e.code() << ": " << e.what();
|
|
}
|
|
catch(const std::exception &e)
|
|
{
|
|
s << "std::exception: " << e.what();
|
|
}
|
|
catch(...)
|
|
#endif
|
|
{
|
|
s << "unknown exception";
|
|
}
|
|
}
|
|
if(total > 1)
|
|
{
|
|
s << " }";
|
|
}
|
|
return s.str();
|
|
}
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#endif
|
|
/* Try operation macros
|
|
(C) 2017-2021 Niall Douglas <http://www.nedproductions.biz/> (20 commits)
|
|
File Created: July 2017
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License in the accompanying file
|
|
Licence.txt or at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file Licence.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
#ifndef OUTCOME_TRY_HPP
|
|
#define OUTCOME_TRY_HPP
|
|
OUTCOME_V2_NAMESPACE_BEGIN
|
|
namespace detail
|
|
{
|
|
struct has_value_overload
|
|
{
|
|
};
|
|
struct as_failure_overload
|
|
{
|
|
};
|
|
struct assume_error_overload
|
|
{
|
|
};
|
|
struct error_overload
|
|
{
|
|
};
|
|
struct assume_value_overload
|
|
{
|
|
};
|
|
struct value_overload
|
|
{
|
|
};
|
|
//#ifdef __APPLE__
|
|
// OUTCOME_TEMPLATE(class T, class R = decltype(std::declval<T>()._xcode_workaround_as_failure()))
|
|
//#else
|
|
OUTCOME_TEMPLATE(class T, class R = decltype(std::declval<T>().as_failure()))
|
|
//#endif
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(OUTCOME_V2_NAMESPACE::is_failure_type<R>))
|
|
constexpr inline bool has_as_failure(int /*unused */) { return true; }
|
|
template <class T> constexpr inline bool has_as_failure(...) { return false; }
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<T>().assume_error()))
|
|
constexpr inline bool has_assume_error(int /*unused */) { return true; }
|
|
template <class T> constexpr inline bool has_assume_error(...) { return false; }
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<T>().error()))
|
|
constexpr inline bool has_error(int /*unused */) { return true; }
|
|
template <class T> constexpr inline bool has_error(...) { return false; }
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<T>().assume_value()))
|
|
constexpr inline bool has_assume_value(int /*unused */) { return true; }
|
|
template <class T> constexpr inline bool has_assume_value(...) { return false; }
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<T>().value()))
|
|
constexpr inline bool has_value(int /*unused */) { return true; }
|
|
template <class T> constexpr inline bool has_value(...) { return false; }
|
|
} // namespace detail
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TEXPR(std::declval<T>().has_value()))
|
|
constexpr inline bool try_operation_has_value(T &&v, detail::has_value_overload = {})
|
|
{
|
|
return v.has_value();
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(detail::has_as_failure<T>(5)))
|
|
constexpr inline decltype(auto) try_operation_return_as(T &&v, detail::as_failure_overload = {})
|
|
{
|
|
return static_cast<T &&>(v).as_failure();
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!detail::has_as_failure<T>(5) && detail::has_assume_error<T>(5)))
|
|
constexpr inline decltype(auto) try_operation_return_as(T &&v, detail::assume_error_overload = {})
|
|
{
|
|
return failure(static_cast<T &&>(v).assume_error());
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!detail::has_as_failure<T>(5) && !detail::has_assume_error<T>(5) && detail::has_error<T>(5)))
|
|
constexpr inline decltype(auto) try_operation_return_as(T &&v, detail::error_overload = {})
|
|
{
|
|
return failure(static_cast<T &&>(v).error());
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(detail::has_assume_value<T>(5)))
|
|
constexpr inline decltype(auto) try_operation_extract_value(T &&v, detail::assume_value_overload = {})
|
|
{
|
|
return static_cast<T &&>(v).assume_value();
|
|
}
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
OUTCOME_TEMPLATE(class T)
|
|
OUTCOME_TREQUIRES(OUTCOME_TPRED(!detail::has_assume_value<T>(5) && detail::has_value<T>(5)))
|
|
constexpr inline decltype(auto) try_operation_extract_value(T &&v, detail::value_overload = {})
|
|
{
|
|
return static_cast<T &&>(v).value();
|
|
}
|
|
OUTCOME_V2_NAMESPACE_END
|
|
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 8
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wparentheses"
|
|
#endif
|
|
#define OUTCOME_TRY_GLUE2(x, y) x##y
|
|
#define OUTCOME_TRY_GLUE(x, y) OUTCOME_TRY_GLUE2(x, y)
|
|
#define OUTCOME_TRY_UNIQUE_NAME OUTCOME_TRY_GLUE(_outcome_try_unique_name_temporary, __COUNTER__)
|
|
#define OUTCOME_TRY_RETURN_ARG_COUNT(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, count, ...) count
|
|
#define OUTCOME_TRY_EXPAND_ARGS(args) OUTCOME_TRY_RETURN_ARG_COUNT args
|
|
#define OUTCOME_TRY_COUNT_ARGS_MAX8(...) OUTCOME_TRY_EXPAND_ARGS((__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0))
|
|
#define OUTCOME_TRY_OVERLOAD_MACRO2(name, count) name##count
|
|
#define OUTCOME_TRY_OVERLOAD_MACRO1(name, count) OUTCOME_TRY_OVERLOAD_MACRO2(name, count)
|
|
#define OUTCOME_TRY_OVERLOAD_MACRO(name, count) OUTCOME_TRY_OVERLOAD_MACRO1(name, count)
|
|
#define OUTCOME_TRY_OVERLOAD_GLUE(x, y) x y
|
|
#define OUTCOME_TRY_CALL_OVERLOAD(name, ...) OUTCOME_TRY_OVERLOAD_GLUE(OUTCOME_TRY_OVERLOAD_MACRO(name, OUTCOME_TRY_COUNT_ARGS_MAX8(__VA_ARGS__)), (__VA_ARGS__))
|
|
#define _OUTCOME_TRY_RETURN_ARG_COUNT(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, count, ...) count
|
|
#define _OUTCOME_TRY_EXPAND_ARGS(args) _OUTCOME_TRY_RETURN_ARG_COUNT args
|
|
#define _OUTCOME_TRY_COUNT_ARGS_MAX8(...) _OUTCOME_TRY_EXPAND_ARGS((__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0))
|
|
#define _OUTCOME_TRY_OVERLOAD_MACRO2(name, count) name##count
|
|
#define _OUTCOME_TRY_OVERLOAD_MACRO1(name, count) _OUTCOME_TRY_OVERLOAD_MACRO2(name, count)
|
|
#define _OUTCOME_TRY_OVERLOAD_MACRO(name, count) _OUTCOME_TRY_OVERLOAD_MACRO1(name, count)
|
|
#define _OUTCOME_TRY_OVERLOAD_GLUE(x, y) x y
|
|
#define _OUTCOME_TRY_CALL_OVERLOAD(name, ...) _OUTCOME_TRY_OVERLOAD_GLUE(_OUTCOME_TRY_OVERLOAD_MACRO(name, _OUTCOME_TRY_COUNT_ARGS_MAX8(__VA_ARGS__)), (__VA_ARGS__))
|
|
#ifndef OUTCOME_TRY_LIKELY_IF
|
|
#if (__cplusplus >= 202000 || _HAS_CXX20) && (!defined(__clang__) || __clang_major__ >= 12) && (!defined(__GNUC__) || defined(__clang__) || __GNUC__ >= 9)
|
|
#define OUTCOME_TRY_LIKELY_IF(...) if(__VA_ARGS__) [[likely]]
|
|
#elif defined(__clang__) || defined(__GNUC__)
|
|
#define OUTCOME_TRY_LIKELY_IF(...) if(__builtin_expect(!!(__VA_ARGS__), true))
|
|
#else
|
|
#define OUTCOME_TRY_LIKELY_IF(...) if(__VA_ARGS__)
|
|
#endif
|
|
#endif
|
|
#define OUTCOME_TRYV2_UNIQUE_STORAGE_UNPACK(...) __VA_ARGS__
|
|
#define OUTCOME_TRYV2_UNIQUE_STORAGE_DEDUCE3(unique, ...) auto unique = (__VA_ARGS__)
|
|
#define OUTCOME_TRYV2_UNIQUE_STORAGE_DEDUCE2(x) x
|
|
#define OUTCOME_TRYV2_UNIQUE_STORAGE_DEDUCE(unique, x, ...) OUTCOME_TRYV2_UNIQUE_STORAGE_DEDUCE2(OUTCOME_TRYV2_UNIQUE_STORAGE_DEDUCE3(unique, __VA_ARGS__))
|
|
#define OUTCOME_TRYV2_UNIQUE_STORAGE_SPECIFIED3(unique, x, y, ...) x unique = (__VA_ARGS__)
|
|
#define OUTCOME_TRYV2_UNIQUE_STORAGE_SPECIFIED2(x) x
|
|
#define OUTCOME_TRYV2_UNIQUE_STORAGE_SPECIFIED(unique, ...) OUTCOME_TRYV2_UNIQUE_STORAGE_SPECIFIED2(OUTCOME_TRYV2_UNIQUE_STORAGE_SPECIFIED3(unique, __VA_ARGS__))
|
|
#define OUTCOME_TRYV2_UNIQUE_STORAGE1(...) OUTCOME_TRYV2_UNIQUE_STORAGE_DEDUCE
|
|
#define OUTCOME_TRYV2_UNIQUE_STORAGE2(...) OUTCOME_TRYV2_UNIQUE_STORAGE_SPECIFIED
|
|
#define OUTCOME_TRYV2_UNIQUE_STORAGE(unique, spec, ...) _OUTCOME_TRY_CALL_OVERLOAD(OUTCOME_TRYV2_UNIQUE_STORAGE, OUTCOME_TRYV2_UNIQUE_STORAGE_UNPACK spec) (unique, OUTCOME_TRYV2_UNIQUE_STORAGE_UNPACK spec, __VA_ARGS__)
|
|
// Use if(!expr); else as some compilers assume else clauses are always unlikely
|
|
#define OUTCOME_TRYV2_SUCCESS_LIKELY(unique, retstmt, spec, ...) OUTCOME_TRYV2_UNIQUE_STORAGE(unique, spec, __VA_ARGS__); OUTCOME_TRY_LIKELY_IF(::OUTCOME_V2_NAMESPACE::try_operation_has_value(unique)); else retstmt ::OUTCOME_V2_NAMESPACE::try_operation_return_as(static_cast<decltype(unique) &&>(unique))
|
|
#define OUTCOME_TRYV3_FAILURE_LIKELY(unique, retstmt, spec, ...) OUTCOME_TRYV2_UNIQUE_STORAGE(unique, spec, __VA_ARGS__); OUTCOME_TRY_LIKELY_IF(!OUTCOME_V2_NAMESPACE::try_operation_has_value(unique)) retstmt ::OUTCOME_V2_NAMESPACE::try_operation_return_as(static_cast<decltype(unique) &&>(unique))
|
|
#define OUTCOME_TRY2_VAR_SECOND2(x, var) var
|
|
#define OUTCOME_TRY2_VAR_SECOND3(x, y, ...) x y
|
|
#define OUTCOME_TRY2_VAR(spec) _OUTCOME_TRY_CALL_OVERLOAD(OUTCOME_TRY2_VAR_SECOND, OUTCOME_TRYV2_UNIQUE_STORAGE_UNPACK spec, spec)
|
|
#define OUTCOME_TRY2_SUCCESS_LIKELY(unique, retstmt, var, ...) OUTCOME_TRYV2_SUCCESS_LIKELY(unique, retstmt, var, __VA_ARGS__); OUTCOME_TRY2_VAR(var) = ::OUTCOME_V2_NAMESPACE::try_operation_extract_value(static_cast<decltype(unique) &&>(unique))
|
|
#define OUTCOME_TRY2_FAILURE_LIKELY(unique, retstmt, var, ...) OUTCOME_TRYV3_FAILURE_LIKELY(unique, retstmt, var, __VA_ARGS__); OUTCOME_TRY2_VAR(var) = ::OUTCOME_V2_NAMESPACE::try_operation_extract_value(static_cast<decltype(unique) &&>(unique))
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_TRYV(...) OUTCOME_TRYV2_SUCCESS_LIKELY(OUTCOME_TRY_UNIQUE_NAME, return, deduce, __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_TRYV_FAILURE_LIKELY(...) OUTCOME_TRYV3_FAILURE_LIKELY(OUTCOME_TRY_UNIQUE_NAME, return, deduce, __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_CO_TRYV(...) OUTCOME_TRYV2_SUCCESS_LIKELY(OUTCOME_TRY_UNIQUE_NAME, co_return, deduce, __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_CO_TRYV_FAILURE_LIKELY(...) OUTCOME_TRYV3_FAILURE_LIKELY(OUTCOME_TRY_UNIQUE_NAME, co_return, deduce, __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_TRYV2(s, ...) OUTCOME_TRYV2_SUCCESS_LIKELY(OUTCOME_TRY_UNIQUE_NAME, return, (s,), __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_TRYV2_FAILURE_LIKELY(s, ...) OUTCOME_TRYV3_FAILURE_LIKELY(OUTCOME_TRY_UNIQUE_NAME, return, (s,), __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_CO_TRYV2(s, ...) OUTCOME_TRYV2_SUCCESS_LIKELY(OUTCOME_TRY_UNIQUE_NAME, co_return, (s,), __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_CO_TRYV2_FAILURE_LIKELY(s, ...) OUTCOME_TRYV3_FAILURE_LIKELY(OUTCOME_TRY_UNIQUE_NAME, co_return, s(,), __VA_ARGS__)
|
|
#if defined(__GNUC__) || defined(__clang__)
|
|
#define OUTCOME_TRYX2(unique, retstmt, ...) ({ OUTCOME_TRYV2_SUCCESS_LIKELY(unique, retstmt, deduce, __VA_ARGS__); ::OUTCOME_V2_NAMESPACE::try_operation_extract_value(static_cast<decltype(unique) &&>(unique)); })
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_TRYX(...) OUTCOME_TRYX2(OUTCOME_TRY_UNIQUE_NAME, return, __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_CO_TRYX(...) OUTCOME_TRYX2(OUTCOME_TRY_UNIQUE_NAME, co_return, __VA_ARGS__)
|
|
#endif
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_TRYA(v, ...) OUTCOME_TRY2_SUCCESS_LIKELY(OUTCOME_TRY_UNIQUE_NAME, return, v, __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_TRYA_FAILURE_LIKELY(v, ...) OUTCOME_TRY2_FAILURE_LIKELY(OUTCOME_TRY_UNIQUE_NAME, return, v, __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_CO_TRYA(v, ...) OUTCOME_TRY2_SUCCESS_LIKELY(OUTCOME_TRY_UNIQUE_NAME, co_return, v, __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_CO_TRYA_FAILURE_LIKELY(v, ...) OUTCOME_TRY2_FAILURE_LIKELY(OUTCOME_TRY_UNIQUE_NAME, co_return, v, __VA_ARGS__)
|
|
#define OUTCOME_TRY_INVOKE_TRY8(a, b, c, d, e, f, g, h) OUTCOME_TRYA(a, b, c, d, e, f, g, h)
|
|
#define OUTCOME_TRY_INVOKE_TRY7(a, b, c, d, e, f, g) OUTCOME_TRYA(a, b, c, d, e, f, g)
|
|
#define OUTCOME_TRY_INVOKE_TRY6(a, b, c, d, e, f) OUTCOME_TRYA(a, b, c, d, e, f)
|
|
#define OUTCOME_TRY_INVOKE_TRY5(a, b, c, d, e) OUTCOME_TRYA(a, b, c, d, e)
|
|
#define OUTCOME_TRY_INVOKE_TRY4(a, b, c, d) OUTCOME_TRYA(a, b, c, d)
|
|
#define OUTCOME_TRY_INVOKE_TRY3(a, b, c) OUTCOME_TRYA(a, b, c)
|
|
#define OUTCOME_TRY_INVOKE_TRY2(a, b) OUTCOME_TRYA(a, b)
|
|
#define OUTCOME_TRY_INVOKE_TRY1(a) OUTCOME_TRYV(a)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_TRY(...) OUTCOME_TRY_CALL_OVERLOAD(OUTCOME_TRY_INVOKE_TRY, __VA_ARGS__)
|
|
#define OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY8(a, b, c, d, e, f, g, h) OUTCOME_TRYA_FAILURE_LIKELY(a, b, c, d, e, f, g, h)
|
|
#define OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY7(a, b, c, d, e, f, g) OUTCOME_TRYA_FAILURE_LIKELY(a, b, c, d, e, f, g)
|
|
#define OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY6(a, b, c, d, e, f) OUTCOME_TRYA_FAILURE_LIKELY(a, b, c, d, e, f)
|
|
#define OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY5(a, b, c, d, e) OUTCOME_TRYA_FAILURE_LIKELY(a, b, c, d, e)
|
|
#define OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY4(a, b, c, d) OUTCOME_TRYA_FAILURE_LIKELY(a, b, c, d)
|
|
#define OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY3(a, b, c) OUTCOME_TRYA_FAILURE_LIKELY(a, b, c)
|
|
#define OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY2(a, b) OUTCOME_TRYA_FAILURE_LIKELY(a, b)
|
|
#define OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY1(a) OUTCOME_TRYV_FAILURE_LIKELY(a)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_TRY_FAILURE_LIKELY(...) OUTCOME_TRY_CALL_OVERLOAD(OUTCOME_TRY_FAILURE_LIKELY_INVOKE_TRY, __VA_ARGS__)
|
|
#define OUTCOME_CO_TRY_INVOKE_TRY8(a, b, c, d, e, f, g, h) OUTCOME_CO_TRYA(a, b, c, d, e, f, g, h)
|
|
#define OUTCOME_CO_TRY_INVOKE_TRY7(a, b, c, d, e, f, g) OUTCOME_CO_TRYA(a, b, c, d, e, f, g)
|
|
#define OUTCOME_CO_TRY_INVOKE_TRY6(a, b, c, d, e, f) OUTCOME_CO_TRYA(a, b, c, d, e, f)
|
|
#define OUTCOME_CO_TRY_INVOKE_TRY5(a, b, c, d, e) OUTCOME_CO_TRYA(a, b, c, d, e)
|
|
#define OUTCOME_CO_TRY_INVOKE_TRY4(a, b, c, d) OUTCOME_CO_TRYA(a, b, c, d)
|
|
#define OUTCOME_CO_TRY_INVOKE_TRY3(a, b, c) OUTCOME_CO_TRYA(a, b, c)
|
|
#define OUTCOME_CO_TRY_INVOKE_TRY2(a, b) OUTCOME_CO_TRYA(a, b)
|
|
#define OUTCOME_CO_TRY_INVOKE_TRY1(a) OUTCOME_CO_TRYV(a)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_CO_TRY(...) OUTCOME_TRY_CALL_OVERLOAD(OUTCOME_CO_TRY_INVOKE_TRY, __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_TRY(...) OUTCOME_TRY_CALL_OVERLOAD(OUTCOME_TRY_INVOKE_TRY, __VA_ARGS__)
|
|
#define OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY8(a, b, c, d, e, f, g, h) OUTCOME_CO_TRYA_FAILURE_LIKELY(a, b, c, d, e, f, g, h)
|
|
#define OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY7(a, b, c, d, e, f, g) OUTCOME_CO_TRYA_FAILURE_LIKELY(a, b, c, d, e, f, g)
|
|
#define OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY6(a, b, c, d, e, f) OUTCOME_CO_TRYA_FAILURE_LIKELY(a, b, c, d, e, f)
|
|
#define OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY5(a, b, c, d, e) OUTCOME_CO_TRYA_FAILURE_LIKELY(a, b, c, d, e)
|
|
#define OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY4(a, b, c, d) OUTCOME_CO_TRYA_FAILURE_LIKELY(a, b, c, d)
|
|
#define OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY3(a, b, c) OUTCOME_CO_TRYA_FAILURE_LIKELY(a, b, c)
|
|
#define OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY2(a, b) OUTCOME_CO_TRYA_FAILURE_LIKELY(a, b)
|
|
#define OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY1(a) OUTCOME_CO_TRYV_FAILURE_LIKELY(a)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME_CO_TRY_FAILURE_LIKELY(...) OUTCOME_TRY_CALL_OVERLOAD(OUTCOME_CO_TRY_FAILURE_LIKELY_INVOKE_TRY, __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME21_TRYA(v, ...) OUTCOME_TRY2_SUCCESS_LIKELY(OUTCOME_TRY_UNIQUE_NAME, return, deduce, auto &&v, __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME21_TRYA_FAILURE_LIKELY(v, ...) OUTCOME_TRY2_FAILURE_LIKELY(OUTCOME_TRY_UNIQUE_NAME, return, deduce, auto &&v, __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME21_CO_TRYA(v, ...) OUTCOME_TRY2_FAILURE_LIKELY(OUTCOME_TRY_UNIQUE_NAME, co_return, deduce, auto &&v, __VA_ARGS__)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME21_CO_TRYA_FAILURE_LIKELY(v, ...) OUTCOME_TRY2_FAILURE_LIKELY(OUTCOME_TRY_UNIQUE_NAME, co_retrn, deduce, auto &&v, __VA_ARGS__)
|
|
#define OUTCOME21_TRY_INVOKE_TRY8(a, b, c, d, e, f, g, h) OUTCOME21_TRYA(a, b, c, d, e, f, g, h)
|
|
#define OUTCOME21_TRY_INVOKE_TRY7(a, b, c, d, e, f, g) OUTCOME21_TRYA(a, b, c, d, e, f, g)
|
|
#define OUTCOME21_TRY_INVOKE_TRY6(a, b, c, d, e, f) OUTCOME21_TRYA(a, b, c, d, e, f)
|
|
#define OUTCOME21_TRY_INVOKE_TRY5(a, b, c, d, e) OUTCOME21_TRYA(a, b, c, d, e)
|
|
#define OUTCOME21_TRY_INVOKE_TRY4(a, b, c, d) OUTCOME21_TRYA(a, b, c, d)
|
|
#define OUTCOME21_TRY_INVOKE_TRY3(a, b, c) OUTCOME21_TRYA(a, b, c)
|
|
#define OUTCOME21_TRY_INVOKE_TRY2(a, b) OUTCOME21_TRYA(a, b)
|
|
#define OUTCOME21_TRY_INVOKE_TRY1(a) OUTCOME_TRYV(a)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME21_TRY(...) OUTCOME_TRY_CALL_OVERLOAD(OUTCOME21_TRY_INVOKE_TRY, __VA_ARGS__)
|
|
#define OUTCOME21_TRY_FAILURE_LIKELY_INVOKE_TRY8(a, b, c, d, e, f, g, h) OUTCOME21_TRYA_FAILURE_LIKELY(a, b, c, d, e, f, g, h)
|
|
#define OUTCOME21_TRY_FAILURE_LIKELY_INVOKE_TRY7(a, b, c, d, e, f, g) OUTCOME21_TRYA_FAILURE_LIKELY(a, b, c, d, e, f, g)
|
|
#define OUTCOME21_TRY_FAILURE_LIKELY_INVOKE_TRY6(a, b, c, d, e, f) OUTCOME21_TRYA_FAILURE_LIKELY(a, b, c, d, e, f)
|
|
#define OUTCOME21_TRY_FAILURE_LIKELY_INVOKE_TRY5(a, b, c, d, e) OUTCOME21_TRYA_FAILURE_LIKELY(a, b, c, d, e)
|
|
#define OUTCOME21_TRY_FAILURE_LIKELY_INVOKE_TRY4(a, b, c, d) OUTCOME21_TRYA_FAILURE_LIKELY(a, b, c, d)
|
|
#define OUTCOME21_TRY_FAILURE_LIKELY_INVOKE_TRY3(a, b, c) OUTCOME21_TRYA_FAILURE_LIKELY(a, b, c)
|
|
#define OUTCOME21_TRY_FAILURE_LIKELY_INVOKE_TRY2(a, b) OUTCOME21_TRYA_FAILURE_LIKELY(a, b)
|
|
#define OUTCOME21_TRY_FAILURE_LIKELY_INVOKE_TRY1(a) OUTCOME_TRYV_FAILURE_LIKELY(a)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME21_TRY_FAILURE_LIKELY(...) OUTCOME_TRY_CALL_OVERLOAD(OUTCOME21_TRY_FAILURE_LIKELY_INVOKE_TRY, __VA_ARGS__)
|
|
#define OUTCOME21_CO_TRY_INVOKE_TRY8(a, b, c, d, e, f, g, h) OUTCOME21_CO_TRYA(a, b, c, d, e, f, g, h)
|
|
#define OUTCOME21_CO_TRY_INVOKE_TRY7(a, b, c, d, e, f, g) OUTCOME21_CO_TRYA(a, b, c, d, e, f, g)
|
|
#define OUTCOME21_CO_TRY_INVOKE_TRY6(a, b, c, d, e, f) OUTCOME21_CO_TRYA(a, b, c, d, e, f)
|
|
#define OUTCOME21_CO_TRY_INVOKE_TRY5(a, b, c, d, e) OUTCOME21_CO_TRYA(a, b, c, d, e)
|
|
#define OUTCOME21_CO_TRY_INVOKE_TRY4(a, b, c, d) OUTCOME21_CO_TRYA(a, b, c, d)
|
|
#define OUTCOME21_CO_TRY_INVOKE_TRY3(a, b, c) OUTCOME21_CO_TRYA(a, b, c)
|
|
#define OUTCOME21_CO_TRY_INVOKE_TRY2(a, b) OUTCOME21_CO_TRYA(a, b)
|
|
#define OUTCOME21_CO_TRY_INVOKE_TRY1(a) OUTCOME_CO_TRYV(a)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME21_CO_TRY(...) OUTCOME_TRY_CALL_OVERLOAD(OUTCOME21_CO_TRY_INVOKE_TRY, __VA_ARGS__)
|
|
#define OUTCOME21_CO_TRY_FAILURE_LIKELY_INVOKE_TRY8(a, b, c, d, e, f, g, h) OUTCOME21_CO_TRYA_FAILURE_LIKELY(a, b, c, d, e, f, g, h)
|
|
#define OUTCOME21_CO_TRY_FAILURE_LIKELY_INVOKE_TRY7(a, b, c, d, e, f, g) OUTCOME21_CO_TRYA_FAILURE_LIKELY(a, b, c, d, e, f, g)
|
|
#define OUTCOME21_CO_TRY_FAILURE_LIKELY_INVOKE_TRY6(a, b, c, d, e, f) OUTCOME21_CO_TRYA_FAILURE_LIKELY(a, b, c, d, e, f)
|
|
#define OUTCOME21_CO_TRY_FAILURE_LIKELY_INVOKE_TRY5(a, b, c, d, e) OUTCOME21_CO_TRYA_FAILURE_LIKELY(a, b, c, d, e)
|
|
#define OUTCOME21_CO_TRY_FAILURE_LIKELY_INVOKE_TRY4(a, b, c, d) OUTCOME21_CO_TRYA_FAILURE_LIKELY(a, b, c, d)
|
|
#define OUTCOME21_CO_TRY_FAILURE_LIKELY_INVOKE_TRY3(a, b, c) OUTCOME21_CO_TRYA_FAILURE_LIKELY(a, b, c)
|
|
#define OUTCOME21_CO_TRY_FAILURE_LIKELY_INVOKE_TRY2(a, b) OUTCOME21_CO_TRYA_FAILURE_LIKELY(a, b)
|
|
#define OUTCOME21_CO_TRY_FAILURE_LIKELY_INVOKE_TRY1(a) OUTCOME_CO_TRYV_FAILURE_LIKELY(a)
|
|
/*! AWAITING HUGO JSON CONVERSION TOOL
|
|
SIGNATURE NOT RECOGNISED
|
|
*/
|
|
#define OUTCOME21_CO_TRY_FAILURE_LIKELY(...) OUTCOME_TRY_CALL_OVERLOAD(OUTCOME21_CO_TRY_FAILURE_LIKELY_INVOKE_TRY, __VA_ARGS__)
|
|
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 8
|
|
#pragma GCC diagnostic pop
|
|
#endif
|
|
#endif
|
|
#else
|
|
import OUTCOME_V2_CXX_MODULE_NAME;
|
|
#endif
|