From 0e7999f2d147b026aaee6693bdd2be2cb4a2519e Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Tue, 8 Oct 2024 23:33:21 +0200 Subject: Start work on formatting --- asl/BUILD.bazel | 13 +++++++- asl/format.cpp | 12 ++++++++ asl/format.hpp | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ asl/format_tests.cpp | 0 asl/meta.hpp | 4 +++ asl/meta_tests.cpp | 5 ++++ asl/option.hpp | 1 - asl/utility.hpp | 12 ++++++++ 8 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 asl/format.cpp create mode 100644 asl/format.hpp create mode 100644 asl/format_tests.cpp (limited to 'asl') 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 +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 + static constexpr void erased_fn(formatter& f, const void* data) + { + AslFormat(f, *reinterpret_cast(data)); + } + + template + explicit constexpr type_erased_arg(const T& arg) + : data{&arg} + , fn{erased_fn} + {} +}; + +// @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 +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); +} + +} // namespace asl diff --git a/asl/format_tests.cpp b/asl/format_tests.cpp new file mode 100644 index 0000000..e69de29 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 struct id { using type = T; }; +template static constexpr int64_t types_count = sizeof...(Args); + template struct integral_constant { static constexpr T value = kValue; }; template using bool_constant = integral_constant; 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>); static_assert(asl::is_same>); static_assert(asl::is_same>); +static_assert(asl::types_count == 2); +static_assert(asl::types_count == 2); +static_assert(asl::types_count == 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 -- cgit