From dba4a884ca67d90f9173a1bdd41d76356a0b35eb Mon Sep 17 00:00:00 2001 From: Reece Wilson Date: Thu, 17 Nov 2022 02:28:23 +0000 Subject: [PATCH] [+] AuTryCall [+] AuTryCallPair [+] AuIsCallable [+] AuIsCallable_v [*] Improved AuResetMember --- Include/auROXTL/Objects/ResetMember.hpp | 15 ++++- Include/auROXTL/auResult.hpp | 11 +--- Include/auROXTL/auTemplateMeta.hpp | 28 ++++++++- Include/auROXTL/auTryCall.hpp | 38 +++++++++++++ Include/auROXTL/auTryCallUtils.hpp | 76 +++++++++++++++++++++++++ Include/auROXTLTypes.hpp | 1 + Include/auROXTLUtils.hpp | 1 + 7 files changed, 155 insertions(+), 15 deletions(-) create mode 100644 Include/auROXTL/auTryCall.hpp create mode 100644 Include/auROXTL/auTryCallUtils.hpp diff --git a/Include/auROXTL/Objects/ResetMember.hpp b/Include/auROXTL/Objects/ResetMember.hpp index 6e74cfd..96d96c8 100644 --- a/Include/auROXTL/Objects/ResetMember.hpp +++ b/Include/auROXTL/Objects/ResetMember.hpp @@ -7,10 +7,19 @@ ***/ #pragma once -template -static void AuResetMember(T &ref) +template +static void AuResetMember(T &ref, Args &&...args) { - ref = AuDecay_t(); + if constexpr (AuIsClass_v) + { + ref.~T(); + AuMemset(&ref, 0, sizeof(ref)); + new (&ref) T(AuForward(args)...); + } + else + { + ref = AuDecay_t(); + } } template diff --git a/Include/auROXTL/auResult.hpp b/Include/auROXTL/auResult.hpp index aae4bbb..dbd4223 100644 --- a/Include/auROXTL/auResult.hpp +++ b/Include/auROXTL/auResult.hpp @@ -25,16 +25,7 @@ struct AuResult AuResult(T &&value) : type(value), success(true) {} - // I could be pulling this out of my ass, but i'd assume with callee provided stack space being provided through arg0 in most abis, - // and with the callers binary originating from a file in which contains the T declaration, i'd assume it would be faster to chuck - // the return value in the callers' stack **and** access it by reference in the callee, rather than assigning a value using move - // constructors/assignment operators whenever the data is available. - // Feels like a landmine of accidental allocates: - // ...what is the default constructor doing in the caller? (hopefully nothing) - // ...does the object even support move semantics? (would AuResult(AuMove(t)) result in a copy no matter what?) - // - // generally recommend ::GetResult() - + // Forced return value optimization. T &GetResult() { return type; diff --git a/Include/auROXTL/auTemplateMeta.hpp b/Include/auROXTL/auTemplateMeta.hpp index 1bcd682..71c167c 100644 --- a/Include/auROXTL/auTemplateMeta.hpp +++ b/Include/auROXTL/auTemplateMeta.hpp @@ -68,6 +68,10 @@ namespace _audetail template auto TestIsBaseOf(int) -> decltype(TestIsPtrConvertible(static_cast(nullptr))); + + // yoinked: https://stackoverflow.com/a/40867906 + template static auto IsCallable(int) -> decltype((void)AuDeclVal()(AuDeclVal()...), AuTrueType {}); + template static AuFalseType IsCallable(...); } template @@ -253,7 +257,7 @@ template using AuAddRReference_t = typename AuAddRReference::type; template -AuAddRReference_t AuDeclVal(); +T &&AuDeclVal(); template struct AuAddConst @@ -353,4 +357,24 @@ template