print: Add c++23 print compatible implementation
Change-Id: I2bb81f79550f3e9bdb0ea15cb21225a015d17800
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/include/meson.build b/include/meson.build
index d24e818..57a5a5e 100644
--- a/include/meson.build
+++ b/include/meson.build
@@ -17,6 +17,7 @@
'stdplus/numeric/endian.hpp',
'stdplus/numeric/str.hpp',
'stdplus/pinned.hpp',
+ 'stdplus/print.hpp',
'stdplus/raw.hpp',
'stdplus/signal.hpp',
'stdplus/str/buf.hpp',
diff --git a/include/stdplus/print.hpp b/include/stdplus/print.hpp
new file mode 100644
index 0000000..d74f2f1
--- /dev/null
+++ b/include/stdplus/print.hpp
@@ -0,0 +1,57 @@
+#include <stdplus/str/buf.hpp>
+
+#include <cstdio>
+#include <format>
+#include <system_error>
+
+namespace stdplus
+{
+
+template <bool ln>
+struct Printer
+{
+ template <typename... Args>
+ static void print(std::FILE* stream, std::format_string<Args...> fmt,
+ Args&&... args)
+ {
+ stdplus::StrBuf buf;
+ std::format_to(std::back_inserter(buf), fmt,
+ std::forward<Args>(args)...);
+ if constexpr (ln)
+ {
+ buf.push_back('\n');
+ }
+ int r = std::fwrite(buf.data(), sizeof(char), buf.size(), stream);
+ if (r < 0)
+ {
+ throw std::system_error(errno, std::generic_category());
+ }
+ }
+};
+
+template <typename... Args>
+void print(std::FILE* stream, std::format_string<Args...> fmt, Args&&... args)
+{
+ Printer<false>::print(stream, fmt, std::forward<Args>(args)...);
+}
+
+template <typename... Args>
+inline void print(std::format_string<Args...> fmt, Args&&... args)
+{
+ Printer<false>::print(stdout, fmt, std::forward<Args>(args)...);
+}
+
+template <typename... Args>
+inline void println(std::FILE* stream, std::format_string<Args...> fmt,
+ Args&&... args)
+{
+ Printer<true>::print(stream, fmt, std::forward<Args>(args)...);
+}
+
+template <typename... Args>
+inline void println(std::format_string<Args...> fmt, Args&&... args)
+{
+ Printer<true>::print(stdout, fmt, std::forward<Args>(args)...);
+}
+
+} // namespace stdplus