diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-10-11 00:32:49 +0200 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-12-20 15:35:58 +0100 |
commit | f011d871ef3af26c8f4e19de2c8d781c601ceffb (patch) | |
tree | ac3611e6fa054cc0f8870aad524b263ff917057f | |
parent | e020805cb140ed98d09e606a867b910fce78ad15 (diff) |
Add console printing
-rw-r--r-- | asl/BUILD.bazel | 3 | ||||
-rw-r--r-- | asl/format.cpp | 12 | ||||
-rw-r--r-- | asl/format.hpp | 40 | ||||
-rw-r--r-- | asl/format_tests.cpp | 4 | ||||
-rw-r--r-- | asl/io.hpp | 20 | ||||
-rw-r--r-- | asl/print.hpp | 31 | ||||
-rw-r--r-- | asl/print_win32.cpp | 33 |
7 files changed, 118 insertions, 25 deletions
diff --git a/asl/BUILD.bazel b/asl/BUILD.bazel index 5137c8f..f904624 100644 --- a/asl/BUILD.bazel +++ b/asl/BUILD.bazel @@ -5,15 +5,18 @@ cc_library( "assert.hpp",
"format.hpp",
"integers.hpp",
+ "io.hpp",
"layout.hpp",
"maybe_uninit.hpp",
"memory.hpp",
"meta.hpp",
"option.hpp",
+ "print.hpp",
"utility.hpp",
],
srcs = [
"format.cpp",
+ "print_win32.cpp",
],
visibility = ["//visibility:public"],
)
diff --git a/asl/format.cpp b/asl/format.cpp index eb653e9..ff565bd 100644 --- a/asl/format.cpp +++ b/asl/format.cpp @@ -80,6 +80,18 @@ void asl::AslFormat(formatter& f, double) f.write("<DOUBLE>", 8); // @Todo Float formatting
}
+void asl::AslFormat(formatter& f, bool v)
+{
+ if (v)
+ {
+ f.write("true", 4);
+ }
+ else
+ {
+ f.write("false", 5);
+ }
+}
+
void asl::AslFormat(formatter& f, uint8_t v)
{
AslFormat(f, static_cast<uint64_t>(v));
diff --git a/asl/format.hpp b/asl/format.hpp index f17329f..b4cb439 100644 --- a/asl/format.hpp +++ b/asl/format.hpp @@ -2,23 +2,11 @@ #include "asl/integers.hpp" #include "asl/meta.hpp"
-#include "asl/utility.hpp"
+#include "asl/io.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>
@@ -70,21 +58,21 @@ public: };
// @Todo Use string_view
-template<typename... Args>
+template<formattable... Args>
void format(writer* w, const char* fmt, const Args&... args)
{
- format_internals::type_erased_arg type_erased_args[] = {
- format_internals::type_erased_arg(args)...
- };
-
- // @Todo Use array extent
- format_internals::format(w, fmt, type_erased_args, types_count<Args...>);
-}
+ if constexpr (types_count<Args...> > 0)
+ {
+ format_internals::type_erased_arg type_erased_args[] = {
+ format_internals::type_erased_arg(args)...
+ };
-// @Todo Use string_view
-inline void format(writer* w, const char* fmt)
-{
- format_internals::format(w, fmt, nullptr, 0);
+ format_internals::format(w, fmt, type_erased_args, types_count<Args...>);
+ }
+ else
+ {
+ format_internals::format(w, fmt, nullptr, 0);
+ }
}
template<int64_t N>
@@ -96,6 +84,8 @@ void AslFormat(formatter& f, const char (&str)[N]) void AslFormat(formatter& f, float);
void AslFormat(formatter& f, double);
+void AslFormat(formatter& f, bool);
+
void AslFormat(formatter& f, uint8_t);
void AslFormat(formatter& f, uint16_t);
void AslFormat(formatter& f, uint32_t);
diff --git a/asl/format_tests.cpp b/asl/format_tests.cpp index 55ed97b..818773b 100644 --- a/asl/format_tests.cpp +++ b/asl/format_tests.cpp @@ -98,5 +98,9 @@ int main() asl::format(&sink, "{} {} {} {}", -1, -23, -456, -7890);
assert(strcmp(sink.cstr(), "-1 -23 -456 -7890") == 0);
+ sink.reset();
+ asl::format(&sink, "{} {}", true, false);
+ assert(strcmp(sink.cstr(), "true false") == 0);
+
return 0;
}
diff --git a/asl/io.hpp b/asl/io.hpp new file mode 100644 index 0000000..79c70c2 --- /dev/null +++ b/asl/io.hpp @@ -0,0 +1,20 @@ +#pragma once
+
+#include "asl/integers.hpp" +#include "asl/utility.hpp"
+
+namespace asl
+{
+
+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;
+};
+
+} // namespace asl
diff --git a/asl/print.hpp b/asl/print.hpp new file mode 100644 index 0000000..d82d52b --- /dev/null +++ b/asl/print.hpp @@ -0,0 +1,31 @@ +#pragma once
+
+#include "asl/format.hpp"
+
+namespace asl
+{
+
+namespace print_internals
+{
+
+// @Todo Make print writers thread safe
+writer* get_stdout_writer();
+writer* get_stderr_writer();
+
+} // namespace print_internals
+
+// @Todo Use string_view
+template<formattable... Args>
+void print(const char* fmt, const Args&... args)
+{
+ format(print_internals::get_stdout_writer(), fmt, args...);
+}
+
+// @Todo Use string_view
+template<formattable... Args>
+void eprint(const char* fmt, const Args&... args)
+{
+ format(print_internals::get_stderr_writer(), fmt, args...);
+}
+
+} // namespace asl
diff --git a/asl/print_win32.cpp b/asl/print_win32.cpp new file mode 100644 index 0000000..45939b2 --- /dev/null +++ b/asl/print_win32.cpp @@ -0,0 +1,33 @@ +#include "asl/print.hpp"
+
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+
+// @Todo Optimize this, maybe make buffered
+class Win32ConsoleWriter : public asl::writer
+{
+ HANDLE m_handle;
+
+public:
+ explicit Win32ConsoleWriter(HANDLE handle)
+ : m_handle{handle}
+ {}
+
+ void write(const char* str, int64_t len) override
+ {
+ ::WriteConsoleA(m_handle, str, static_cast<DWORD>(len), nullptr, nullptr);
+ }
+};
+
+asl::writer* asl::print_internals::get_stdout_writer()
+{
+ static Win32ConsoleWriter writer{::GetStdHandle(STD_OUTPUT_HANDLE)};
+ return &writer;
+}
+
+asl::writer* asl::print_internals::get_stderr_writer()
+{
+ static Win32ConsoleWriter writer{::GetStdHandle(STD_ERROR_HANDLE)};
+ return &writer;
+}
+
|