diff --git a/include/libimp/def.h b/include/libimp/def.h index 0b5ffb0..a0ff342 100644 --- a/include/libimp/def.h +++ b/include/libimp/def.h @@ -9,10 +9,9 @@ #include #include -#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_ diff --git a/include/libimp/result.h b/include/libimp/result.h index 43463b4..121e4b3 100644 --- a/include/libimp/result.h +++ b/include/libimp/result.h @@ -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 = void> +class result; + namespace detail_result { template @@ -57,8 +63,9 @@ struct default_traits::value>> { static T cast_from_code(std::uint64_t code) noexcept { return static_cast(code); } - static T regularize(T value) noexcept { - return value; + template + static auto format(result const &r, Out &&out) noexcept { + return format_to(out, "{}", *r); } }; @@ -72,16 +79,19 @@ struct default_traits::value>> { static T cast_from_code(std::uint64_t code) noexcept { return reinterpret_cast(code); } - static void *regularize(T value) noexcept { - return value; + template + static auto format(result const &r, Out &&out) noexcept { + if LIBIMP_LIKELY(r) { + return format_to(out, "{}", static_cast(*r)); + } + return format_to(out, "{}, code = {}", static_cast(*r), r.code()); } }; } // namespace detail_result -template > -class result { +template +class result::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 +class result::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 -struct fmt::formatter<::LIBIMP_NAMESPACE::result> { +template +struct fmt::formatter<::LIBIMP_::result> { constexpr auto parse(format_parse_context& ctx) { return ctx.end(); } template - auto format(::LIBIMP_NAMESPACE::result r, FormatContext &ctx) { - return format_to(ctx.out(), "[{}, value = {}]", - (r ? "succ" : "fail"), - ::LIBIMP_NAMESPACE::result::default_traits_t::regularize(*r)); + auto format(::LIBIMP_::result r, FormatContext &ctx) { + return format_to(::LIBIMP_::result::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> { +struct fmt::formatter<::LIBIMP_::result_code> + : formatter<::LIBIMP_::result> { template - 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); } }; diff --git a/include/libipc/def.h b/include/libipc/def.h index aa0c0c8..2ce94db 100755 --- a/include/libipc/def.h +++ b/include/libipc/def.h @@ -9,14 +9,21 @@ #include #include -#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_ diff --git a/include/libipc/mmap.h b/include/libipc/mmap.h index d2bc07f..3b266a5 100644 --- a/include/libipc/mmap.h +++ b/include/libipc/mmap.h @@ -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_open(); LIBIPC_NAMESPACE_END_ diff --git a/test/test_result.cpp b/test/test_result.cpp index a20aaa6..87f9cd4 100644 --- a/test/test_result.cpp +++ b/test/test_result.cpp @@ -68,10 +68,14 @@ TEST(result, fmt) { { imp::result r1 {false, -123}; EXPECT_EQ(fmt::format("{}", r1), fmt::format("[fail, value = {}]", -123)); - imp::result r2 {true, &r1}; + imp::result r2 {&r1}; EXPECT_EQ(fmt::format("{}", r2), fmt::format("[succ, value = {}]", (void *)&r1)); int aaa {}; - imp::result r3 {false, &aaa}; - EXPECT_EQ(fmt::format("{}", r3), fmt::format("[fail, value = {}]", (void *)&aaa)); + imp::result r3 {&aaa}; + EXPECT_EQ(fmt::format("{}", r3), fmt::format("[succ, value = {}]", (void *)&aaa)); + imp::result 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)); } } \ No newline at end of file