7#include <system/details/value_init.h>
8#include <system/details/is_lambda.h>
13#ifndef INCLUDE_STD_OPTIONAL_EXPERIMENTAL
18# if CODEPORTING_CPP_STANDARD >= 17
21# if defined(__cpp_lib_optional)
22# define INCLUDE_STD_OPTIONAL_EXPERIMENTAL 0
25# elif defined(__cpp_lib_experimental_optional)
26# define INCLUDE_STD_OPTIONAL_EXPERIMENTAL 1
30# elif !defined(__has_include)
31# define INCLUDE_STD_OPTIONAL_EXPERIMENTAL 1
34# elif __has_include(<optional>)
40# if __has_include(<yvals_core.h>)
41# include <yvals_core.h>
44# if defined(_HAS_CXX17) && _HAS_CXX17
46# define INCLUDE_STD_OPTIONAL_EXPERIMENTAL 0
47# elif __has_include(<experimental/optional>)
48# define INCLUDE_STD_OPTIONAL_EXPERIMENTAL 1
53# ifndef INCLUDE_STD_OPTIONAL_EXPERIMENTAL
54# define INCLUDE_STD_OPTIONAL_EXPERIMENTAL 2
59# define INCLUDE_STD_OPTIONAL_EXPERIMENTAL 0
63# elif __has_include(<experimental/optional>)
64# define INCLUDE_STD_OPTIONAL_EXPERIMENTAL 1
68# define INCLUDE_STD_OPTIONAL_EXPERIMENTAL 2
72# elif CODEPORTING_CPP_STANDARD >= 14
75# if defined(__cpp_lib_experimental_optional)
76# define INCLUDE_STD_OPTIONAL_EXPERIMENTAL 1
77# elif !defined(__has_include)
78# define INCLUDE_STD_OPTIONAL_EXPERIMENTAL 1
81# elif __has_include(<experimental/optional>)
82# define INCLUDE_STD_OPTIONAL_EXPERIMENTAL 1
86# define INCLUDE_STD_OPTIONAL_EXPERIMENTAL 2
93# define INCLUDE_STD_OPTIONAL_EXPERIMENTAL 2
98# if INCLUDE_STD_OPTIONAL_EXPERIMENTAL == 1
100# include <experimental/optional>
105 using optional = experimental::optional<T>;
107 constexpr auto nullopt = std::experimental::nullopt;
111# elif INCLUDE_STD_OPTIONAL_EXPERIMENTAL == 2
113# include "details/optional.h"
118 using optional = experimental::optional<T>;
120 constexpr auto nullopt = std::experimental::nullopt;
149 FinallyGuard(std::exception_ptr& exception, F&& finallyBlock)
150 : mException(exception), mFinallyBlock(std::move(finallyBlock))
162 mException = std::current_exception();
169 std::exception_ptr& mException;
183FinallyGuard<F> MakeFinallyGuard(std::exception_ptr& exception, F&& f)
185 return FinallyGuard<F>(exception, std::move(f));
197template <
typename T,
typename F>
198void DoTryFinallyImpl(T&& tryBlock, F&& finallyBlock)
200 std::exception_ptr exception;
202 auto finally_guard = MakeFinallyGuard(exception, std::move(finallyBlock));
210 exception = std::current_exception();
216 std::rethrow_exception(exception);
236template<
typename T,
typename F>
237std::enable_if_t<Details::is_lambda_void_void<T>::value>
240 Details::DoTryFinallyImpl(tryBlock, finallyBlock);
258template<
typename T,
typename F>
259std::enable_if_t<Details::is_lambda_void_boolref<T>::value,
bool>
262 bool isReturned =
true;
263 Details::DoTryFinallyImpl([&]() { tryBlock(isReturned); }, finallyBlock);
282template<
typename T,
typename F>
283std::enable_if_t<Details::is_lambda_nonovoid_boolref<T>::value, std::optional<Details::ResultOf<T, bool&>>>
286 using ReturnValueType = Details::ResultOf<T, bool&>;
287 ReturnValueType returnValue;
289 bool isReturned =
true;
291 Details::DoTryFinallyImpl([&]() { returnValue = tryBlock(isReturned); }, finallyBlock);
293 return isReturned ? std::optional<ReturnValueType>(returnValue) : std::nullopt;
Definition: db_command.h:9
std::enable_if_t< Details::is_lambda_void_void< T >::value > DoTryFinally(T &&tryBlock, F &&finallyBlock)
The sigle function that emulates behavior of C#'s try[-catch]-finally statement. During translation o...
Definition: do_try_finally.h:238