#pragma once #include #include #include namespace floormat { template concept DebugPrintable = requires(Debug& dbg, const T& value) { { dbg << value } -> std::convertible_to; }; } // namespace floormat namespace floormat::detail::corrade_debug { // ***** colon ***** struct Colon { char c; }; Debug& operator<<(Debug& dbg, Colon box); // ***** error string ***** struct ErrorString { int value; }; Debug& operator<<(Debug& dbg, ErrorString box); // ***** quoted ***** template struct Quoted { using type = T; T value; char c; }; Debug::Flags quoted_begin(Debug& dbg, char c); Debug& quoted_end(Debug& dbg, Debug::Flags flags, char c); template Debug& operator<<(Debug& dbg, Quoted box) { Debug::Flags flags = quoted_begin(dbg, box.c); dbg << box.value; return quoted_end(dbg, flags, box.c); } // ***** float ***** struct Fraction { float value; int decimal_points; }; Debug& operator<<(Debug& dbg, Fraction frac); } // namespace floormat::detail::corrade_debug // ***** api ***** // ***** functions ***** namespace floormat { std::istream* standard_input(); std::ostream* standard_output(); std::ostream* standard_error(); floormat::detail::corrade_debug::Colon colon(char c = ':'); floormat::detail::corrade_debug::ErrorString error_string(int error); floormat::detail::corrade_debug::ErrorString error_string(); floormat::detail::corrade_debug::Fraction fraction(float value, int decimal_points = 1); template auto quoted(T&& value, char c = '\'') { using U = std::remove_cvref_t; using floormat::detail::corrade_debug::Quoted; if constexpr(std::is_rvalue_reference_v) return Quoted{ .value = move(value), .c = c }; else return Quoted{ .value = value, .c = c }; } template auto quoted2(T&& value) { return quoted(forward(value), '"'); } // todo add operator for joining two printable items without spaces (when spaces are normally on) } // namespace floormat