AuROXTL/Include/auROXTL/auTryConstructUtils.hpp
2024-02-16 10:28:14 +00:00

123 lines
3.6 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 CtorCode_t AuTryConstruct(T &ref, Args&& ... args)
{
CtorCode_t status;
if constexpr (AuIsConstructible_v<T, CtorCode_t &, Args ...>)
{
ref = AuMove(T(AuReference(status), AuForward<Args>(args)...));
return status;
}
else if constexpr (AuIsConstructible_v<T, Args ..., CtorCode_t &>)
{
ref = AuMove(T(AuForward<Args>(args)..., AuReference(status)));
return status;
}
else
{
try
{
ref = AuMove(T(AuForward<Args>(args)...));
return CtorCode_t::Success();
}
catch (...)
{
ref = AuMove(T());
return CtorCode_t::Failed();
}
}
}
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), AuForward(def), AuForward<Args>(args)...);
return AuMakePair(AuMove(code), AuMove(object));
}
#undef _AU_TRYCONTRUST_CHECKCODE