Files
CPP_Core/psc_global_include/error.hpp
T
2026-06-16 10:56:40 +08:00

460 lines
25 KiB
C++

#pragma once
#ifndef PSC_TRIPLE_API_HPP_INCLUDED
#define PSC_TRIPLE_API_HPP_INCLUDED
#include "expected.h"
#include <system_error>
#include <utility>
#ifndef PSC_TRIPLE_API_INLINE
#define PSC_TRIPLE_API_INLINE
#endif
#ifndef PSC_TRIPLE_API_NODISCARD
#define PSC_TRIPLE_API_NODISCARD [[nodiscard]]
#endif
#ifndef PSC_TRIPLE_API_ERROR_TEXT
#define PSC_TRIPLE_API_ERROR_TEXT(NAME) #NAME " failed"
#endif
#define PSC_DETAIL_COMMA() ,
#define PSC_DETAIL_PARAM_DECL(TYPE, NAME) TYPE NAME
#define PSC_DETAIL_PARAM_NAME(TYPE, NAME) NAME
#define PSC_PARAM_DECLS(PARAMS) \
PARAMS(PSC_DETAIL_PARAM_DECL, PSC_DETAIL_COMMA)
#define PSC_PARAM_NAMES(PARAMS) \
PARAMS(PSC_DETAIL_PARAM_NAME, PSC_DETAIL_COMMA)
#define PSC_DETAIL_CAT_IMPL(A, B) A##B
#define PSC_DETAIL_CAT(A, B) PSC_DETAIL_CAT_IMPL(A, B)
// 防止 NAME 是函数宏时在声明/定义处被展开
#define PSC_DETAIL_FUNC(NAME) (NAME)
// expected 版本默认名:try_NAME
#ifndef PSC_TRIPLE_API_EXPECTED_NAME
#define PSC_TRIPLE_API_EXPECTED_NAME(NAME) PSC_DETAIL_CAT(try_, NAME)
#endif
// error_code 版本默认名:NAME_ec
#ifndef PSC_TRIPLE_API_ERROR_CODE_NAME
#define PSC_TRIPLE_API_ERROR_CODE_NAME(NAME) PSC_DETAIL_CAT(NAME, _ec)
#endif
#define PSC_DETAIL_EXPECTED_FUNC(NAME) \
PSC_DETAIL_FUNC(PSC_TRIPLE_API_EXPECTED_NAME(NAME))
#define PSC_DETAIL_ERROR_CODE_FUNC(NAME) \
PSC_DETAIL_FUNC(PSC_TRIPLE_API_ERROR_CODE_NAME(NAME))
// 支持 CORE 是宏函数
#define PSC_DETAIL_CALL_CORE(CORE, ...) \
CORE(__VA_ARGS__)
namespace Psc::detail {
template <typename Ret, typename Fn>
Ret triple_api_throwing(Fn&& fn, const char* name)
{
Ret out{};
std::error_code ec;
if (!std::forward<Fn>(fn)(out, ec))
{
throw std::system_error(ec, name);
}
return std::move(out);
}
template <typename Ret, typename Fn>
expected<Ret, std::error_code> triple_api_expected(Fn&& fn) noexcept
{
Ret out{};
std::error_code ec;
if (!std::forward<Fn>(fn)(out, ec))
{
return unexpected<std::error_code>(ec);
}
return std::move(out);
}
template <typename Fn>
void triple_api_throwing_void(Fn&& fn, const char* name)
{
std::error_code ec;
if (!std::forward<Fn>(fn)(ec))
{
throw std::system_error(ec, name);
}
}
template <typename Fn>
expected<void, std::error_code> triple_api_expected_void(Fn&& fn) noexcept
{
std::error_code ec;
if (!std::forward<Fn>(fn)(ec))
{
return unexpected<std::error_code>(ec);
}
return {};
}
}
// ================================================================
// 非 void 返回值版本
//
// 生成:
// RET NAME(params...);
// std::expected<RET, std::error_code> try_NAME(params...) noexcept;
// bool NAME_ec(params..., RET& out, std::error_code& ec) noexcept;
//
// NAME(...) 是异常版本。
// NAME_ec(...) 是唯一核心实现。
// ================================================================
#define PSC_DECLARE_TRIPLE_API(RET, NAME, PARAMS) \
PSC_TRIPLE_API_NODISCARD \
RET PSC_DETAIL_FUNC(NAME)(PSC_PARAM_DECLS(PARAMS)); \
\
PSC_TRIPLE_API_NODISCARD \
Psc::expected<RET, std::error_code> \
PSC_DETAIL_EXPECTED_FUNC(NAME)(PSC_PARAM_DECLS(PARAMS)) noexcept; \
\
PSC_TRIPLE_API_NODISCARD \
bool PSC_DETAIL_ERROR_CODE_FUNC(NAME)( \
PSC_PARAM_DECLS(PARAMS), \
RET& out, \
std::error_code& ec \
) noexcept
#define PSC_DEFINE_TRIPLE_API_FROM_BOOL(RET, NAME, PARAMS) \
PSC_TRIPLE_API_INLINE \
RET PSC_DETAIL_FUNC(NAME)(PSC_PARAM_DECLS(PARAMS)) \
{ \
RET out{}; \
std::error_code ec; \
\
if (!PSC_DETAIL_ERROR_CODE_FUNC(NAME)( \
PSC_PARAM_NAMES(PARAMS), \
out, \
ec \
)) \
{ \
throw std::system_error(ec, PSC_TRIPLE_API_ERROR_TEXT(NAME)); \
} \
\
return out; \
} \
\
PSC_TRIPLE_API_INLINE \
Psc::expected<RET, std::error_code> \
PSC_DETAIL_EXPECTED_FUNC(NAME)(PSC_PARAM_DECLS(PARAMS)) noexcept \
{ \
RET out{}; \
std::error_code ec; \
\
if (!PSC_DETAIL_ERROR_CODE_FUNC(NAME)( \
PSC_PARAM_NAMES(PARAMS), \
out, \
ec \
)) \
{ \
return Psc::unexpected<std::error_code>(ec); \
} \
\
return out; \
}
#define PSC_DEFINE_TRIPLE_API_FROM_BOOL_CORE(RET, NAME, PARAMS, CORE) \
PSC_TRIPLE_API_INLINE \
bool PSC_DETAIL_ERROR_CODE_FUNC(NAME)( \
PSC_PARAM_DECLS(PARAMS), \
RET& out, \
std::error_code& ec \
) noexcept \
{ \
return PSC_DETAIL_CALL_CORE( \
CORE, \
PSC_PARAM_NAMES(PARAMS), \
out, \
ec \
); \
} \
\
PSC_DEFINE_TRIPLE_API_FROM_BOOL(RET, NAME, PARAMS)
// ================================================================
// 非 void,零参数版本
// ================================================================
#define PSC_DECLARE_TRIPLE_API_0(RET, NAME) \
PSC_TRIPLE_API_NODISCARD \
RET PSC_DETAIL_FUNC(NAME)(); \
\
PSC_TRIPLE_API_NODISCARD \
Psc::expected<RET, std::error_code> \
PSC_DETAIL_EXPECTED_FUNC(NAME)() noexcept; \
\
PSC_TRIPLE_API_NODISCARD \
bool PSC_DETAIL_ERROR_CODE_FUNC(NAME)( \
RET& out, \
std::error_code& ec \
) noexcept
#define PSC_DEFINE_TRIPLE_API_FROM_BOOL_0(RET, NAME) \
PSC_TRIPLE_API_INLINE \
RET PSC_DETAIL_FUNC(NAME)() \
{ \
RET out{}; \
std::error_code ec; \
\
if (!PSC_DETAIL_ERROR_CODE_FUNC(NAME)(out, ec)) \
{ \
throw std::system_error(ec, PSC_TRIPLE_API_ERROR_TEXT(NAME)); \
} \
\
return out; \
} \
\
PSC_TRIPLE_API_INLINE \
Psc::expected<RET, std::error_code> \
PSC_DETAIL_EXPECTED_FUNC(NAME)() noexcept \
{ \
RET out{}; \
std::error_code ec; \
\
if (!PSC_DETAIL_ERROR_CODE_FUNC(NAME)(out, ec)) \
{ \
return Psc::unexpected<std::error_code>(ec); \
} \
\
return out; \
}
#define PSC_DEFINE_TRIPLE_API_FROM_BOOL_CORE_0(RET, NAME, CORE) \
PSC_TRIPLE_API_INLINE \
bool PSC_DETAIL_ERROR_CODE_FUNC(NAME)( \
RET& out, \
std::error_code& ec \
) noexcept \
{ \
return PSC_DETAIL_CALL_CORE(CORE, out, ec); \
} \
\
PSC_DEFINE_TRIPLE_API_FROM_BOOL_0(RET, NAME)
// ================================================================
// void 返回值版本
//
// 生成:
// void NAME(params...);
// std::expected<void, std::error_code> try_NAME(params...) noexcept;
// bool NAME_ec(params..., std::error_code& ec) noexcept;
//
// NAME(...) 是异常版本。
// NAME_ec(...) 是唯一核心实现。
// ================================================================
#define PSC_DECLARE_TRIPLE_API_VOID(NAME, PARAMS) \
void PSC_DETAIL_FUNC(NAME)(PSC_PARAM_DECLS(PARAMS)); \
\
PSC_TRIPLE_API_NODISCARD \
Psc::expected<void, std::error_code> \
PSC_DETAIL_EXPECTED_FUNC(NAME)(PSC_PARAM_DECLS(PARAMS)) noexcept; \
\
PSC_TRIPLE_API_NODISCARD \
bool PSC_DETAIL_ERROR_CODE_FUNC(NAME)( \
PSC_PARAM_DECLS(PARAMS), \
std::error_code& ec \
) noexcept
#define PSC_DEFINE_TRIPLE_API_VOID_FROM_BOOL(NAME, PARAMS) \
PSC_TRIPLE_API_INLINE \
void PSC_DETAIL_FUNC(NAME)(PSC_PARAM_DECLS(PARAMS)) \
{ \
std::error_code ec; \
\
if (!PSC_DETAIL_ERROR_CODE_FUNC(NAME)( \
PSC_PARAM_NAMES(PARAMS), \
ec \
)) \
{ \
throw std::system_error(ec, PSC_TRIPLE_API_ERROR_TEXT(NAME)); \
} \
} \
\
PSC_TRIPLE_API_INLINE \
Psc::expected<void, std::error_code> \
PSC_DETAIL_EXPECTED_FUNC(NAME)(PSC_PARAM_DECLS(PARAMS)) noexcept \
{ \
std::error_code ec; \
\
if (!PSC_DETAIL_ERROR_CODE_FUNC(NAME)( \
PSC_PARAM_NAMES(PARAMS), \
ec \
)) \
{ \
return Psc::unexpected<std::error_code>(ec); \
} \
\
return {}; \
}
#define PSC_DEFINE_TRIPLE_API_VOID_FROM_BOOL_CORE(NAME, PARAMS, CORE) \
PSC_TRIPLE_API_INLINE \
bool PSC_DETAIL_ERROR_CODE_FUNC(NAME)( \
PSC_PARAM_DECLS(PARAMS), \
std::error_code& ec \
) noexcept \
{ \
return PSC_DETAIL_CALL_CORE( \
CORE, \
PSC_PARAM_NAMES(PARAMS), \
ec \
); \
} \
\
PSC_DEFINE_TRIPLE_API_VOID_FROM_BOOL(NAME, PARAMS)
// ================================================================
// void,零参数版本
// ================================================================
#define PSC_DECLARE_TRIPLE_API_VOID_0(NAME) \
void PSC_DETAIL_FUNC(NAME)(); \
\
PSC_TRIPLE_API_NODISCARD \
Psc::expected<void, std::error_code> \
PSC_DETAIL_EXPECTED_FUNC(NAME)() noexcept; \
\
PSC_TRIPLE_API_NODISCARD \
bool PSC_DETAIL_ERROR_CODE_FUNC(NAME)(std::error_code& ec) noexcept
#define PSC_DEFINE_TRIPLE_API_VOID_FROM_BOOL_0(NAME) \
PSC_TRIPLE_API_INLINE \
void PSC_DETAIL_FUNC(NAME)() \
{ \
std::error_code ec; \
\
if (!PSC_DETAIL_ERROR_CODE_FUNC(NAME)(ec)) \
{ \
throw std::system_error(ec, PSC_TRIPLE_API_ERROR_TEXT(NAME)); \
} \
} \
\
PSC_TRIPLE_API_INLINE \
Psc::expected<void, std::error_code> \
PSC_DETAIL_EXPECTED_FUNC(NAME)() noexcept \
{ \
std::error_code ec; \
\
if (!PSC_DETAIL_ERROR_CODE_FUNC(NAME)(ec)) \
{ \
return Psc::unexpected<std::error_code>(ec); \
} \
\
return {}; \
}
#define PSC_DEFINE_TRIPLE_API_VOID_FROM_BOOL_CORE_0(NAME, CORE) \
PSC_TRIPLE_API_INLINE \
bool PSC_DETAIL_ERROR_CODE_FUNC(NAME)(std::error_code& ec) noexcept \
{ \
return PSC_DETAIL_CALL_CORE(CORE, ec); \
} \
\
PSC_DEFINE_TRIPLE_API_VOID_FROM_BOOL_0(NAME)
// ================================================================
// const member function variants
// ================================================================
#define PSC_DECLARE_TRIPLE_API_CONST_METHOD(RET, NAME, PARAMS) \
PSC_TRIPLE_API_NODISCARD \
RET PSC_DETAIL_FUNC(NAME)(PSC_PARAM_DECLS(PARAMS)) const; \
\
PSC_TRIPLE_API_NODISCARD \
Psc::expected<RET, std::error_code> \
PSC_DETAIL_EXPECTED_FUNC(NAME)(PSC_PARAM_DECLS(PARAMS)) const noexcept; \
\
PSC_TRIPLE_API_NODISCARD \
bool PSC_DETAIL_ERROR_CODE_FUNC(NAME)( \
PSC_PARAM_DECLS(PARAMS), \
RET& out, \
std::error_code& ec \
) const noexcept
#define PSC_DEFINE_TRIPLE_API_CONST_METHOD_FROM_BOOL(RET, CLASS, NAME, PARAMS) \
PSC_TRIPLE_API_INLINE \
RET CLASS::NAME(PSC_PARAM_DECLS(PARAMS)) const \
{ \
RET out{}; \
std::error_code ec; \
if (!PSC_TRIPLE_API_ERROR_CODE_NAME(NAME)( \
PSC_PARAM_NAMES(PARAMS), out, ec)) \
{ \
throw std::system_error(ec, PSC_TRIPLE_API_ERROR_TEXT(NAME)); \
} \
return out; \
} \
\
PSC_TRIPLE_API_INLINE \
Psc::expected<RET, std::error_code> \
CLASS::PSC_TRIPLE_API_EXPECTED_NAME(NAME)( \
PSC_PARAM_DECLS(PARAMS)) const noexcept \
{ \
RET out{}; \
std::error_code ec; \
if (!PSC_TRIPLE_API_ERROR_CODE_NAME(NAME)( \
PSC_PARAM_NAMES(PARAMS), out, ec)) \
{ \
return Psc::unexpected<std::error_code>(ec); \
} \
return out; \
}
#define PSC_DECLARE_TRIPLE_API_CONST_METHOD_0(RET, NAME) \
PSC_TRIPLE_API_NODISCARD \
RET PSC_DETAIL_FUNC(NAME)() const; \
\
PSC_TRIPLE_API_NODISCARD \
Psc::expected<RET, std::error_code> \
PSC_DETAIL_EXPECTED_FUNC(NAME)() const noexcept; \
\
PSC_TRIPLE_API_NODISCARD \
bool PSC_DETAIL_ERROR_CODE_FUNC(NAME)( \
RET& out, \
std::error_code& ec \
) const noexcept
#define PSC_DEFINE_TRIPLE_API_CONST_METHOD_FROM_BOOL_0(RET, CLASS, NAME) \
PSC_TRIPLE_API_INLINE \
RET CLASS::NAME() const \
{ \
RET out{}; \
std::error_code ec; \
if (!PSC_TRIPLE_API_ERROR_CODE_NAME(NAME)(out, ec)) \
{ \
throw std::system_error(ec, PSC_TRIPLE_API_ERROR_TEXT(NAME)); \
} \
return out; \
} \
\
PSC_TRIPLE_API_INLINE \
Psc::expected<RET, std::error_code> \
CLASS::PSC_TRIPLE_API_EXPECTED_NAME(NAME)() const noexcept \
{ \
RET out{}; \
std::error_code ec; \
if (!PSC_TRIPLE_API_ERROR_CODE_NAME(NAME)(out, ec)) \
{ \
return Psc::unexpected<std::error_code>(ec); \
} \
return out; \
}
#endif // PSC_TRIPLE_API_HPP_INCLUDED