summaryrefslogtreecommitdiff
path: root/deimos/core
diff options
context:
space:
mode:
Diffstat (limited to 'deimos/core')
-rw-r--r--deimos/core/base.h6
-rw-r--r--deimos/core/format.cpp3
-rw-r--r--deimos/core/format.h39
-rw-r--r--deimos/core/log.h6
-rw-r--r--deimos/core/status.cpp30
-rw-r--r--deimos/core/status.h10
-rw-r--r--deimos/core/std.h1
-rw-r--r--deimos/core/temp_allocator.cpp2
8 files changed, 82 insertions, 15 deletions
diff --git a/deimos/core/base.h b/deimos/core/base.h
index f24991d..5cd3a40 100644
--- a/deimos/core/base.h
+++ b/deimos/core/base.h
@@ -78,6 +78,9 @@ constexpr void MemoryCopy(void* dst, const void* src, int64_t size)
__builtin_memcpy(dst, src, (size_t)size);
}
+template<typename T, int64_t N>
+constexpr int64_t ArraySize(const T (&)[N]) { return N; }
+
template<typename T>
class Span
{
@@ -113,6 +116,7 @@ public:
constexpr T* begin() const { return m_begin; }
constexpr T* end() const { return m_begin + m_size; } // NOLINT
constexpr int64_t size() const { return m_size; }
+ constexpr bool empty() const { return m_size == 0; }
};
template<typename T>
@@ -141,8 +145,8 @@ public:
{}
constexpr const char* data() const { return m_begin; }
-
constexpr int64_t size() const { return m_size; }
+ constexpr bool empty() const { return m_size == 0; }
};
inline Span<const std::byte> AsBytes(StringView span)
diff --git a/deimos/core/format.cpp b/deimos/core/format.cpp
index af0a851..5f420e9 100644
--- a/deimos/core/format.cpp
+++ b/deimos/core/format.cpp
@@ -51,6 +51,9 @@ public:
case FormatArg::kUnsignedInteger:
PushUnsignedInteger(arg.integer);
break;
+ case FormatArg::kCustom:
+ arg.custom.callback(m_writer, arg.custom.payload);
+ break;
}
}
};
diff --git a/deimos/core/format.h b/deimos/core/format.h
index 3424dc2..ba1a3e2 100644
--- a/deimos/core/format.h
+++ b/deimos/core/format.h
@@ -7,6 +7,14 @@ namespace deimos
class IWriter;
+struct CustomFormatter
+{
+ using Callback = void (*)(IWriter*, const void* payload);
+
+ const void* payload;
+ Callback callback;
+};
+
struct FormatArg
{
enum Type : uint8_t
@@ -14,42 +22,57 @@ struct FormatArg
kInteger,
kUnsignedInteger,
kString,
+ kCustom,
};
Type type;
union
{
- int64_t integer;
- uint64_t unsigned_integer;
- StringView string;
+ int64_t integer;
+ uint64_t unsigned_integer;
+ StringView string;
+ CustomFormatter custom;
};
- explicit FormatArg(std::signed_integral auto value) :
+ constexpr explicit FormatArg(std::signed_integral auto value) :
type{kInteger},
integer{value}
{}
- explicit FormatArg(std::unsigned_integral auto value) :
+ constexpr explicit FormatArg(std::unsigned_integral auto value) :
type{kUnsignedInteger},
unsigned_integer{value}
{}
- explicit FormatArg(StringView value) :
+ constexpr explicit FormatArg(StringView value) :
type{kString},
string{value}
{}
+
+ template<typename T>
+ constexpr explicit FormatArg(const T& payload, CustomFormatter::Callback callback) :
+ type{kCustom},
+ custom{CustomFormatter{&payload, callback}}
+ {}
};
template<typename T>
-concept Formattable = requires (T value) { FormatArg(value); };
+deimos::FormatArg DeimosMakeFormatArg(T&& value)
+ requires std::is_constructible_v<deimos::FormatArg, T>
+{
+ return deimos::FormatArg(value);
+}
+
+template<typename T>
+concept Formattable = std::same_as<deimos::FormatArg, decltype(DeimosMakeFormatArg(std::declval<T>()))>;
void FormatVa(IWriter*, gsl::czstring fmt, Span<const FormatArg>);
template<Formattable... Args>
void Format(IWriter* writer, gsl::czstring fmt, Args&&... args)
{
- FormatVa(writer, fmt, { FormatArg(std::forward<Args>(args))... });
+ FormatVa(writer, fmt, { DeimosMakeFormatArg(std::forward<Args>(args))... });
}
} // namespace deimos
diff --git a/deimos/core/log.h b/deimos/core/log.h
index 9bb4dbb..260d9a4 100644
--- a/deimos/core/log.h
+++ b/deimos/core/log.h
@@ -50,19 +50,19 @@ public:
template<Formattable... Args>
void LogInfo(const LogSourceLocation& fmt_source_location, Args&&... args)
{
- LogVa(LogSeverity::kInfo, fmt_source_location.source_location, fmt_source_location.fmt, { FormatArg(std::forward<Args>(args))... });
+ LogVa(LogSeverity::kInfo, fmt_source_location.source_location, fmt_source_location.fmt, { DeimosMakeFormatArg(std::forward<Args>(args))... });
}
template<Formattable... Args>
void LogDebug(const LogSourceLocation& fmt_source_location, Args&&... args)
{
- LogVa(LogSeverity::kDebug, fmt_source_location.source_location, fmt_source_location.fmt, { FormatArg(std::forward<Args>(args))... });
+ LogVa(LogSeverity::kDebug, fmt_source_location.source_location, fmt_source_location.fmt, { DeimosMakeFormatArg(std::forward<Args>(args))... });
}
template<Formattable... Args>
void LogError(const LogSourceLocation& fmt_source_location, Args&&... args)
{
- LogVa(LogSeverity::kError, fmt_source_location.source_location, fmt_source_location.fmt, { FormatArg(std::forward<Args>(args))... });
+ LogVa(LogSeverity::kError, fmt_source_location.source_location, fmt_source_location.fmt, { DeimosMakeFormatArg(std::forward<Args>(args))... });
}
};
diff --git a/deimos/core/status.cpp b/deimos/core/status.cpp
index f472aac..efdd6df 100644
--- a/deimos/core/status.cpp
+++ b/deimos/core/status.cpp
@@ -9,6 +9,18 @@ static deimos::AllocatorApi* allocator_api;
namespace deimos
{
+StringView StatusCodeToString(StatusCode code)
+{
+ switch (code)
+ {
+ case StatusCode::kOk: return StringView("OK");
+ case StatusCode::kUnknown: return StringView("Unknown error");
+ case StatusCode::kInvalidArgument: return StringView("Invalid argument");
+ case StatusCode::kUnimplemented: return StringView("Unimplemented");
+ case StatusCode::kInternal: return StringView("Internal error");
+ }
+}
+
struct StatusRep
{
Atomic<int32_t> ref_count;
@@ -18,9 +30,9 @@ struct StatusRep
Status::Status(StatusCode code, StringView message)
{
- if (code == StatusCode::kOk)
+ if (code == StatusCode::kOk || message.empty())
{
- m_rep = CodeToRep(StatusCode::kOk);
+ m_rep = CodeToRep(code);
}
else
{
@@ -74,6 +86,20 @@ void Status::Unref() const
}
}
+void Status::FormatStatus(IWriter* writer, const void* payload)
+{
+ const auto& status = *(const Status*)payload; // NOLINT
+ if (status.IsInline())
+ {
+ Format(writer, "[$]", StatusCodeToString(status.code()));
+ }
+ else
+ {
+ auto* rep = std::bit_cast<StatusRep*>(status.m_rep);
+ Format(writer, "[$: $]", StatusCodeToString(rep->code), rep->message);
+ }
+}
+
void InitializeStatus(ApiRegistry* api_registry)
{
allocator_api = api_registry->Get<AllocatorApi>();
diff --git a/deimos/core/status.h b/deimos/core/status.h
index bf34833..7350cc5 100644
--- a/deimos/core/status.h
+++ b/deimos/core/status.h
@@ -1,6 +1,7 @@
#pragma once
#include "deimos/core/base.h"
+#include "deimos/core/format.h"
namespace deimos
{
@@ -15,6 +16,8 @@ enum class StatusCode : uint32_t
kInternal,
};
+StringView StatusCodeToString(StatusCode code);
+
class Status
{
uintptr_t m_rep;
@@ -79,6 +82,13 @@ public:
if (IsInline()) { return (StatusCode)(m_rep >> 1U); }
return RepCode();
}
+
+ static void FormatStatus(IWriter* writer, const void* payload);
+
+ friend constexpr deimos::FormatArg DeimosMakeFormatArg(const Status& status)
+ {
+ return deimos::FormatArg(status, FormatStatus);
+ }
};
inline Status UnknownError(StringView message = {})
diff --git a/deimos/core/std.h b/deimos/core/std.h
index 4bb2983..0e0336e 100644
--- a/deimos/core/std.h
+++ b/deimos/core/std.h
@@ -24,6 +24,7 @@ template<typename T> concept signed_integral = integral<T> && __is_signed(T);
template<typename T> concept unsigned_integral = integral<T> && __is_unsigned(T);
template<typename T> constexpr bool is_trivially_destructible_v = __is_trivially_destructible(T);
+template<typename T, typename... Args> constexpr bool is_constructible_v = __is_constructible(T, Args...);
template<typename T> constexpr bool is_trivially_copyable_v = __is_trivially_copyable(T);
template<typename U, typename V> constexpr bool _is_same_helper = false;
diff --git a/deimos/core/temp_allocator.cpp b/deimos/core/temp_allocator.cpp
index 2f07bcc..d2b7900 100644
--- a/deimos/core/temp_allocator.cpp
+++ b/deimos/core/temp_allocator.cpp
@@ -41,7 +41,7 @@ public:
if (new_current > m_commit_end)
{
const int64_t new_commit_size = AlignUp(
- (uint64_t)(std::bit_cast<uintptr_t>(new_current) - std::bit_cast<uintptr_t>(m_base)), // NOLINT
+ (int64_t)(std::bit_cast<uintptr_t>(new_current) - std::bit_cast<uintptr_t>(m_base)), // NOLINT
kPageSize);
os_api->virtual_memory->Commit(m_base, new_commit_size);
m_commit_end = OffsetBytes(m_base, new_commit_size);