157 lines
5.7 KiB
C++
157 lines
5.7 KiB
C++
#pragma once
|
|
|
|
#include <boost/asio/awaitable.hpp>
|
|
#include <boost/system/errc.hpp>
|
|
#include <boost/system/error_code.hpp>
|
|
|
|
#if __has_include(<expected>)
|
|
#include <expected>
|
|
#elif __has_include(<tl/expected.hpp>)
|
|
#include <tl/expected.hpp>
|
|
#else
|
|
#error "No expected implementation available"
|
|
#endif
|
|
|
|
namespace ranczo {
|
|
|
|
#if __has_include(<expected>)
|
|
template < typename T >
|
|
using expected = std::expected< T, boost::system::error_code >;
|
|
|
|
template < typename T >
|
|
using unexpected = std::unexpected< T >;
|
|
|
|
#elif __has_include(<tl/expected.hpp>)
|
|
template < typename T >
|
|
using expected = tl::expected< T, boost::system::error_code >;
|
|
|
|
template < typename T >
|
|
using unexpected = tl::unexpected< T >;
|
|
|
|
#else
|
|
#error "No expected implementation available"
|
|
#endif
|
|
|
|
template < typename T >
|
|
using awaitable = boost::asio::awaitable< T >;
|
|
|
|
template < typename T >
|
|
using awaitable_expected = awaitable< expected< T > >;
|
|
|
|
using _void = expected< void >;
|
|
|
|
using ::boost::system::errc::make_error_code;
|
|
|
|
#define TRY(failable) \
|
|
({ \
|
|
auto _result = failable; \
|
|
if(!_result) \
|
|
return unexpected{_result.error()}; \
|
|
*_result; \
|
|
})
|
|
|
|
#define TRY_MSG(failable, ...) \
|
|
({ \
|
|
auto _result = (failable); \
|
|
if(!_result) { \
|
|
spdlog::error(__VA_ARGS__); \
|
|
return unexpected{_result.error()}; \
|
|
} \
|
|
*_result; \
|
|
})
|
|
|
|
#define TRY_TRANSFORM_ERROR(failable, transform) \
|
|
({ \
|
|
auto _result = (failable); \
|
|
if(!_result) \
|
|
return unexpected{transform(_result.error())}; \
|
|
*_result; \
|
|
})
|
|
|
|
#define CHECK(failable) \
|
|
do { \
|
|
auto _result = await(failable); \
|
|
if(!_result) \
|
|
return unexpected(_result.error()); \
|
|
} while(0)
|
|
|
|
#define CHECK_MSG(failable, ...) \
|
|
do { \
|
|
auto _result = await(failable); \
|
|
if(!_result) { \
|
|
spdlog::error(__VA_ARGS__); \
|
|
return unexpected{_result.error()}; \
|
|
} \
|
|
} while(0)
|
|
|
|
#define ASYNC_TRY(failable) \
|
|
({ \
|
|
auto _result = co_await (failable); \
|
|
if(!_result) \
|
|
co_return unexpected{_result.error()}; \
|
|
*_result; \
|
|
})
|
|
|
|
#define ASYNC_TRY_TRANSFORM_ERROR(failable, transform) \
|
|
({ \
|
|
auto _result = co_await (failable); \
|
|
if(!_result) \
|
|
co_return unexpected{transform(_result.error())}; \
|
|
*_result; \
|
|
})
|
|
|
|
#define ASYNC_TRY_MSG(failable, ...) \
|
|
({ \
|
|
auto _result = co_await (failable); \
|
|
if(!_result) { \
|
|
spdlog::error(__VA_ARGS__); \
|
|
co_return unexpected{_result.error()}; \
|
|
} \
|
|
*_result; \
|
|
})
|
|
|
|
#define ASYNC_CHECK(failable) \
|
|
do { \
|
|
auto _result = co_await (failable); \
|
|
if(!_result) \
|
|
co_return unexpected(_result.error()); \
|
|
} while(0)
|
|
|
|
#define ASYNC_CHECK_MSG(failable, ...) \
|
|
do { \
|
|
auto _result = co_await (failable); \
|
|
if(!_result) { \
|
|
spdlog::error(__VA_ARGS__); \
|
|
co_return unexpected{_result.error()}; \
|
|
} \
|
|
} while(0)
|
|
|
|
/// asserts that a _log objject is available, usefull for modules
|
|
#define ASYNC_CHECK_LOG(failable, ...) \
|
|
do { \
|
|
auto _result = co_await (failable); \
|
|
if(!_result) { \
|
|
_log.error(__VA_ARGS__); \
|
|
co_return unexpected{_result.error()}; \
|
|
} \
|
|
} while(0)
|
|
|
|
#define ASYNC_CHECK_TRANSFORM_ERROR(failable, transform) \
|
|
do { \
|
|
auto _result = co_await (failable); \
|
|
if(!_result) { \
|
|
co_return unexpected{transform(_result.error())}; \
|
|
} \
|
|
} while(0)
|
|
|
|
#define ASYNC_CHECK_TRANSFORM_ERR_LOG(failable, transform, ...) \
|
|
do { \
|
|
auto _result = co_await (failable); \
|
|
if(!_result) { \
|
|
_log.error(__VA_ARGS__); \
|
|
co_return unexpected{transform(_result.error())}; \
|
|
} \
|
|
} while(0)
|
|
|
|
} // namespace ranczo
|