mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
add: [imp] result<void>
This commit is contained in:
parent
649a5ee02a
commit
d17aeaae1e
@ -16,6 +16,7 @@
|
|||||||
LIBIMP_NAMESPACE_BEG_
|
LIBIMP_NAMESPACE_BEG_
|
||||||
|
|
||||||
using error_code_t = std::uint64_t;
|
using error_code_t = std::uint64_t;
|
||||||
|
constexpr error_code_t error_number_limit = error_code_t(-1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Serves as the base class for specific error category types.
|
* \brief Serves as the base class for specific error category types.
|
||||||
|
|||||||
@ -42,7 +42,7 @@ struct generic_traits {
|
|||||||
|
|
||||||
/// \brief Custom initialization.
|
/// \brief Custom initialization.
|
||||||
constexpr static void init_code(storage_t &code) noexcept {
|
constexpr static void init_code(storage_t &code) noexcept {
|
||||||
code = {0, -1/*make a default error code*/};
|
code = {0, error_number_limit/*make a default error code*/};
|
||||||
}
|
}
|
||||||
constexpr static void init_code(storage_t &code, T value, error_code const &ec) noexcept {
|
constexpr static void init_code(storage_t &code, T value, error_code const &ec) noexcept {
|
||||||
code = {value, ec};
|
code = {value, ec};
|
||||||
@ -66,12 +66,39 @@ struct generic_traits {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename ___>
|
||||||
|
struct default_traits<void, ___> {
|
||||||
|
/// \typedef Use the `error_code` as the storage type.
|
||||||
|
using storage_t = error_code;
|
||||||
|
|
||||||
|
/// \brief Custom initialization.
|
||||||
|
constexpr static void init_code(storage_t &code) noexcept {
|
||||||
|
code = error_number_limit/*make a default error code*/;
|
||||||
|
}
|
||||||
|
constexpr static void init_code(storage_t &code, error_code const &ec) noexcept {
|
||||||
|
code = ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Custom type data acquisition.
|
||||||
|
constexpr static bool get_ok(storage_t const &code) noexcept {
|
||||||
|
return !code;
|
||||||
|
}
|
||||||
|
constexpr static error_code get_error(storage_t const &code) noexcept {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Custom formatted output.
|
||||||
|
static std::string format(result<void> const &r) noexcept {
|
||||||
|
return fmt("error = ", r.error());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct default_traits<T, std::enable_if_t<std::is_integral<T>::value>> : generic_traits<T> {
|
struct default_traits<T, std::enable_if_t<std::is_integral<T>::value>> : generic_traits<T> {
|
||||||
/// \brief Custom initialization.
|
/// \brief Custom initialization.
|
||||||
constexpr static void init_code(storage_t &code, T value, bool ok) noexcept {
|
constexpr static void init_code(storage_t &code, T value, bool ok) noexcept {
|
||||||
code = {value, static_cast<error_code_t>(ok ? 0 :
|
code = {value, static_cast<error_code_t>(ok ? 0 :
|
||||||
((value == default_value()) ? -1 : value))};
|
((value == default_value()) ? error_number_limit : value))};
|
||||||
}
|
}
|
||||||
using generic_traits<T>::init_code;
|
using generic_traits<T>::init_code;
|
||||||
|
|
||||||
@ -146,6 +173,33 @@ public:
|
|||||||
friend bool operator!=(result const &lhs, result const &rhs) noexcept { return !(lhs == rhs); }
|
friend bool operator!=(result const &lhs, result const &rhs) noexcept { return !(lhs == rhs); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename TypeTraits>
|
||||||
|
class result<void, TypeTraits> {
|
||||||
|
public:
|
||||||
|
using type_traits_t = TypeTraits;
|
||||||
|
using storage_t = typename type_traits_t::storage_t;
|
||||||
|
|
||||||
|
private:
|
||||||
|
storage_t code_; ///< internal data
|
||||||
|
|
||||||
|
public:
|
||||||
|
template <typename... A,
|
||||||
|
typename = is_not_match<result, A...>,
|
||||||
|
typename = decltype(type_traits_t::init_code(std::declval<storage_t &>()
|
||||||
|
, std::declval<A>()...))>
|
||||||
|
result(A &&... args) noexcept {
|
||||||
|
type_traits_t::init_code(code_, std::forward<A>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok () const noexcept { return type_traits_t::get_ok (code_); }
|
||||||
|
error_code error() const noexcept { return type_traits_t::get_error(code_); }
|
||||||
|
|
||||||
|
explicit operator bool() const noexcept { return ok (); }
|
||||||
|
|
||||||
|
friend bool operator==(result const &lhs, result const &rhs) noexcept { return lhs.code_ == rhs.code_; }
|
||||||
|
friend bool operator!=(result const &lhs, result const &rhs) noexcept { return !(lhs == rhs); }
|
||||||
|
};
|
||||||
|
|
||||||
/// \brief Custom defined fmt_to method for imp::fmt
|
/// \brief Custom defined fmt_to method for imp::fmt
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
@ -154,5 +208,10 @@ bool tag_invoke(decltype(::LIBIMP::fmt_to), fmt_context &ctx, result<T, D> r) {
|
|||||||
return fmt_to(ctx, (r ? "succ" : "fail"), ", value = ", result<T, D>::type_traits_t::format(r));
|
return fmt_to(ctx, (r ? "succ" : "fail"), ", value = ", result<T, D>::type_traits_t::format(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename D>
|
||||||
|
bool tag_invoke(decltype(::LIBIMP::fmt_to), fmt_context &ctx, result<void, D> r) {
|
||||||
|
return fmt_to(ctx, (r ? "succ" : "fail"), ", ", result<void, D>::type_traits_t::format(r));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
LIBIMP_NAMESPACE_END_
|
LIBIMP_NAMESPACE_END_
|
||||||
|
|||||||
@ -17,7 +17,7 @@ public:
|
|||||||
return "generic";
|
return "generic";
|
||||||
}
|
}
|
||||||
std::string message(error_code_t const &r) const {
|
std::string message(error_code_t const &r) const {
|
||||||
if (r == error_code_t(-1)) {
|
if (r == error_number_limit) {
|
||||||
return "0, \"failure\"";
|
return "0, \"failure\"";
|
||||||
}
|
}
|
||||||
if (r == error_code_t(0)) {
|
if (r == error_code_t(0)) {
|
||||||
|
|||||||
@ -48,6 +48,16 @@ TEST(result, ok) {
|
|||||||
EXPECT_TRUE(ret.ok());
|
EXPECT_TRUE(ret.ok());
|
||||||
EXPECT_EQ(ret.value(), 4321);
|
EXPECT_EQ(ret.value(), 4321);
|
||||||
|
|
||||||
|
imp::result<void> r1;
|
||||||
|
EXPECT_FALSE(r1);
|
||||||
|
r1 = 0;
|
||||||
|
EXPECT_TRUE(r1);
|
||||||
|
r1 = {};
|
||||||
|
EXPECT_FALSE(r1);
|
||||||
|
r1 = 9999;
|
||||||
|
EXPECT_FALSE(r1);
|
||||||
|
EXPECT_EQ(r1.error(), 9999);
|
||||||
|
|
||||||
imp::result<int *> r2 {nullptr, 4321};
|
imp::result<int *> r2 {nullptr, 4321};
|
||||||
EXPECT_NE(r2, nullptr); // imp::result<int *>{nullptr}
|
EXPECT_NE(r2, nullptr); // imp::result<int *>{nullptr}
|
||||||
EXPECT_EQ(*r2, nullptr);
|
EXPECT_EQ(*r2, nullptr);
|
||||||
@ -102,4 +112,11 @@ TEST(result, fmt) {
|
|||||||
imp::result<std::int64_t> r1 {-123};
|
imp::result<std::int64_t> r1 {-123};
|
||||||
EXPECT_EQ(imp::fmt(r1), imp::fmt("succ, value = ", -123));
|
EXPECT_EQ(imp::fmt(r1), imp::fmt("succ, value = ", -123));
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
imp::result<void> r1;
|
||||||
|
EXPECT_EQ(imp::fmt(r1), "fail, error = [generic: 0, \"failure\"]");
|
||||||
|
r1 = 0;
|
||||||
|
EXPECT_TRUE(r1);
|
||||||
|
EXPECT_EQ(imp::fmt(r1), "succ, error = [generic: 0, \"success\"]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user