Add copy to status
This commit is contained in:
@ -3,6 +3,7 @@
|
||||
#include "asl/string.hpp"
|
||||
#include "asl/atomic.hpp"
|
||||
|
||||
// @Todo Use custom allocator
|
||||
using Allocator = asl::DefaultAllocator;
|
||||
static Allocator g_allocator{};
|
||||
|
||||
@ -11,13 +12,12 @@ namespace
|
||||
|
||||
struct StatusInternal
|
||||
{
|
||||
// @Todo Use custom allocator
|
||||
asl::string<> msg;
|
||||
asl::string<Allocator> msg;
|
||||
asl::status_code code;
|
||||
asl::atomic<int32_t> ref_count;
|
||||
|
||||
constexpr StatusInternal(asl::string_view msg_, asl::status_code code_)
|
||||
: msg{msg_}
|
||||
: msg{msg_, g_allocator}
|
||||
, code{code_}
|
||||
{
|
||||
atomic_store(&ref_count, 1);
|
||||
@ -32,10 +32,23 @@ asl::status::status(status_code code, string_view msg)
|
||||
|
||||
asl::status_code asl::status::code_internal() const
|
||||
{
|
||||
ASL_ASSERT(m_payload && (bit_cast<uintptr_t>(m_payload) & 1) == 0);
|
||||
ASL_ASSERT(!is_inline());
|
||||
return reinterpret_cast<const StatusInternal*>(m_payload)->code;
|
||||
}
|
||||
|
||||
asl::string_view asl::status::message_internal() const
|
||||
{
|
||||
ASL_ASSERT(!is_inline());
|
||||
return reinterpret_cast<const StatusInternal*>(m_payload)->msg;
|
||||
}
|
||||
|
||||
void asl::status::ref()
|
||||
{
|
||||
ASL_ASSERT(!is_inline());
|
||||
auto* internal = reinterpret_cast<StatusInternal*>(m_payload);
|
||||
atomic_fetch_increment(&internal->ref_count, memory_order::relaxed);
|
||||
}
|
||||
|
||||
void asl::status::unref()
|
||||
{
|
||||
ASL_ASSERT(!is_inline());
|
||||
|
@ -49,7 +49,9 @@ class status
|
||||
}
|
||||
|
||||
status_code code_internal() const;
|
||||
string_view message_internal() const;
|
||||
|
||||
void ref();
|
||||
void unref();
|
||||
|
||||
public:
|
||||
@ -57,10 +59,7 @@ public:
|
||||
|
||||
constexpr ~status()
|
||||
{
|
||||
if (!is_inline())
|
||||
{
|
||||
unref();
|
||||
}
|
||||
if (!is_inline()) { unref(); }
|
||||
}
|
||||
|
||||
explicit constexpr status(status_code code)
|
||||
@ -69,10 +68,27 @@ public:
|
||||
|
||||
status(status_code code, string_view msg);
|
||||
|
||||
constexpr status(const status& other)
|
||||
: m_payload{other.m_payload}
|
||||
{
|
||||
if (!is_inline()) { ref(); }
|
||||
}
|
||||
|
||||
constexpr status(status&& other)
|
||||
: m_payload{exchange(other.m_payload, nullptr)}
|
||||
{}
|
||||
|
||||
constexpr status& operator=(const status& other)
|
||||
{
|
||||
if (&other != this)
|
||||
{
|
||||
if (!is_inline()) { unref(); }
|
||||
m_payload = other.m_payload;
|
||||
if (!is_inline()) { ref(); }
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr status& operator=(status&& other)
|
||||
{
|
||||
if (&other != this)
|
||||
@ -82,8 +98,6 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
// @Todo Copy constructor & assignment
|
||||
|
||||
constexpr bool ok() const
|
||||
{
|
||||
return m_payload == nullptr || code() == status_code::ok;
|
||||
@ -96,6 +110,15 @@ public:
|
||||
{
|
||||
return is_inline() ? code_inline() : code_internal();
|
||||
}
|
||||
|
||||
constexpr string_view message() const
|
||||
{
|
||||
if (!is_inline())
|
||||
{
|
||||
return message_internal();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace asl
|
||||
|
@ -15,6 +15,7 @@ ASL_TEST(simple_code)
|
||||
ASL_TEST_ASSERT(!s);
|
||||
ASL_TEST_ASSERT(!s.ok());
|
||||
ASL_TEST_ASSERT(s.code() == asl::status_code::runtime);
|
||||
ASL_TEST_ASSERT(s.message() == ""_sv);
|
||||
}
|
||||
|
||||
ASL_TEST(with_message)
|
||||
@ -23,5 +24,47 @@ ASL_TEST(with_message)
|
||||
ASL_TEST_ASSERT(!s);
|
||||
ASL_TEST_ASSERT(!s.ok());
|
||||
ASL_TEST_ASSERT(s.code() == asl::status_code::internal);
|
||||
// @Todo test message
|
||||
ASL_TEST_ASSERT(s.message() == "We done goofed"_sv);
|
||||
}
|
||||
|
||||
ASL_TEST(copy_inline)
|
||||
{
|
||||
asl::status s{asl::status_code::ok};
|
||||
asl::status s2{asl::status_code::internal};
|
||||
|
||||
asl::status s3 = s;
|
||||
ASL_TEST_ASSERT(s3.code() == asl::status_code::ok);
|
||||
|
||||
s3 = s2;
|
||||
ASL_TEST_ASSERT(s3.code() == asl::status_code::internal);
|
||||
}
|
||||
|
||||
ASL_TEST(copy_message)
|
||||
{
|
||||
asl::status s2;
|
||||
|
||||
{
|
||||
asl::status s{asl::status_code::internal, "Oh no!"};
|
||||
ASL_TEST_ASSERT(!s);
|
||||
ASL_TEST_ASSERT(!s.ok());
|
||||
ASL_TEST_ASSERT(s.code() == asl::status_code::internal);
|
||||
ASL_TEST_ASSERT(s.message() == "Oh no!"_sv);
|
||||
|
||||
const asl::status s3{s}; // NOLINT
|
||||
ASL_TEST_ASSERT(!s3);
|
||||
ASL_TEST_ASSERT(!s3.ok());
|
||||
ASL_TEST_ASSERT(s3.code() == asl::status_code::internal);
|
||||
ASL_TEST_ASSERT(s3.message() == "Oh no!"_sv);
|
||||
|
||||
s2 = s;
|
||||
ASL_TEST_ASSERT(!s2);
|
||||
ASL_TEST_ASSERT(!s2.ok());
|
||||
ASL_TEST_ASSERT(s2.code() == asl::status_code::internal);
|
||||
ASL_TEST_ASSERT(s2.message() == "Oh no!"_sv);
|
||||
}
|
||||
|
||||
ASL_TEST_ASSERT(!s2);
|
||||
ASL_TEST_ASSERT(!s2.ok());
|
||||
ASL_TEST_ASSERT(s2.code() == asl::status_code::internal);
|
||||
ASL_TEST_ASSERT(s2.message() == "Oh no!"_sv);
|
||||
}
|
||||
|
Reference in New Issue
Block a user