omni/core/ResultError.h

File members: omni/core/ResultError.h

// Copyright (c) 2021-2023, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//

#pragma once

#include "../../carb/extras/Debugging.h"
#include "Assert.h"
#include "IObject.h"

#include <stdexcept>
#include <string>

namespace omni
{
namespace core
{

inline const char* resultToString(Result result)
{
#ifndef DOXYGEN_BUILD
#    define OMNI_RESULT_CODE_GEN_RESULT_TO_STRING_CASE(symbol_, snek_symbol_, message_)                                \
        case kResult##symbol_:                                                                                         \
            return message_;
#endif

    switch (result)
    {
        OMNI_RESULT_CODE_LIST(OMNI_RESULT_CODE_GEN_RESULT_TO_STRING_CASE)
        default:
            return "unknown error";
    }
#undef OMNI_RESULT_CODE_GEN_RESULT_TO_STRING_CASE
}

class ResultError : public std::exception
{
public:
    ResultError(Result result) : m_result{ result }
    {
    }

    ResultError(Result result, std::string msg) : m_result{ result }, m_msg(std::move(msg))
    {
    }

    virtual const char* what() const noexcept override
    {
        if (m_msg.empty())
        {
            return resultToString(m_result);
        }
        else
        {
            return m_msg.c_str();
        }
    }

    Result getResult() const noexcept
    {
        return m_result;
    }

private:
    Result m_result;
    std::string m_msg;
};

} // namespace core
} // namespace omni

#if CARB_DEBUG && !defined(DOXYGEN_BUILD)
#    define OMNI_RETURN_ERROR(e_)                                                                                      \
        carb::extras::debuggerBreak();                                                                                 \
        return e_;
#else
#    define OMNI_RETURN_ERROR(e_) return e_
#endif

#define OMNI_CATCH_ABI_EXCEPTION()                                                                                     \
    catch (const omni::core::ResultError& e_)                                                                          \
    {                                                                                                                  \
        OMNI_RETURN_ERROR(e_.getResult());                                                                             \
    }                                                                                                                  \
    catch (...)                                                                                                        \
    {                                                                                                                  \
        OMNI_RETURN_ERROR(omni::core::kResultFail);                                                                    \
    }

#define OMNI_THROW_IF_FAILED(expr_)                                                                                    \
    do                                                                                                                 \
    {                                                                                                                  \
        omni::core::Result result_ = (expr_);                                                                          \
        if (OMNI_FAILED(result_))                                                                                      \
        {                                                                                                              \
            throw omni::core::ResultError{ result_ };                                                                  \
        }                                                                                                              \
    } while (0)

#define OMNI_RETURN_IF_ARG_NULL(expr_)                                                                                 \
    do                                                                                                                 \
    {                                                                                                                  \
        if (nullptr == expr_)                                                                                          \
        {                                                                                                              \
            OMNI_RETURN_ERROR(omni::core::kResultInvalidArgument);                                                     \
        }                                                                                                              \
    } while (0)

#define OMNI_THROW_IF_ARG_NULL(ptr_)                                                                                   \
    do                                                                                                                 \
    {                                                                                                                  \
        if (!ptr_)                                                                                                     \
        {                                                                                                              \
            auto constexpr const msg_ = __FILE__ ":" CARB_STRINGIFY(__LINE__) /*": "  CARB_PRETTY_FUNCTION*/           \
                ": argument '" #ptr_ "' must not be nullptr";                                                          \
            throw omni::core::ResultError(omni::core::kResultInvalidArgument, msg_);                                   \
        }                                                                                                              \
    } while (0)