// ConsoleApplication1.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include #include #include // Unsigned integers template auto convert(char* out, size_t maxSize, size_t& written, T&& arg) -> std::enable_if_t>::value&& std::is_unsigned>::value, bool> { char* p = out; std::size_t c = 0; while (arg != 0) { if (++c > maxSize) return false; *p = '0' + (arg % 10); ++p; arg /= 10; } written = c; for (size_t i = 0; i < c / 2; ++i) { std::swap(out[i], out[c - i - 1]); } return true; } // Signed integers template auto convert(char* out, size_t maxSize, size_t& written, T&& arg) -> std::enable_if_t>::value&& std::is_signed>::value, bool> { char* p = out; std::size_t c = 0; bool neg = arg < 0; if (neg) { arg = -arg; ++p; } while (arg != 0) { if (++c > maxSize) return false; *p = '0' + (arg % 10); ++p; arg /= 10; } if (neg) { if (c + 1 > maxSize) return false; out[0] = '-'; p = out + 1; written = c + 1; } else { if (c > maxSize) return false; p = out; written = c; } for (size_t i = 0; i < c / 2; ++i) { std::swap(p[i], p[c - i - 1]); } return true; } // Characters bool convert(char* out, size_t maxSize, size_t& written, char arg) { if (maxSize < 1) return false; *out = arg; written = 1; return true; } // String Literals. Excludes the null termination character. template bool convert(char* out, size_t maxSize, size_t& written, const char (&str) [N]) { if (N - 1 > maxSize) return false; std::memcpy(out, str, N-1); written = N - 1; return true; } // C Strings bool convert(char* out, size_t maxSize, size_t& written, const char* str) { std::size_t len = std::strlen(str); if (len > maxSize) return false; std::memcpy(out, str, len); written = len; return true; } template bool format(char* out, size_t& size, Args&&... args) { bool cont = true; std::size_t remainingSize = size; auto lambda = [&](auto&& arg) { if (cont) { size_t written; if (!convert(out, remainingSize, written, std::forward(arg))) { cont = false; } else { remainingSize -= written; out += written; } } }; int dummy[] = { (lambda (std::forward(args)), 0)... }; static_cast (dummy); size = size - remainingSize; return cont; } template bool print(Args&&... args) { static char printBuffer[1024]; size_t size = sizeof(printBuffer); if (!format(printBuffer, size, std::forward(args)..., '\n')) return false; std::cout.write (printBuffer, size); return true; } int main() { const char* cString = "blubb"; print(12345U, -12, 'x', 27U, "blargh", cString); print("foo"); }