Errors.h#

Fully qualified name: carb/extras/Errors.h

File members: carb/extras/Errors.h

// SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
//
// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
// property and proprietary rights in and to this material, related
// documentation and any modifications thereto. Any use, reproduction,
// disclosure or distribution of this material and related documentation
// without an express license agreement from NVIDIA CORPORATION or
// its affiliates is strictly prohibited.

#pragma once

#include "../Defines.h"

#if CARB_PLATFORM_WINDOWS
#    include "../CarbWindows.h"
#endif

#include <cerrno>
#include <system_error>

namespace carb::extras
{

using ErrnoType = std::decay_t<decltype(errno)>;

namespace detail
{
class ScopedErrno
{
    ErrnoType m_err;

public:
    ScopedErrno() noexcept : m_err(errno)
    {
    }
    ~ScopedErrno()
    {
        errno = m_err;
    }
    ErrnoType get() const noexcept
    {
        return m_err;
    }
    operator ErrnoType() const noexcept
    {
        return get();
    }
};
#if CARB_PLATFORM_WINDOWS
class ScopedGetLastError
{
    DWORD m_gle;

public:
    ScopedGetLastError() noexcept : m_gle(::GetLastError())
    {
    }
    ~ScopedGetLastError()
    {
        ::SetLastError(m_gle);
    }
    DWORD get() const noexcept
    {
        return m_gle;
    }
    operator DWORD() const noexcept
    {
        return get();
    }
};
#endif
} // namespace detail

#if defined(DOXYGEN_BUILD) || CARB_PLATFORM_WINDOWS
using WinApiErrorType = unsigned long;
#endif

inline ErrnoType getLastErrno() noexcept
{
    return errno;
}

inline std::string convertErrnoToMessage(ErrnoType errorCode)
{
    if (errorCode == 0)
        return {};

    return std::generic_category().message(errorCode);
}

inline std::string getLastErrnoMessage(ErrnoType* out = nullptr)
{
    detail::ScopedErrno e;
    if (out)
        *out = e;
    return convertErrnoToMessage(e);
}

#if CARB_PLATFORM_WINDOWS || defined(DOXYGEN_BUILD)

inline WinApiErrorType getLastWinApiErrorCode() noexcept
{
    return ::GetLastError();
}

inline std::string convertWinApiErrorCodeToMessage(WinApiErrorType errorCode)
{
    if (errorCode == CARBWIN_ERROR_SUCCESS)
        return {};

    return std::system_category().message(errorCode);
}

inline std::string getLastWinApiErrorMessage()
{
    detail::ScopedGetLastError e;
    return convertWinApiErrorCodeToMessage(e);
}

#endif // #if CARB_PLATFORM_WINDOWS

} // namespace carb::extras