AuROXTL/Include/auROXTL/auTryConstructUtils.hpp
2022-04-01 05:06:53 +01:00

94 lines
2.8 KiB
C++

/***
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<AuCtorErrorTag, CtorCode_t>)
template <class T, class CtorCode_t = AuCtorCode_t, typename ... Args, _AU_TRYCONTRUST_CHECKCODE>
inline T AuTryConstruct(CtorCode_t &status, Args&& ... args)
{
if constexpr (AuIsConstructible_v<T, CtorCode_t &, Args ...>)
{
status = CtorCode_t::Failed();
return T(AuReference(status), AuForward<Args>(args)...);
}
else if constexpr (AuIsConstructible_v<T, Args ..., CtorCode_t &>)
{
status = CtorCode_t::Failed();
return T(AuForward<Args>(args)..., AuReference(status));
}
else
{
try
{
status = CtorCode_t::Success();
return T(AuForward<Args>(args)...);
}
catch (...)
{
status = CtorCode_t::Failed();
return T();
}
}
}
template <class T, class CtorCode_t = AuCtorCode_t, typename ... Args, _AU_TRYCONTRUST_CHECKCODE>
inline AuPair<CtorCode_t, T> AuTryConstructPair(Args&& ... args)
{
CtorCode_t code;
T object = AuTryConstruct<T, CtorCode_t, Args...>(AuReference(code), AuForward<Args>(args)...);
return AuMakePair(AuMove(code), AuMove(object));
}
template <class T, class CtorCode_t = AuCtorCode_t, typename ... Args, _AU_TRYCONTRUST_CHECKCODE>
inline T AuTryConstructWithDefault(CtorCode_t &status, T &&def, Args&& ... args)
{
if constexpr (AuIsConstructible_v<T, CtorCode_t &, Args ...>)
{
status = CtorCode_t::Failed();
T returnValue = T(AuReference(status), AuForward<Args>(args)...);
if (!status)
{
return AuMove(def);
}
return returnValue;
}
else if constexpr (AuIsConstructible_v<T, Args ..., CtorCode_t &>)
{
status = CtorCode_t::Failed();
T returnValue = T(AuForward<Args>(args)..., AuReference(status));
if (!status)
{
return AuMove(def);
}
return returnValue;
}
else
{
try
{
status = CtorCode_t::Success();
return T(AuForward<Args>(args)...);
}
catch (...)
{
status = CtorCode_t::Failed();
return AuMove(def);
}
}
}
template <class T, class CtorCode_t = AuCtorCode_t, typename ... Args, _AU_TRYCONTRUST_CHECKCODE>
inline AuPair<CtorCode_t, T> AuTryConstructWithDefaultPair(T &&def, Args&& ... args)
{
CtorCode_t code;
T object = AuTryConstructWithDefault<T, CtorCode_t, Args...>(AuReference(code), AuFoward(def), AuForward<Args>(args)...);
return AuMakePair(AuMove(code), AuMove(object));
}
#undef _AU_TRYCONTRUST_CHECKCODE