/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: auTryCallUtils.hpp Date: 2022-11-16 Author: Reece ***/ #pragma once #define _AU_TRYCALL_CHECKCODE(X) AU_TEMPLATE_ENABLE_WHEN(AuIsBaseOf_v && !AuIsSame_v) template inline auto AuTryCall(Callable_t callable, CtorCode_t &status, Args&& ... args) { if constexpr (AuIsCallable_v) { status = CtorCode_t::Failed(); return callable(AuForward(args)..., AuReference(status)); } else { static_assert(AuIsCallable_v, "bad try-call prototype"); try { status = CtorCode_t::Success(); return callable(AuForward(args)...); } catch (...) { status = CtorCode_t::Failed(); return AuResultOf_t(); } } } template inline CtorCode_t AuTryCall(Callable_t callable, T &ref, Args&& ... args) { CtorCode_t status; if constexpr (AuIsCallable_v) { ref = callable(AuForward(args)..., AuReference(status)); return status; } else { try { ref = callable(AuForward(args)...); return CtorCode_t::Success(); } catch (...) { ref = AuMove(T()); if constexpr (AuIsSame_v) { return CtorCode_t::Catch(); } else { return CtorCode_t::Failed(); } } } } template inline auto AuTryCallPair(Callable_t callable, Args&& ... args) { CtorCode_t code; auto a = AuTryCall(callable, AuReference(code), AuForward(args)...); return AuMakePair(AuMove(code), a); } #undef _AU_TRYCALL_CHECKCODE