460 lines
25 KiB
C++
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
|