mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
add: [result] an additional status code can be returned on failure to return a pointer
This commit is contained in:
parent
9e170999a1
commit
e21da4fe2d
@ -9,10 +9,9 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#if !defined(LIBIMP_NAMESPACE)
|
||||
# define LIBIMP_NAMESPACE imp
|
||||
#endif
|
||||
#define LIBIMP_NAMESPACE_BEG_ namespace LIBIMP_NAMESPACE {
|
||||
#define LIBIMP_ imp
|
||||
#define LIBIMP_NAMESPACE_ LIBIMP_
|
||||
#define LIBIMP_NAMESPACE_BEG_ namespace LIBIMP_NAMESPACE_ {
|
||||
#define LIBIMP_NAMESPACE_END_ }
|
||||
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include "libimp/def.h"
|
||||
#include "libimp/detect_plat.h"
|
||||
#include "libimp/export.h"
|
||||
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
@ -26,7 +27,7 @@ class LIBIMP_EXPORT result_code {
|
||||
|
||||
public:
|
||||
result_code() noexcept;
|
||||
result_code(bool ok, std::uint64_t value = 0) noexcept;
|
||||
result_code(bool ok, std::uint64_t value = {}) noexcept;
|
||||
|
||||
std::uint64_t value() const noexcept;
|
||||
bool ok() const noexcept;
|
||||
@ -42,6 +43,11 @@ public:
|
||||
friend bool operator!=(result_code const &lhs, result_code const &rhs) noexcept;
|
||||
};
|
||||
|
||||
template <typename T,
|
||||
typename DefTraits = detail_result::default_traits<T>,
|
||||
typename = void>
|
||||
class result;
|
||||
|
||||
namespace detail_result {
|
||||
|
||||
template <typename T, typename = void>
|
||||
@ -57,8 +63,9 @@ struct default_traits<T, std::enable_if_t<std::is_integral<T>::value>> {
|
||||
static T cast_from_code(std::uint64_t code) noexcept {
|
||||
return static_cast<T>(code);
|
||||
}
|
||||
static T regularize(T value) noexcept {
|
||||
return value;
|
||||
template <typename Out>
|
||||
static auto format(result<T> const &r, Out &&out) noexcept {
|
||||
return format_to(out, "{}", *r);
|
||||
}
|
||||
};
|
||||
|
||||
@ -72,16 +79,19 @@ struct default_traits<T, std::enable_if_t<std::is_pointer<T>::value>> {
|
||||
static T cast_from_code(std::uint64_t code) noexcept {
|
||||
return reinterpret_cast<T>(code);
|
||||
}
|
||||
static void *regularize(T value) noexcept {
|
||||
return value;
|
||||
template <typename Out>
|
||||
static auto format(result<T> const &r, Out &&out) noexcept {
|
||||
if LIBIMP_LIKELY(r) {
|
||||
return format_to(out, "{}", static_cast<void *>(*r));
|
||||
}
|
||||
return format_to(out, "{}, code = {}", static_cast<void *>(*r), r.code());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail_result
|
||||
|
||||
template <typename T,
|
||||
typename DefTraits = detail_result::default_traits<T>>
|
||||
class result {
|
||||
template <typename T, typename DefTraits>
|
||||
class result<T, DefTraits, std::enable_if_t<std::is_integral<T>::value>> {
|
||||
|
||||
result_code code_;
|
||||
|
||||
@ -89,7 +99,7 @@ public:
|
||||
using default_traits_t = DefTraits;
|
||||
|
||||
result() noexcept = default;
|
||||
result(bool ok, T value = default_traits_t::value())
|
||||
result(bool ok, T value = default_traits_t::value()) noexcept
|
||||
: code_(ok, default_traits_t::cast_to_code(value)) {}
|
||||
|
||||
T value() const noexcept { return default_traits_t::cast_from_code(code_.value()); }
|
||||
@ -104,31 +114,58 @@ public:
|
||||
|
||||
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.code_ != rhs.code_; }
|
||||
};
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &o, result const &r) noexcept { return o << r.code_; }
|
||||
template <typename T, typename DefTraits>
|
||||
class result<T, DefTraits, std::enable_if_t<std::is_pointer<T>::value>> {
|
||||
|
||||
result_code code_;
|
||||
|
||||
public:
|
||||
using default_traits_t = DefTraits;
|
||||
|
||||
result(T value = default_traits_t::value()) noexcept
|
||||
: code_(default_traits_t::value() != value,
|
||||
default_traits_t::cast_to_code(value)) {}
|
||||
|
||||
result(std::nullptr_t, std::uint64_t code) noexcept
|
||||
: code_(false, code) {}
|
||||
|
||||
T value() const noexcept { return code_.ok() ? default_traits_t::cast_from_code(code_.value()) : nullptr; }
|
||||
bool ok() const noexcept { return code_.ok(); }
|
||||
std::uint64_t code() const noexcept { return code_.value(); }
|
||||
|
||||
T operator*() const noexcept {
|
||||
return value();
|
||||
}
|
||||
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.code_ != rhs.code_; }
|
||||
};
|
||||
|
||||
LIBIMP_NAMESPACE_END_
|
||||
|
||||
template <typename T>
|
||||
struct fmt::formatter<::LIBIMP_NAMESPACE::result<T>> {
|
||||
template <typename T, typename D>
|
||||
struct fmt::formatter<::LIBIMP_::result<T, D>> {
|
||||
constexpr auto parse(format_parse_context& ctx) {
|
||||
return ctx.end();
|
||||
}
|
||||
|
||||
template <typename FormatContext>
|
||||
auto format(::LIBIMP_NAMESPACE::result<T> r, FormatContext &ctx) {
|
||||
return format_to(ctx.out(), "[{}, value = {}]",
|
||||
(r ? "succ" : "fail"),
|
||||
::LIBIMP_NAMESPACE::result<T>::default_traits_t::regularize(*r));
|
||||
auto format(::LIBIMP_::result<T, D> r, FormatContext &ctx) {
|
||||
return format_to(::LIBIMP_::result<T, D>::default_traits_t::format(r,
|
||||
format_to(ctx.out(), "[{}, value = ", r ? "succ" : "fail")), "]");
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct fmt::formatter<::LIBIMP_NAMESPACE::result_code>
|
||||
: formatter<::LIBIMP_NAMESPACE::result<std::uint64_t>> {
|
||||
struct fmt::formatter<::LIBIMP_::result_code>
|
||||
: formatter<::LIBIMP_::result<std::uint64_t>> {
|
||||
template <typename FormatContext>
|
||||
auto format(::LIBIMP_NAMESPACE::result_code r, FormatContext &ctx) {
|
||||
auto format(::LIBIMP_::result_code r, FormatContext &ctx) {
|
||||
return format_to(ctx.out(), "[{}, value = {}]", (r ? "succ" : "fail"), *r);
|
||||
}
|
||||
};
|
||||
|
||||
@ -9,14 +9,21 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#if !defined(LIBIPC_NAMESPACE)
|
||||
# define LIBIPC_NAMESPACE ipc
|
||||
#endif
|
||||
#define LIBIPC_NAMESPACE_BEG_ namespace LIBIPC_NAMESPACE {
|
||||
#define LIBIPC_ ipc
|
||||
#define LIBIPC_NAMESPACE_ LIBIPC_
|
||||
#define LIBIPC_NAMESPACE_BEG_ namespace LIBIPC_NAMESPACE_ {
|
||||
#define LIBIPC_NAMESPACE_END_ }
|
||||
|
||||
LIBIPC_NAMESPACE_BEG_
|
||||
|
||||
// constants
|
||||
|
||||
struct prot {
|
||||
enum : std::uint32_t {
|
||||
none = 0x00,
|
||||
read = 0x01,
|
||||
write = 0x02,
|
||||
};
|
||||
};
|
||||
|
||||
LIBIPC_NAMESPACE_END_
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
#include "libimp/export.h"
|
||||
#include "libimp/result.h"
|
||||
|
||||
#include "libipc/def.h"
|
||||
|
||||
LIBIPC_NAMESPACE_BEG_
|
||||
@ -18,6 +19,6 @@ using mmap_t = mmap_handle *;
|
||||
/**
|
||||
* @brief Creates a new mapping in the virtual address space of the calling process.
|
||||
*/
|
||||
LIBIMP_EXPORT mmap_t mmap_open();
|
||||
LIBIMP_EXPORT ::LIBIMP_::result<mmap_t> mmap_open();
|
||||
|
||||
LIBIPC_NAMESPACE_END_
|
||||
|
||||
@ -68,10 +68,14 @@ TEST(result, fmt) {
|
||||
{
|
||||
imp::result<int> r1 {false, -123};
|
||||
EXPECT_EQ(fmt::format("{}", r1), fmt::format("[fail, value = {}]", -123));
|
||||
imp::result<void *> r2 {true, &r1};
|
||||
imp::result<void *> r2 {&r1};
|
||||
EXPECT_EQ(fmt::format("{}", r2), fmt::format("[succ, value = {}]", (void *)&r1));
|
||||
int aaa {};
|
||||
imp::result<int *> r3 {false, &aaa};
|
||||
EXPECT_EQ(fmt::format("{}", r3), fmt::format("[fail, value = {}]", (void *)&aaa));
|
||||
imp::result<int *> r3 {&aaa};
|
||||
EXPECT_EQ(fmt::format("{}", r3), fmt::format("[succ, value = {}]", (void *)&aaa));
|
||||
imp::result<int *> r4 {nullptr};
|
||||
EXPECT_EQ(fmt::format("{}", r4), fmt::format("[fail, value = {}, code = 0]", nullptr));
|
||||
r4 = {nullptr, 1234};
|
||||
EXPECT_EQ(fmt::format("{}", r4), fmt::format("[fail, value = {}, code = 1234]", nullptr));
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user