@@ -955,14 +955,15 @@ inline void vformat(std::ostream& out, const char* fmt, FormatListRef list)
955955#ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES
956956
957957// / Format list of arguments to the stream according to given format string.
958+ // / This honors the stream's existing locale conventions.
958959template <typename ... Args>
959960void format (std::ostream& out, const char * fmt, const Args&... args)
960961{
961962 vformat (out, fmt, makeFormatList (args...));
962963}
963964
964965// / Format list of arguments according to the given format string and return
965- // / the result as a string.
966+ // / the result as a string, honoring the current global native locale .
966967template <typename ... Args>
967968std::string format (const char * fmt, const Args&... args)
968969{
@@ -972,6 +973,7 @@ std::string format(const char* fmt, const Args&... args)
972973}
973974
974975// / Format list of arguments to std::cout, according to the given format string
976+ // / This honors std::out's existing locale conventions.
975977template <typename ... Args>
976978void printf (const char * fmt, const Args&... args)
977979{
@@ -986,6 +988,44 @@ void printfln(const char* fmt, const Args&... args)
986988}
987989
988990
991+ // / Formatting functions ending in _c force the classic "C" locale (i.e. '.'
992+ // / for decimal). They may be more expensive than the default functions,
993+ // / but they are useful when you MUST be locale-independent (like for
994+ // / persistent saved output when you always need identical formatting
995+ // / that should not vary, or be mis-parsed if written by a computer set
996+ // / up for one locale but read by a computer with a different locale).
997+ template <typename ... Args>
998+ void format_c (std::ostream& out, const char * fmt, const Args&... args)
999+ {
1000+ // Force "C" locale but save the previous one asssociated with the stream
1001+ std::locale oldloc = out.imbue (std::locale::classic ());
1002+ vformat (out, fmt, makeFormatList (args...));
1003+ out.imbue (oldloc); // restore the original locale
1004+ }
1005+
1006+ template <typename ... Args>
1007+ std::string format_c (const char * fmt, const Args&... args)
1008+ {
1009+ std::ostringstream oss;
1010+ oss.imbue (std::locale::classic ()); // force "C" locale with '.' decimal
1011+ format (oss, fmt, args...);
1012+ return oss.str ();
1013+ }
1014+
1015+ template <typename ... Args>
1016+ void printf_c (const char * fmt, const Args&... args)
1017+ {
1018+ format_c (std::cout, fmt, args...);
1019+ }
1020+
1021+ template <typename ... Args>
1022+ void printfln_c (const char * fmt, const Args&... args)
1023+ {
1024+ format_c (std::cout, fmt, args...);
1025+ std::cout << ' \n ' ;
1026+ }
1027+
1028+
9891029#else // C++98 version
9901030
9911031inline void format (std::ostream& out, const char * fmt)
@@ -1011,6 +1051,31 @@ inline void printfln(const char* fmt)
10111051 std::cout << ' \n ' ;
10121052}
10131053
1054+ inline void format_c (std::ostream& out, const char * fmt)
1055+ {
1056+ std::locale oldloc = out.imbue (std::locale::classic ());
1057+ vformat (out, fmt, makeFormatList ());
1058+ out.imbue (oldloc); // restore the original locale
1059+ }
1060+
1061+ inline std::string format_c (const char * fmt)
1062+ {
1063+ std::ostringstream oss;
1064+ format_c (oss, fmt);
1065+ return oss.str ();
1066+ }
1067+
1068+ inline void printf_c (const char * fmt)
1069+ {
1070+ format_c (std::cout, fmt);
1071+ }
1072+
1073+ inline void printfln_c (const char * fmt)
1074+ {
1075+ format_c (std::cout, fmt);
1076+ std::cout << ' \n ' ;
1077+ }
1078+
10141079#define TINYFORMAT_MAKE_FORMAT_FUNCS (n ) \
10151080 \
10161081template <TINYFORMAT_ARGTYPES(n)> \
@@ -1038,6 +1103,36 @@ void printfln(const char* fmt, TINYFORMAT_VARARGS(n)) \
10381103{ \
10391104 format (std::cout, fmt, TINYFORMAT_PASSARGS (n)); \
10401105 std::cout << ' \n ' ; \
1106+ } \
1107+ \
1108+ template <TINYFORMAT_ARGTYPES(n)> \
1109+ void format_c (std::ostream& out, const char * fmt, TINYFORMAT_VARARGS(n)) \
1110+ { \
1111+ std::locale oldloc = out.imbue (std::locale::classic ()); \
1112+ vformat (out, fmt, makeFormatList (TINYFORMAT_PASSARGS (n))); \
1113+ out.imbue (oldloc); \
1114+ } \
1115+ \
1116+ template <TINYFORMAT_ARGTYPES(n)> \
1117+ std::string format_c (const char * fmt, TINYFORMAT_VARARGS(n)) \
1118+ { \
1119+ std::ostringstream oss; \
1120+ oss.imbue (std::locale::classic ()); \
1121+ format (oss, fmt, TINYFORMAT_PASSARGS (n)); \
1122+ return oss.str (); \
1123+ } \
1124+ \
1125+ template <TINYFORMAT_ARGTYPES(n)> \
1126+ void printf_c (const char * fmt, TINYFORMAT_VARARGS(n)) \
1127+ { \
1128+ format_c (std::cout, fmt, TINYFORMAT_PASSARGS (n)); \
1129+ } \
1130+ \
1131+ template <TINYFORMAT_ARGTYPES(n)> \
1132+ void printfln_c (const char * fmt, TINYFORMAT_VARARGS(n)) \
1133+ { \
1134+ format_c (std::cout, fmt, TINYFORMAT_PASSARGS (n)); \
1135+ std::cout << ' \n ' ; \
10411136}
10421137
10431138TINYFORMAT_FOREACH_ARGNUM (TINYFORMAT_MAKE_FORMAT_FUNCS)
0 commit comments