Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core/StarFormat.hpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
commit6352e8e3196f78388b6c771073f9e03eaa612673 (patch)
treee23772f79a7fbc41bc9108951e9e136857484bf4 /source/core/StarFormat.hpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/core/StarFormat.hpp')
-rw-r--r--source/core/StarFormat.hpp100
1 files changed, 100 insertions, 0 deletions
diff --git a/source/core/StarFormat.hpp b/source/core/StarFormat.hpp
new file mode 100644
index 0000000..bb0327e
--- /dev/null
+++ b/source/core/StarFormat.hpp
@@ -0,0 +1,100 @@
+#ifndef STAR_FORMAT_HPP
+#define STAR_FORMAT_HPP
+
+#include "StarMemory.hpp"
+
+namespace Star {
+
+struct FormatException : public std::exception {
+ FormatException(std::string what) : whatmsg(move(what)) {}
+
+ char const* what() const noexcept override {
+ return whatmsg.c_str();
+ }
+
+ std::string whatmsg;
+};
+
+}
+
+#define TINYFORMAT_ERROR(reason) throw Star::FormatException(reason)
+
+#include "tinyformat.h"
+
+namespace Star {
+
+template <typename... Args>
+void format(std::ostream& out, char const* fmt, Args const&... args) {
+ tinyformat::format(out, fmt, args...);
+}
+
+// Automatically flushes, use format to avoid flushing.
+template <typename... Args>
+void coutf(char const* fmt, Args const&... args) {
+ format(std::cout, fmt, args...);
+ std::cout.flush();
+}
+
+// Automatically flushes, use format to avoid flushing.
+template <typename... Args>
+void cerrf(char const* fmt, Args const&... args) {
+ format(std::cerr, fmt, args...);
+ std::cerr.flush();
+}
+
+template <typename... Args>
+std::string strf(char const* fmt, Args const&... args) {
+ std::ostringstream os;
+ format(os, fmt, args...);
+ return os.str();
+}
+
+namespace OutputAnyDetail {
+ template<typename T, typename CharT, typename Traits>
+ std::basic_ostream<CharT, Traits>& output(std::basic_ostream<CharT, Traits>& os, T const& t) {
+ return os << "<type " << typeid(T).name() << " at address: " << &t << ">";
+ }
+
+ namespace Operator {
+ template<typename T, typename CharT, typename Traits>
+ std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, T const& t) {
+ return output(os, t);
+ }
+ }
+
+ template <typename T>
+ struct Wrapper {
+ T const& wrapped;
+ };
+
+ template <typename T>
+ std::ostream& operator<<(std::ostream& os, Wrapper<T> const& wrapper) {
+ using namespace Operator;
+ return os << wrapper.wrapped;
+ }
+}
+
+// Wraps a type so that is printable no matter what.. If no operator<< is
+// defined for a type, then will print <type [typeid] at address: [address]>
+template <typename T>
+OutputAnyDetail::Wrapper<T> outputAny(T const& t) {
+ return OutputAnyDetail::Wrapper<T>{t};
+}
+
+struct OutputProxy {
+ typedef function<void(std::ostream&)> PrintFunction;
+
+ OutputProxy(PrintFunction p)
+ : print(move(p)) {}
+
+ PrintFunction print;
+};
+
+inline std::ostream& operator<<(std::ostream& os, OutputProxy const& p) {
+ p.print(os);
+ return os;
+}
+
+}
+
+#endif