From 8b71e9d476877025e0acb3c72c652377e38584da Mon Sep 17 00:00:00 2001 From: rudy Date: Mon, 3 Jan 2022 11:06:01 +0100 Subject: [PATCH] feat(Clientlib): separate client encryption and server computation Resolve #200 --- .../workflows/scripts/check_for_license.sh | 3 +- .github/workflows/scripts/format_cpp.sh | 4 +- compiler/CMakeLists.txt | 10 + compiler/Makefile | 19 +- .../include/boost-single-header/outcome.hpp | 7939 +++++++++++++++++ compiler/include/boost/outcome.h | 13 + .../concretelang/ClientLib/ClientLambda.h | 141 + .../concretelang/ClientLib/ClientParameters.h | 25 +- .../concretelang/ClientLib/EncryptedArgs.h | 133 + .../include/concretelang/ClientLib/KeySet.h | 73 +- .../concretelang/ClientLib/KeySetCache.h | 24 +- .../concretelang/ClientLib/PublicArguments.h | 66 + .../concretelang/ClientLib/Serializers.h | 78 + .../include/concretelang/ClientLib/Types.h | 58 + .../include/concretelang/Common/BitsSize.h | 19 + compiler/include/concretelang/Common/Error.h | 43 + .../include/concretelang/Runtime/context.h | 5 +- .../DynamicArityCall.h} | 18 +- .../{TestLib => ServerLib}/DynamicModule.h | 23 +- .../concretelang/ServerLib/DynamicRankCall.h | 25 + .../concretelang/ServerLib/ServerLambda.h | 52 + .../ServerLib/genDynamicArityCall.py | 45 + .../concretelang/Support/CompilerEngine.h | 4 +- compiler/include/concretelang/Support/Jit.h | 3 +- .../concretelang/Support/JitCompilerEngine.h | 2 + .../concretelang/Support/V0ClientParameters.h | 3 +- .../include/concretelang/TestLib/Arguments.h | 105 - .../concretelang/TestLib/DynamicLambda.h | 123 - .../concretelang/TestLib/TestTypedLambda.h | 118 + .../TestLib/genDynamicArityCall.py | 6 - compiler/lib/CAPI/Support/CompilerEngine.cpp | 2 +- compiler/lib/CMakeLists.txt | 3 +- compiler/lib/ClientLib/CMakeLists.txt | 20 + compiler/lib/ClientLib/ClientLambda.cpp | 207 + compiler/lib/ClientLib/ClientParameters.cpp | 61 +- compiler/lib/ClientLib/EncryptedArgs.cpp | 181 + compiler/lib/ClientLib/KeySet.cpp | 164 +- compiler/lib/ClientLib/KeySetCache.cpp | 79 +- compiler/lib/ClientLib/PublicArguments.cpp | 156 + compiler/lib/ClientLib/Serializers.cpp | 185 + compiler/lib/Common/BitsSize.cpp | 23 + compiler/lib/Common/CMakeLists.txt | 19 + compiler/lib/Runtime/context.cpp | 14 +- compiler/lib/ServerLib/CMakeLists.txt | 27 + compiler/lib/ServerLib/DynamicModule.cpp | 54 + compiler/lib/ServerLib/DynamicRankCall.cpp | 163 + compiler/lib/ServerLib/ServerLambda.cpp | 159 + compiler/lib/ServerLib/genDynamicRankCall.py | 44 + compiler/lib/Support/CMakeLists.txt | 3 +- compiler/lib/Support/CompilerEngine.cpp | 101 +- compiler/lib/Support/Jit.cpp | 40 +- compiler/lib/Support/JitCompilerEngine.cpp | 14 +- compiler/lib/Support/V0ClientParameters.cpp | 16 +- compiler/lib/TestLib/Arguments.cpp | 187 - compiler/lib/TestLib/CMakeLists.txt | 16 - compiler/lib/TestLib/DynamicLambda.cpp | 217 - compiler/lib/TestLib/DynamicModule.cpp | 61 - compiler/src/CMakeLists.txt | 1 - compiler/tests/Support/CMakeLists.txt | 1 + compiler/tests/Support/support_unit_test.cpp | 86 +- compiler/tests/TestLib/CMakeLists.txt | 7 +- .../call_2t_1s_with_header-client.h.generated | 22 + compiler/tests/TestLib/testlib_unit_test.cpp | 277 +- .../unittest/end_to_end_jit_clear_tensor.cc | 4 +- .../end_to_end_jit_encrypted_tensor.cc | 12 +- compiler/tests/unittest/end_to_end_jit_test.h | 12 + docs/cpp_api/clientlib.rst | 16 + docs/cpp_api/clientlib/arguments.rst | 4 + docs/cpp_api/clientlib/client_example.cpp | 16 + docs/cpp_api/clientlib/client_lambda.rst | 5 + docs/cpp_api/clientlib/client_parameters.rst | 5 + docs/cpp_api/clientlib/intro.rst | 23 + .../{support => clientlib}/key_set.rst | 0 docs/cpp_api/clientlib/server_example.cpp | 10 + docs/cpp_api/clientlib/server_lambda.rst | 4 + docs/cpp_api/support/client_parameters.rst | 4 - 76 files changed, 10799 insertions(+), 1106 deletions(-) create mode 100644 compiler/include/boost-single-header/outcome.hpp create mode 100644 compiler/include/boost/outcome.h create mode 100644 compiler/include/concretelang/ClientLib/ClientLambda.h create mode 100644 compiler/include/concretelang/ClientLib/EncryptedArgs.h create mode 100644 compiler/include/concretelang/ClientLib/PublicArguments.h create mode 100644 compiler/include/concretelang/ClientLib/Serializers.h create mode 100644 compiler/include/concretelang/ClientLib/Types.h create mode 100644 compiler/include/concretelang/Common/BitsSize.h create mode 100644 compiler/include/concretelang/Common/Error.h rename compiler/include/concretelang/{TestLib/dynamicArityCall.h => ServerLib/DynamicArityCall.h} (99%) rename compiler/include/concretelang/{TestLib => ServerLib}/DynamicModule.h (56%) create mode 100644 compiler/include/concretelang/ServerLib/DynamicRankCall.h create mode 100644 compiler/include/concretelang/ServerLib/ServerLambda.h create mode 100644 compiler/include/concretelang/ServerLib/genDynamicArityCall.py delete mode 100644 compiler/include/concretelang/TestLib/Arguments.h delete mode 100644 compiler/include/concretelang/TestLib/DynamicLambda.h create mode 100644 compiler/include/concretelang/TestLib/TestTypedLambda.h delete mode 100644 compiler/include/concretelang/TestLib/genDynamicArityCall.py create mode 100644 compiler/lib/ClientLib/ClientLambda.cpp create mode 100644 compiler/lib/ClientLib/EncryptedArgs.cpp create mode 100644 compiler/lib/ClientLib/PublicArguments.cpp create mode 100644 compiler/lib/ClientLib/Serializers.cpp create mode 100644 compiler/lib/Common/BitsSize.cpp create mode 100644 compiler/lib/Common/CMakeLists.txt create mode 100644 compiler/lib/ServerLib/CMakeLists.txt create mode 100644 compiler/lib/ServerLib/DynamicModule.cpp create mode 100644 compiler/lib/ServerLib/DynamicRankCall.cpp create mode 100644 compiler/lib/ServerLib/ServerLambda.cpp create mode 100644 compiler/lib/ServerLib/genDynamicRankCall.py delete mode 100644 compiler/lib/TestLib/Arguments.cpp delete mode 100644 compiler/lib/TestLib/CMakeLists.txt delete mode 100644 compiler/lib/TestLib/DynamicLambda.cpp delete mode 100644 compiler/lib/TestLib/DynamicModule.cpp create mode 100644 compiler/tests/TestLib/call_2t_1s_with_header-client.h.generated create mode 100644 docs/cpp_api/clientlib.rst create mode 100644 docs/cpp_api/clientlib/arguments.rst create mode 100644 docs/cpp_api/clientlib/client_example.cpp create mode 100644 docs/cpp_api/clientlib/client_lambda.rst create mode 100644 docs/cpp_api/clientlib/client_parameters.rst create mode 100644 docs/cpp_api/clientlib/intro.rst rename docs/cpp_api/{support => clientlib}/key_set.rst (100%) create mode 100644 docs/cpp_api/clientlib/server_example.cpp create mode 100644 docs/cpp_api/clientlib/server_lambda.rst delete mode 100644 docs/cpp_api/support/client_parameters.rst diff --git a/.github/workflows/scripts/check_for_license.sh b/.github/workflows/scripts/check_for_license.sh index 18298db29..e2655e58a 100755 --- a/.github/workflows/scripts/check_for_license.sh +++ b/.github/workflows/scripts/check_for_license.sh @@ -5,8 +5,9 @@ print_and_exit() { exit 1 } +EXCLUDE_DIRS="-path ./compiler/include/boost-single-header -prune -o" -files=$(find ./compiler/{include,lib,src} -iregex '^.*\.\(cpp\|cc\|h\|hpp\)$') +files=$(find ./compiler/{include,lib,src} $EXCLUDE_DIRS -iregex '^.*\.\(cpp\|cc\|h\|hpp\)$' -print) for file in $files do diff --git a/.github/workflows/scripts/format_cpp.sh b/.github/workflows/scripts/format_cpp.sh index 6755e396a..93b1df4c9 100755 --- a/.github/workflows/scripts/format_cpp.sh +++ b/.github/workflows/scripts/format_cpp.sh @@ -2,7 +2,9 @@ set -e -o pipefail -find ./compiler/{include,lib,src} -iregex '^.*\.\(cpp\|cc\|h\|hpp\)$' | xargs clang-format -i -style='file' +EXCLUDE_DIRS="-path ./compiler/include/boost-single-header -prune -o" + +find ./compiler/{include,lib,src} $EXCLUDE_DIRS -iregex '^.*\.\(cpp\|cc\|h\|hpp\)$' -print | xargs clang-format -i -style='file' # show changes if any git --no-pager diff diff --git a/compiler/CMakeLists.txt b/compiler/CMakeLists.txt index a4d794b96..2577786bb 100644 --- a/compiler/CMakeLists.txt +++ b/compiler/CMakeLists.txt @@ -12,6 +12,16 @@ if (APPLE) add_definitions("-Wno-narrowing") endif() +add_compile_options(-Wfatal-errors) # stop at first error + # variable length array = vla +if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + # using Clang + add_compile_options(-Wno-vla-extension) +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # using GCC + add_compile_options(-Wno-vla) +endif() + # If we are trying to build the compiler with LLVM/MLIR as libraries if( NOT DEFINED LLVM_EXTERNAL_CONCRETELANG_SOURCE_DIR ) message(FATAL_ERROR "Concrete compiler requires a unified build with LLVM/MLIR") diff --git a/compiler/Makefile b/compiler/Makefile index 5be572c83..ec146987b 100644 --- a/compiler/Makefile +++ b/compiler/Makefile @@ -5,6 +5,8 @@ PARALLEL_EXECUTION_ENABLED=OFF CC_COMPILER= CXX_COMPILER= +EXTERNAL_HEADERS=include/boost-single-header/outcome.hpp + export PATH := $(BUILD_DIR)/bin:$(PATH) ifeq ($(shell which ccache),) @@ -51,7 +53,10 @@ $(BUILD_DIR)/configured.stamp: -DPython3_EXECUTABLE=${Python3_EXECUTABLE} touch $@ -build-initialized: $(BUILD_DIR)/configured.stamp +include/boost-single-header/outcome.hpp: + wget https://github.com/ned14/outcome/raw/master/single-header/outcome.hpp -O $@ + +build-initialized: $(EXTERNAL_HEADERS) $(BUILD_DIR)/configured.stamp doc: build-initialized cmake --build $(BUILD_DIR) --target mlir-doc @@ -63,6 +68,12 @@ python-bindings: build-initialized cmake --build $(BUILD_DIR) --target ConcretelangMLIRPythonModules cmake --build $(BUILD_DIR) --target ConcretelangPythonModules +clientlib: build-initialized + cmake --build $(BUILD_DIR) --target ConcretelangClientLib + +serverlib: build-initialized + cmake --build $(BUILD_DIR) --target ConcretelangServerLib + test-check: concretecompiler file-check not $(BUILD_DIR)/bin/llvm-lit -v tests/ @@ -87,6 +98,12 @@ uninstall_runtime_lib: # unit-test +clientlib-unit-test: build-clientlib-unit-test + $(BUILD_DIR)/bin/clientlib_unit_test + +build-clientlib-unit-test: + cmake --build $(BUILD_DIR) --target clientlib_unit_test + testlib-unit-test: build-testlib-unit-test $(BUILD_DIR)/bin/testlib_unit_test diff --git a/compiler/include/boost-single-header/outcome.hpp b/compiler/include/boost-single-header/outcome.hpp new file mode 100644 index 000000000..8ca27cb99 --- /dev/null +++ b/compiler/include/boost-single-header/outcome.hpp @@ -0,0 +1,7939 @@ +/* Include the default amount of outcome +(C) 2018-2021 Niall Douglas (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 (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 (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 (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 (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 (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 QUICKCPPLIB_HAS_CPP_ATTRIBUTE(nodiscard) +#define QUICKCPPLIB_NODISCARD [[nodiscard]] +#elif defined(__clang__) // deliberately not GCC +#define QUICKCPPLIB_NODISCARD __attribute__((warn_unused_result)) +#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 (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 (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 (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 // for uint32_t etc +#include +#include // for future serialisation +#include // for placement in moves etc +#include +#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() +#define OUTCOME_USE_STD_IN_PLACE_TYPE 0 // must have it if 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 // for in_place_type_t +OUTCOME_V2_NAMESPACE_BEGIN +template using in_place_type_t = std::in_place_type_t; +using std::in_place_type; +OUTCOME_V2_NAMESPACE_END +#else +OUTCOME_V2_NAMESPACE_BEGIN +/*! AWAITING HUGO JSON CONVERSION TOOL +type definition template in_place_type_t. Potential doc page: `in_place_type_t` +*/ +template struct in_place_type_t +{ + explicit in_place_type_t() = default; +}; +/*! AWAITING HUGO JSON CONVERSION TOOL +SIGNATURE NOT RECOGNISED +*/ +template constexpr in_place_type_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 struct is_in_place_type_t + { + static constexpr bool value = false; + }; + template struct is_in_place_type_t> + { + 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 using devoid = std::conditional_t::value, void_type, T>; + template using rebind_type5 = Output; + template + using rebind_type4 = std::conditional_t< // + std::is_volatile::value, // + std::add_volatile_t>>, // + rebind_type5>; + template + using rebind_type3 = std::conditional_t< // + std::is_const::value, // + std::add_const_t>>, // + rebind_type4>; + template + using rebind_type2 = std::conditional_t< // + std::is_lvalue_reference::value, // + std::add_lvalue_reference_t>>, // + rebind_type3>; + template + using rebind_type = std::conditional_t< // + std::is_rvalue_reference::value, // + std::add_rvalue_reference_t>>, // + rebind_type2>; + // static_assert(std::is_same_v, volatile const int &&>, ""); + /* True if type is the same or constructible. Works around a bug where clang + libstdc++ + pukes on std::is_constructible (this bug is fixed upstream). + */ + template struct _is_explicitly_constructible + { + static constexpr bool value = std::is_constructible::value; + }; + template struct _is_explicitly_constructible + { + static constexpr bool value = false; + }; + template <> struct _is_explicitly_constructible + { + static constexpr bool value = false; + }; + template static constexpr bool is_explicitly_constructible = _is_explicitly_constructible::value; + template struct _is_implicitly_constructible + { + static constexpr bool value = std::is_convertible::value; + }; + template struct _is_implicitly_constructible + { + static constexpr bool value = false; + }; + template <> struct _is_implicitly_constructible + { + static constexpr bool value = false; + }; + template static constexpr bool is_implicitly_constructible = _is_implicitly_constructible::value; + template struct _is_nothrow_constructible + { + static constexpr bool value = std::is_nothrow_constructible::value; + }; + template struct _is_nothrow_constructible + { + static constexpr bool value = false; + }; + template <> struct _is_nothrow_constructible + { + static constexpr bool value = false; + }; + template static constexpr bool is_nothrow_constructible = _is_nothrow_constructible::value; + template struct _is_constructible + { + static constexpr bool value = std::is_constructible::value; + }; + template struct _is_constructible + { + static constexpr bool value = false; + }; + template <> struct _is_constructible + { + static constexpr bool value = false; + }; + template static constexpr bool is_constructible = _is_constructible::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() +#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 using is_nothrow_swappable = std::is_nothrow_swappable; +#else + template struct is_nothrow_swappable + { + static constexpr bool value = std::is_nothrow_move_constructible::value && std::is_nothrow_move_assignable::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 (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 +#include +#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 (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 (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 +#include // for abort +#include +// 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 +#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 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 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 +#endif +#endif // OUTCOME_DISABLE_EXECINFO +#include +#include +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 (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 +#include +#include +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(ep), not_matched); } + } // namespace detail +} // namespace awaitables +OUTCOME_V2_NAMESPACE_END +#endif +/* Tells C++ coroutines about Outcome's result +(C) 2019-2020 Niall Douglas (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 +#include +#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() +#include +OUTCOME_V2_NAMESPACE_BEGIN +namespace awaitables +{ + template using coroutine_handle = std::coroutine_handle; + template using coroutine_traits = std::coroutine_traits; + 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() +#include +OUTCOME_V2_NAMESPACE_BEGIN +namespace awaitables +{ + template using coroutine_handle = std::experimental::coroutine_handle; + template using coroutine_traits = std::experimental::coroutine_traits; + 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 struct type_found + { + using type = T; + }; + template constexpr inline type_found extract_error_type(int /*unused*/) { return {}; } + template constexpr inline type_found extract_error_type(...) { return {}; } + template constexpr inline type_found extract_exception_type(int /*unused*/) { return {}; } + template constexpr inline type_found extract_exception_type(...) { return {}; } + OUTCOME_TEMPLATE(class T, class U) + OUTCOME_TREQUIRES(OUTCOME_TPRED(OUTCOME_V2_NAMESPACE::detail::is_constructible)) + inline bool try_set_error(T &&e, U *result) + { + new(result) U(static_cast(e)); + return true; + } + template 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)) + inline void set_or_rethrow(T &e, U *result) { new(result) U(e); } + template inline void set_or_rethrow(T &e, ...) { rethrow_exception(e); } + template 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 struct outcome_promise_type + { + using container_type = typename Awaitable::container_type; + using result_set_type = std::conditional_t, fake_atomic>; + 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(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(e), {}); + // Try to set error code first + if(!detail::error_is_set(ec) || !detail::try_set_error(static_cast(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 self) noexcept + { + return self.promise().continuation ? self.promise().continuation : noop_coroutine(); + } +#else + void await_suspend(coroutine_handle self) + { + if(self.promise().continuation) + { + return self.promise().continuation.resume(); + } + } +#endif + }; + return awaiter{}; + } + }; + template struct outcome_promise_type + { + using container_type = void; + using result_set_type = std::conditional_t, fake_atomic>; + 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 self) noexcept + { + return self.promise().continuation ? self.promise().continuation : noop_coroutine(); + } +#else + void await_suspend(coroutine_handle self) + { + if(self.promise().continuation) + { + return self.promise().continuation.resume(); + } + } +#endif + }; + return awaiter{}; + } + }; + template + constexpr inline auto move_result_from_promise_if_not_void(outcome_promise_type &p) + { + return static_cast(p.result); + } + template + constexpr inline void move_result_from_promise_if_not_void(outcome_promise_type & /*unused*/) + { + } + template struct OUTCOME_NODISCARD awaitable + { + using container_type = Cont; + using promise_type = outcome_promise_type::value>; + coroutine_handle _h; + awaitable(awaitable &&o) noexcept + : _h(static_cast &&>(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::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 using eager = OUTCOME_V2_NAMESPACE::awaitables::detail::awaitable; +/*! AWAITING HUGO JSON CONVERSION TOOL +SIGNATURE NOT RECOGNISED +*/ +template using atomic_eager = OUTCOME_V2_NAMESPACE::awaitables::detail::awaitable; +/*! AWAITING HUGO JSON CONVERSION TOOL +SIGNATURE NOT RECOGNISED +*/ +template using lazy = OUTCOME_V2_NAMESPACE::awaitables::detail::awaitable; +/*! AWAITING HUGO JSON CONVERSION TOOL +SIGNATURE NOT RECOGNISED +*/ +template using atomic_lazy = OUTCOME_V2_NAMESPACE::awaitables::detail::awaitable; +} 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 (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 (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 (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 (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 (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 (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 (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 (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 success_type. Potential doc page: `success_type` +*/ +template 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>::value)) + constexpr explicit success_type(U &&v, uint16_t spare_storage = 0) + : _value(static_cast(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); } + constexpr const value_type &&value() const && { return static_cast(_value); } + constexpr uint16_t spare_storage() const { return _spare_storage; } +}; +template <> struct OUTCOME_NODISCARD success_type +{ + using value_type = void; + constexpr uint16_t spare_storage() const { return 0; } +}; +/*! Returns type sugar for implicitly constructing a `basic_result` with a successful state, +default constructing `T` if necessary. +*/ +inline constexpr success_type success() noexcept +{ + return success_type{}; +} +/*! Returns type sugar for implicitly constructing a `basic_result` with a successful state. +\effects Copies or moves the successful state supplied into the returned type sugar. +*/ +template inline constexpr success_type> success(T &&v, uint16_t spare_storage = 0) +{ + return success_type>{static_cast(v), spare_storage}; +} +/*! AWAITING HUGO JSON CONVERSION TOOL +type definition template failure_type. Potential doc page: `failure_type` +*/ +template 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 + constexpr explicit failure_type(U &&u, V &&v, uint16_t spare_storage = 0) + : _error(static_cast(u)) + , _exception(static_cast(v)) + , _have_error(true) + , _have_exception(true) + , _spare_storage(spare_storage) + { + } + template + constexpr explicit failure_type(in_place_type_t /*unused*/, U &&u, uint16_t spare_storage = 0, error_init_tag /*unused*/ = error_init_tag()) + : _error(static_cast(u)) + , _exception() + , _have_error(true) + , _spare_storage(spare_storage) + { + } + template + constexpr explicit failure_type(in_place_type_t /*unused*/, U &&u, uint16_t spare_storage = 0, + exception_init_tag /*unused*/ = exception_init_tag()) + : _error() + , _exception(static_cast(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); } + constexpr const error_type &&error() const && { return static_cast(_error); } + constexpr exception_type &exception() & { return _exception; } + constexpr const exception_type &exception() const & { return _exception; } + constexpr exception_type &&exception() && { return static_cast(_exception); } + constexpr const exception_type &&exception() const && { return static_cast(_exception); } + constexpr uint16_t spare_storage() const { return _spare_storage; } +}; +template struct OUTCOME_NODISCARD failure_type +{ + 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>::value)) + constexpr explicit failure_type(U &&u, uint16_t spare_storage = 0) + : _error(static_cast(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); } + constexpr const error_type &&error() const && { return static_cast(_error); } + constexpr uint16_t spare_storage() const { return _spare_storage; } +}; +template struct OUTCOME_NODISCARD failure_type +{ + 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>::value)) + constexpr explicit failure_type(V &&v, uint16_t spare_storage = 0) + : _exception(static_cast(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); } + constexpr const exception_type &&exception() const && { return static_cast(_exception); } + constexpr uint16_t spare_storage() const { return _spare_storage; } +}; +/*! AWAITING HUGO JSON CONVERSION TOOL +SIGNATURE NOT RECOGNISED +*/ +template inline constexpr failure_type> failure(EC &&v, uint16_t spare_storage = 0) +{ + return failure_type>{static_cast(v), spare_storage}; +} +/*! AWAITING HUGO JSON CONVERSION TOOL +SIGNATURE NOT RECOGNISED +*/ +template inline constexpr failure_type, std::decay_t> failure(EC &&v, E &&w, uint16_t spare_storage = 0) +{ + return failure_type, std::decay_t>{static_cast(v), static_cast(w), spare_storage}; +} +namespace detail +{ + template struct is_success_type + { + static constexpr bool value = false; + }; + template struct is_success_type> + { + static constexpr bool value = true; + }; + template struct is_failure_type + { + static constexpr bool value = false; + }; + template struct is_failure_type> + { + static constexpr bool value = true; + }; +} // namespace detail +/*! AWAITING HUGO JSON CONVERSION TOOL +SIGNATURE NOT RECOGNISED +*/ +template static constexpr bool is_success_type = detail::is_success_type>::value; +/*! AWAITING HUGO JSON CONVERSION TOOL +SIGNATURE NOT RECOGNISED +*/ +template static constexpr bool is_failure_type = detail::is_failure_type>::value; +OUTCOME_V2_NAMESPACE_END +#endif +/* Traits for Outcome +(C) 2018-2019 Niall Douglas (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 // + static constexpr bool type_can_be_used_in_basic_result = // + (!std::is_reference::value // + && !OUTCOME_V2_NAMESPACE::detail::is_in_place_type_t>::value // + && !is_success_type // + && !is_failure_type // + && !std::is_array::value // + && (std::is_void::value || (std::is_object::value // + && std::is_destructible::value)) // + ); + /*! AWAITING HUGO JSON CONVERSION TOOL +type definition is_error_type. Potential doc page: NOT FOUND +*/ + template 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 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 struct is_error_type_enum + { + static constexpr bool value = false; + }; + namespace detail + { + template using devoid = OUTCOME_V2_NAMESPACE::detail::devoid; + template std::add_rvalue_reference_t> declval() noexcept; + // From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4436.pdf + namespace detector_impl + { + template using void_t = void; + template class Op, class... Args> struct detector + { + static constexpr bool value = false; + using type = Default; + }; + template class Op, class... Args> struct detector>, Op, Args...> + { + static constexpr bool value = true; + using type = Op; + }; + } // namespace detector_impl + template