mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06: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 <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#if !defined(LIBIMP_NAMESPACE)
|
#define LIBIMP_ imp
|
||||||
# define LIBIMP_NAMESPACE imp
|
#define LIBIMP_NAMESPACE_ LIBIMP_
|
||||||
#endif
|
#define LIBIMP_NAMESPACE_BEG_ namespace LIBIMP_NAMESPACE_ {
|
||||||
#define LIBIMP_NAMESPACE_BEG_ namespace LIBIMP_NAMESPACE {
|
|
||||||
#define LIBIMP_NAMESPACE_END_ }
|
#define LIBIMP_NAMESPACE_END_ }
|
||||||
|
|
||||||
LIBIMP_NAMESPACE_BEG_
|
LIBIMP_NAMESPACE_BEG_
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
|
||||||
#include "libimp/def.h"
|
#include "libimp/def.h"
|
||||||
|
#include "libimp/detect_plat.h"
|
||||||
#include "libimp/export.h"
|
#include "libimp/export.h"
|
||||||
|
|
||||||
LIBIMP_NAMESPACE_BEG_
|
LIBIMP_NAMESPACE_BEG_
|
||||||
@ -26,7 +27,7 @@ class LIBIMP_EXPORT result_code {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
result_code() noexcept;
|
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;
|
std::uint64_t value() const noexcept;
|
||||||
bool ok() const noexcept;
|
bool ok() const noexcept;
|
||||||
@ -42,6 +43,11 @@ public:
|
|||||||
friend bool operator!=(result_code const &lhs, result_code const &rhs) noexcept;
|
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 {
|
namespace detail_result {
|
||||||
|
|
||||||
template <typename T, typename = void>
|
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 {
|
static T cast_from_code(std::uint64_t code) noexcept {
|
||||||
return static_cast<T>(code);
|
return static_cast<T>(code);
|
||||||
}
|
}
|
||||||
static T regularize(T value) noexcept {
|
template <typename Out>
|
||||||
return value;
|
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 {
|
static T cast_from_code(std::uint64_t code) noexcept {
|
||||||
return reinterpret_cast<T>(code);
|
return reinterpret_cast<T>(code);
|
||||||
}
|
}
|
||||||
static void *regularize(T value) noexcept {
|
template <typename Out>
|
||||||
return value;
|
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
|
} // namespace detail_result
|
||||||
|
|
||||||
template <typename T,
|
template <typename T, typename DefTraits>
|
||||||
typename DefTraits = detail_result::default_traits<T>>
|
class result<T, DefTraits, std::enable_if_t<std::is_integral<T>::value>> {
|
||||||
class result {
|
|
||||||
|
|
||||||
result_code code_;
|
result_code code_;
|
||||||
|
|
||||||
@ -89,7 +99,7 @@ public:
|
|||||||
using default_traits_t = DefTraits;
|
using default_traits_t = DefTraits;
|
||||||
|
|
||||||
result() noexcept = default;
|
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)) {}
|
: code_(ok, default_traits_t::cast_to_code(value)) {}
|
||||||
|
|
||||||
T value() const noexcept { return default_traits_t::cast_from_code(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 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_
|
LIBIMP_NAMESPACE_END_
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, typename D>
|
||||||
struct fmt::formatter<::LIBIMP_NAMESPACE::result<T>> {
|
struct fmt::formatter<::LIBIMP_::result<T, D>> {
|
||||||
constexpr auto parse(format_parse_context& ctx) {
|
constexpr auto parse(format_parse_context& ctx) {
|
||||||
return ctx.end();
|
return ctx.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FormatContext>
|
template <typename FormatContext>
|
||||||
auto format(::LIBIMP_NAMESPACE::result<T> r, FormatContext &ctx) {
|
auto format(::LIBIMP_::result<T, D> r, FormatContext &ctx) {
|
||||||
return format_to(ctx.out(), "[{}, value = {}]",
|
return format_to(::LIBIMP_::result<T, D>::default_traits_t::format(r,
|
||||||
(r ? "succ" : "fail"),
|
format_to(ctx.out(), "[{}, value = ", r ? "succ" : "fail")), "]");
|
||||||
::LIBIMP_NAMESPACE::result<T>::default_traits_t::regularize(*r));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct fmt::formatter<::LIBIMP_NAMESPACE::result_code>
|
struct fmt::formatter<::LIBIMP_::result_code>
|
||||||
: formatter<::LIBIMP_NAMESPACE::result<std::uint64_t>> {
|
: formatter<::LIBIMP_::result<std::uint64_t>> {
|
||||||
template <typename FormatContext>
|
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);
|
return format_to(ctx.out(), "[{}, value = {}]", (r ? "succ" : "fail"), *r);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,14 +9,21 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#if !defined(LIBIPC_NAMESPACE)
|
#define LIBIPC_ ipc
|
||||||
# define LIBIPC_NAMESPACE ipc
|
#define LIBIPC_NAMESPACE_ LIBIPC_
|
||||||
#endif
|
#define LIBIPC_NAMESPACE_BEG_ namespace LIBIPC_NAMESPACE_ {
|
||||||
#define LIBIPC_NAMESPACE_BEG_ namespace LIBIPC_NAMESPACE {
|
|
||||||
#define LIBIPC_NAMESPACE_END_ }
|
#define LIBIPC_NAMESPACE_END_ }
|
||||||
|
|
||||||
LIBIPC_NAMESPACE_BEG_
|
LIBIPC_NAMESPACE_BEG_
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
|
|
||||||
|
struct prot {
|
||||||
|
enum : std::uint32_t {
|
||||||
|
none = 0x00,
|
||||||
|
read = 0x01,
|
||||||
|
write = 0x02,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
LIBIPC_NAMESPACE_END_
|
LIBIPC_NAMESPACE_END_
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "libimp/export.h"
|
#include "libimp/export.h"
|
||||||
#include "libimp/result.h"
|
#include "libimp/result.h"
|
||||||
|
|
||||||
#include "libipc/def.h"
|
#include "libipc/def.h"
|
||||||
|
|
||||||
LIBIPC_NAMESPACE_BEG_
|
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.
|
* @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_
|
LIBIPC_NAMESPACE_END_
|
||||||
|
|||||||
@ -68,10 +68,14 @@ TEST(result, fmt) {
|
|||||||
{
|
{
|
||||||
imp::result<int> r1 {false, -123};
|
imp::result<int> r1 {false, -123};
|
||||||
EXPECT_EQ(fmt::format("{}", r1), fmt::format("[fail, value = {}]", -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));
|
EXPECT_EQ(fmt::format("{}", r2), fmt::format("[succ, value = {}]", (void *)&r1));
|
||||||
int aaa {};
|
int aaa {};
|
||||||
imp::result<int *> r3 {false, &aaa};
|
imp::result<int *> r3 {&aaa};
|
||||||
EXPECT_EQ(fmt::format("{}", r3), fmt::format("[fail, value = {}]", (void *)&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