/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: auTryConstruct.hpp Date: 2022-3-25 Author: Reece ***/ #pragma once #define _AU_TRYCONTRUST_CHECKCODE AU_TEMPLATE_ENABLE_WHEN(AuIsBaseOf_v) template inline T AuTryConstruct(CtorCode_t &status, Args&& ... args) { if constexpr (AuIsConstructible_v) { status = CtorCode_t::Failed(); return T(AuReference(status), AuForward(args)...); } else if constexpr (AuIsConstructible_v) { status = CtorCode_t::Failed(); return T(AuForward(args)..., AuReference(status)); } else { try { status = CtorCode_t::Success(); return T(AuForward(args)...); } catch (...) { status = CtorCode_t::Failed(); return T(); } } } template inline CtorCode_t AuTryConstruct(T &ref, Args&& ... args) { CtorCode_t status; if constexpr (AuIsConstructible_v) { ref = AuMove(T(AuReference(status), AuForward(args)...)); return status; } else if constexpr (AuIsConstructible_v) { ref = AuMove(T(AuForward(args)..., AuReference(status))); return status; } else { try { ref = AuMove(T(AuForward(args)...)); return CtorCode_t::Success(); } catch (...) { ref = AuMove(T()); return CtorCode_t::Failed(); } } } template inline AuPair AuTryConstructPair(Args&& ... args) { CtorCode_t code; T object = AuTryConstruct(AuReference(code), AuForward(args)...); return AuMakePair(AuMove(code), AuMove(object)); } template inline T AuTryConstructWithDefault(CtorCode_t &status, T &&def, Args&& ... args) { if constexpr (AuIsConstructible_v) { status = CtorCode_t::Failed(); T returnValue = T(AuReference(status), AuForward(args)...); if (!status) { return AuMove(def); } return returnValue; } else if constexpr (AuIsConstructible_v) { status = CtorCode_t::Failed(); T returnValue = T(AuForward(args)..., AuReference(status)); if (!status) { return AuMove(def); } return returnValue; } else { try { status = CtorCode_t::Success(); return T(AuForward(args)...); } catch (...) { status = CtorCode_t::Failed(); return AuMove(def); } } } template inline AuPair AuTryConstructWithDefaultPair(T &&def, Args&& ... args) { CtorCode_t code; T object = AuTryConstructWithDefault(AuReference(code), AuForward(def), AuForward(args)...); return AuMakePair(AuMove(code), AuMove(object)); } #undef _AU_TRYCONTRUST_CHECKCODE