summaryrefslogtreecommitdiff
path: root/asl
diff options
context:
space:
mode:
authorSteven Le Rouzic <steven.lerouzic@gmail.com>2024-10-08 23:33:21 +0200
committerSteven Le Rouzic <steven.lerouzic@gmail.com>2024-12-20 15:35:58 +0100
commit0e7999f2d147b026aaee6693bdd2be2cb4a2519e (patch)
treeb5bc7e49f732009f5d5f26ec625f4fa96935d40a /asl
parent85462f25d6335bcca9423b6fc1e624d9a76a2375 (diff)
Start work on formatting
Diffstat (limited to 'asl')
-rw-r--r--asl/BUILD.bazel13
-rw-r--r--asl/format.cpp12
-rw-r--r--asl/format.hpp84
-rw-r--r--asl/format_tests.cpp0
-rw-r--r--asl/meta.hpp4
-rw-r--r--asl/meta_tests.cpp5
-rw-r--r--asl/option.hpp1
-rw-r--r--asl/utility.hpp12
8 files changed, 129 insertions, 2 deletions
diff --git a/asl/BUILD.bazel b/asl/BUILD.bazel
index 06e2a9f..5137c8f 100644
--- a/asl/BUILD.bazel
+++ b/asl/BUILD.bazel
@@ -3,6 +3,7 @@ cc_library(
hdrs = [
"annotations.hpp",
"assert.hpp",
+ "format.hpp",
"integers.hpp",
"layout.hpp",
"maybe_uninit.hpp",
@@ -11,6 +12,9 @@ cc_library(
"option.hpp",
"utility.hpp",
],
+ srcs = [
+ "format.cpp",
+ ],
visibility = ["//visibility:public"],
)
@@ -23,4 +27,11 @@ cc_library(
deps = [
":asl",
],
-) for name in ["integers", "maybe_uninit", "meta", "option", "utility"]]
+) for name in [
+ "format",
+ "integers",
+ "maybe_uninit",
+ "meta",
+ "option",
+ "utility",
+]]
diff --git a/asl/format.cpp b/asl/format.cpp
new file mode 100644
index 0000000..890e532
--- /dev/null
+++ b/asl/format.cpp
@@ -0,0 +1,12 @@
+#include "asl/format.hpp"
+
+void asl::format_internals::format(
+ writer* writer,
+ const char* fmt,
+ const type_erased_arg* args,
+ int64_t arg_count)
+{
+ formatter f(writer);
+
+ f.write("Hello", 5);
+}
diff --git a/asl/format.hpp b/asl/format.hpp
new file mode 100644
index 0000000..6cffd3a
--- /dev/null
+++ b/asl/format.hpp
@@ -0,0 +1,84 @@
+#pragma once
+
+#include "asl/integers.hpp"
+#include "asl/meta.hpp"
+#include "asl/utility.hpp"
+
+namespace asl
+{
+
+// @Todo Move this to io
+class writer
+{
+public:
+ writer() = default;
+ ASL_DELETE_COPY_MOVE(writer);
+ virtual ~writer() = default;
+
+ // @Todo Use string view, or span of bytes?
+ virtual void write(const char* str, int64_t len) = 0;
+};
+
+class formatter;
+
+template<typename T>
+concept formattable = requires (formatter& f, const T& value)
+{
+ AslFormat(f, value);
+};
+
+namespace format_internals
+{
+
+struct type_erased_arg
+{
+ const void* data;
+ void (*fn)(formatter&, const void*);
+
+ template<formattable T>
+ static constexpr void erased_fn(formatter& f, const void* data)
+ {
+ AslFormat(f, *reinterpret_cast<const T*>(data));
+ }
+
+ template<formattable T>
+ explicit constexpr type_erased_arg(const T& arg)
+ : data{&arg}
+ , fn{erased_fn<T>}
+ {}
+};
+
+// @Todo Use span
+void format(writer*, const char* fmt, const type_erased_arg* args, int64_t arg_count);
+
+} // internals
+
+class formatter
+{
+ writer* m_writer;
+
+public:
+ explicit constexpr formatter(writer* writer)
+ : m_writer{writer}
+ {}
+
+ // @Todo Use string_view
+ constexpr void write(const char* s, int64_t len)
+ {
+ m_writer->write(s, len);
+ }
+};
+
+// @Todo Use string_view
+template<typename... Args>
+void format(writer* w, const char* fmt, const Args&... args)
+{
+ auto type_erased_args[] = {
+ format_internals::type_erased_arg(args)...
+ };
+
+ // @Todo Use array extent
+ format_internals::format(w, fmt, type_erased_args, types_count<Args...>);
+}
+
+} // namespace asl
diff --git a/asl/format_tests.cpp b/asl/format_tests.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asl/format_tests.cpp
diff --git a/asl/meta.hpp b/asl/meta.hpp
index 931310f..7372c3f 100644
--- a/asl/meta.hpp
+++ b/asl/meta.hpp
@@ -1,11 +1,15 @@
#pragma once
+#include "asl/integers.hpp"
+
namespace asl {
struct empty {};
template<typename T> struct id { using type = T; };
+template<typename... Args> static constexpr int64_t types_count = sizeof...(Args);
+
template<typename T, T kValue> struct integral_constant { static constexpr T value = kValue; };
template<bool B> using bool_constant = integral_constant<bool, B>;
diff --git a/asl/meta_tests.cpp b/asl/meta_tests.cpp
index 8456f92..e53f870 100644
--- a/asl/meta_tests.cpp
+++ b/asl/meta_tests.cpp
@@ -158,4 +158,9 @@ static_assert(asl::is_same<int, asl::un_ref_t<int&>>);
static_assert(asl::is_same<int, asl::un_ref_t<int&&>>);
static_assert(asl::is_same<int() &, asl::un_ref_t<int() &>>);
+static_assert(asl::types_count<int, float> == 2);
+static_assert(asl::types_count<int, int> == 2);
+static_assert(asl::types_count<int> == 1);
+static_assert(asl::types_count<> == 0);
+
int main() { return 0; }
diff --git a/asl/option.hpp b/asl/option.hpp
index 8662250..7600252 100644
--- a/asl/option.hpp
+++ b/asl/option.hpp
@@ -116,7 +116,6 @@ public:
m_has_value = false;
}
}
-
};
} // namespace asl
diff --git a/asl/utility.hpp b/asl/utility.hpp
index 6cbff8e..2cbf8db 100644
--- a/asl/utility.hpp
+++ b/asl/utility.hpp
@@ -17,4 +17,16 @@ T exchange(T& obj, U&& new_value)
return old_value;
}
+#define ASL_DELETE_COPY(T) \
+ T(const T&) = delete; \
+ T& operator=(const T&) = delete;
+
+#define ASL_DELETE_MOVE(T) \
+ T(T&&) = delete; \
+ T& operator=(T&&) = delete;
+
+#define ASL_DELETE_COPY_MOVE(T) \
+ ASL_DELETE_COPY(T) \
+ ASL_DELETE_MOVE(T)
+
} // namespace asl