|
|
@ -5,18 +5,17 @@ |
|
|
|
#include <exception> |
|
|
|
#include <exception> |
|
|
|
#include <algorithm> |
|
|
|
#include <algorithm> |
|
|
|
#include <cctype> |
|
|
|
#include <cctype> |
|
|
|
|
|
|
|
namespace Bk { |
|
|
|
// base case of recursion, no more arguments
|
|
|
|
void format_impl(std::stringstream& ss, const char* format) {
|
|
|
|
void format_impl(std::stringstream& ss, const char* format) {
|
|
|
|
|
|
|
|
while (*format) { |
|
|
|
while (*format) { |
|
|
|
if (*format == '%' && *++format != '%') // %% == % (not a format directive)
|
|
|
|
if (*format == '%' && *++format != '%') // %% == % (not a format directive)
|
|
|
|
throw std::invalid_argument("not enough arguments !\n"); |
|
|
|
throw std::invalid_argument("not enough arguments !\n"); |
|
|
|
ss << *format++; |
|
|
|
ss << *format++; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <typename Arg, typename... Args> |
|
|
|
template <typename Arg, typename... Args> |
|
|
|
void format_impl(std::stringstream& ss, const char* format, Arg arg, Args... args) { |
|
|
|
void format_impl(std::stringstream& ss, const char* format, Arg arg, Args... args) { |
|
|
|
while (*format) { |
|
|
|
while (*format) { |
|
|
|
if (*format == '%' && *++format != '%') { |
|
|
|
if (*format == '%' && *++format != '%') { |
|
|
|
auto current_format_qualifier = *format; |
|
|
|
auto current_format_qualifier = *format; |
|
|
@ -45,11 +44,12 @@ void format_impl(std::stringstream& ss, const char* format, Arg arg, Args... arg |
|
|
|
ss << *format++; |
|
|
|
ss << *format++; |
|
|
|
} // the format string is exhausted and we still have args : throw
|
|
|
|
} // the format string is exhausted and we still have args : throw
|
|
|
|
throw std::invalid_argument("Too many arguments\n"); |
|
|
|
throw std::invalid_argument("Too many arguments\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <typename... Args> |
|
|
|
template <typename... Args> |
|
|
|
std::string format(const char* fmt, Args... args) { |
|
|
|
std::string format(const char* fmt, Args... args) { |
|
|
|
std::stringstream ss; |
|
|
|
std::stringstream ss; |
|
|
|
format_impl(ss, fmt, args...); |
|
|
|
format_impl(ss, fmt, args...); |
|
|
|
return ss.str(); |
|
|
|
return ss.str(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|