Created
October 15, 2016 22:02
-
-
Save dpjudas/6f501e782dec84a8f9ff8e00bf481dc0 to your computer and use it in GitHub Desktop.
C++11 formatting example using variadic template args
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Program output: | |
mbn@cuba:~/Development$ clang -std=c++11 -o format format.cpp -lstdc++ | |
mbn@cuba:~/Development$ ./format | |
This is a foobar string with a 666 number | |
This is a moobar string with a 333 number | |
This is a foobar string with moobar and woobar with a 333 number | |
*/ | |
#include <string> | |
#include <iostream> | |
class FString | |
{ | |
public: | |
FString() { } | |
FString(const char *s) : buffer(s) { } | |
void Format(const char *format) | |
{ | |
buffer += format; | |
} | |
template<typename T, typename... Args> | |
void Format(const char *format, T value, Args && ... args) | |
{ | |
Format(FormatNextArg(format, value), args...); | |
} | |
template<typename... Args> | |
void Format(const char *format, const std::string &str, Args && ... args) | |
{ | |
Format(format, str.c_str(), args...); | |
} | |
template<typename... Args> | |
void Format(const char *format, const FString &str, Args && ... args) | |
{ | |
Format(format, str.GetBytes(), args...); | |
} | |
const char *GetBytes() const { return buffer.c_str(); } | |
private: | |
const char *FormatNextArg(const char *format, ...) | |
{ | |
va_list args; | |
va_start(args, format); | |
for (; format[0] != 0; format++) | |
{ | |
if (format[0] == '%') | |
{ | |
if (format[1] == 's') | |
{ | |
buffer += va_arg(args, const char*); | |
format += 2; | |
break; | |
} | |
else if (format[1] == 'd') | |
{ | |
buffer += std::to_string(va_arg(args, int)); | |
format += 2; | |
break; | |
} | |
} | |
buffer.push_back(format[0]); | |
} | |
va_end(args); | |
return format; | |
} | |
std::string buffer; | |
}; | |
int main(int, char**) | |
{ | |
FString s1, s2, s3; | |
s1.Format("This is a %s string with a %d number", "foobar", 666); | |
std::cout << s1.GetBytes() << std::endl; | |
std::string moo = "moobar"; | |
s2.Format("This is a %s string with a %d number", moo, 333); | |
std::cout << s2.GetBytes() << std::endl; | |
FString woo = "woobar"; | |
s3.Format("This is a %s string with %s and %s with a %d number", "foobar", moo, woo, 333); | |
std::cout << s3.GetBytes() << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment