diff --git a/include/indentlog/print/quoted.hpp b/include/indentlog/print/quoted.hpp index 15d7a397..3691d874 100644 --- a/include/indentlog/print/quoted.hpp +++ b/include/indentlog/print/quoted.hpp @@ -12,136 +12,136 @@ #include namespace xo { - namespace print { - /* use this to avoid template conversion hassles - * since literal strings get treated as arrays - */ - template - char const * ccs(T x) { return x; } + namespace print { + /* use this to avoid template conversion hassles + * since literal strings get treated as arrays + */ + template + char const * ccs(T x) { return x; } - /* Printing cases: - * 1. T&&: - * move into quoted_impl. T must be moveable! - * 2. T&: - * copy reference into quoted_impl. - * similarly for T const &, copy reference into quoted_impl - */ + /* Printing cases: + * 1. T&&: + * move into quoted_impl. T must be moveable! + * 2. T&: + * copy reference into quoted_impl. + * similarly for T const &, copy reference into quoted_impl + */ - template - class quoted_impl { - public: - quoted_impl(bool unq_flag, T const & x) : unq_flag_{unq_flag}, value_{x} {} - quoted_impl(bool unq_flag, T && x) : unq_flag_{unq_flag}, value_{std::move(x)} {} + template + class quoted_impl { + public: + quoted_impl(bool unq_flag, T const & x) : unq_flag_{unq_flag}, value_{x} {} + quoted_impl(bool unq_flag, T && x) : unq_flag_{unq_flag}, value_{std::move(x)} {} - bool unq_flag() const { return unq_flag_; } - T const & value() const { return value_; } + bool unq_flag() const { return unq_flag_; } + T const & value() const { return value_; } - void print(std::ostream & os) const { - std::string xs = xo::tostr(value_); + void print(std::ostream & os) const { + std::string xs = xo::tostr(value_); - if (xs.empty()) { - /* print empty string as "" */ - os << "\"\""; - } else if ((xs.at(0) == '<') && (xs.at(xs.size() - 1) == '>')) { - /* assume string represents output of a well-formed object printer, - * and already self-escapes - */ - os << xs; - } else if (xs.find_first_of(" \"\n\r\\") == std::string::npos) { - /* no escapes needed, just print xs */ - if (unq_flag_) - os << xs; - else - os << "\"" << xs << "\""; - } else { - /* printed value contains a space - * and/or a must-be-escaped character. - * in any case, need quotes - */ + if (xs.empty()) { + /* always print empty string as "" */ + os << "\"\""; + } else if ((xs.at(0) == '<') && (xs.at(xs.size() - 1) == '>')) { + /* assume string represents output of a well-formed object printer, + * and already self-escapes + */ + os << xs; + } else if (xs.find_first_of(" \"\n\r\\") == std::string::npos) { + /* no escapes needed, just print xs */ + if (unq_flag_) + os << xs; + else + os << "\"" << xs << "\""; + } else { + /* printed value contains a space + * and/or a must-be-escaped character. + * in any case, need quotes + */ - os << "\""; + os << "\""; - /* print contents of ss, with escapes: - * \ => \\ - * " => \" - * newline => \n - * cr => \r - */ - for (char ch : xs) { - switch (ch) { - case '"': - /* " => \" */ - os << "\\\""; - break; - case '\n': - /* newline -> \n */ - os << "\\\n"; - break; - case '\r': - /* cr -> \r */ - os << "\\\r"; - break; - case '\\': - /* \ => \\ (mind c++ requires we escape \) */ - os << "\\\\"; - break; - default: - os << ch; - break; + /* print contents of ss, with escapes: + * \ => \\ + * " => \" + * newline => \n + * cr => \r + */ + for (char ch : xs) { + switch (ch) { + case '"': + /* " => \" */ + os << "\\\""; + break; + case '\n': + /* newline -> \n */ + os << "\\\n"; + break; + case '\r': + /* cr -> \r */ + os << "\\\r"; + break; + case '\\': + /* \ => \\ (mind c++ requires we escape \) */ + os << "\\\\"; + break; + default: + os << ch; + break; + } + } + + os << "\""; + } + } /*print*/ + + private: + /* .unq_flag: if true, omit surrounding " chars + * if printed value satisfies both: + * - no escaped chars + * - no spaces + */ + bool unq_flag_ = false; + /* .value: value to be printed */ + T value_; + }; /*quoted_impl*/ + + template + std::ostream & + operator<<(std::ostream & os, quoted_impl const & x) { + x.print(os); + return os; + } /*operator*/ + + /* writing out std::forward behavior for completeness' sake: + * + * 1. call quoted(x) with rvalue std::string x, then: + * - T will be deduced to [std::string] + * (in particular: _not_ std::string &, std::string const &, std::string &&) + * - rvalue std::string passed to quoted_impl ctor + * + * 2a. call quoted(x) with std::string & x, then: + * - T deduced to [std::string &] + * - std::string & passed to quoted_impl ctor + * + * 2b. call quoted(x) with std::string const & x, then: + * - T deduced to [std::string const &] + * - std::string const & passed to quoted_impl ctor + */ + template + auto quoted(T && x) { + return quoted_impl(false /*unq_flag*/, std::forward(x)); } - } - os << "\""; - } - } /*print*/ + inline auto qcstr(char const * x) { + return quoted(x); + } /*qcstr*/ - private: - /* .unq_flag: if true, omit surrounding " chars - * if printed value satisfies both: - * - no escaped chars - * - no spaces - */ - bool unq_flag_ = false; - /* .value: value to be printed */ - T value_; - }; /*quoted_impl*/ - - template - std::ostream & - operator<<(std::ostream & os, quoted_impl const & x) { - x.print(os); - return os; - } /*operator*/ - - /* writing out std::forward behavior for completeness' sake: - * - * 1. call quoted(x) with rvalue std::string x, then: - * - T will be deduced to [std::string] - * (in particular: _not_ std::string &, std::string const &, std::string &&) - * - rvalue std::string passed to quoted_impl ctor - * - * 2a. call quoted(x) with std::string & x, then: - * - T deduced to [std::string &] - * - std::string & passed to quoted_impl ctor - * - * 2b. call quoted(x) with std::string const & x, then: - * - T deduced to [std::string const &] - * - std::string const & passed to quoted_impl ctor - */ - template - auto quoted(T && x) { - return quoted_impl(false /*unq_flag*/, std::forward(x)); - } - - inline auto qcstr(char const * x) { - return quoted(x); - } /*qcstr*/ - - template - auto unq(T && x) { - return quoted_impl(true /*unq_flag*/, std::forward(x)); - } - } /*namespace print*/ + template + auto unq(T && x) { + return quoted_impl(true /*unq_flag*/, std::forward(x)); + } + } /*namespace print*/ } /*namespace xo*/ /* end quoted.hpp */