/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: auResult.hpp Date: 2022-3-23 Author: Reece ***/ #pragma once #include "auCopyMoveUtils.hpp" #include "auHashUtils.hpp" template struct AuResult { bool success; T type; AuResult() : success(false) {} AuResult(bool success) : success(success) {} 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() T &GetResult() { return type; } constexpr const T *operator->() const { return &type; } constexpr T *operator->() { return &type; } const T &GetResult() const { return type; } void Complete() { this->success = true; } operator bool() const { return this->success; } bool has_value() const { return this->success; } const T &value() const { return type; } T &value() { return type; } };