@@ -955,14 +955,15 @@ inline void vformat(std::ostream& out, const char* fmt, FormatListRef list)
955
955
#ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES
956
956
957
957
// / Format list of arguments to the stream according to given format string.
958
+ // / This honors the stream's existing locale conventions.
958
959
template <typename ... Args>
959
960
void format (std::ostream& out, const char * fmt, const Args&... args)
960
961
{
961
962
vformat (out, fmt, makeFormatList (args...));
962
963
}
963
964
964
965
// / 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 .
966
967
template <typename ... Args>
967
968
std::string format (const char * fmt, const Args&... args)
968
969
{
@@ -972,6 +973,7 @@ std::string format(const char* fmt, const Args&... args)
972
973
}
973
974
974
975
// / Format list of arguments to std::cout, according to the given format string
976
+ // / This honors std::out's existing locale conventions.
975
977
template <typename ... Args>
976
978
void printf (const char * fmt, const Args&... args)
977
979
{
@@ -986,6 +988,44 @@ void printfln(const char* fmt, const Args&... args)
986
988
}
987
989
988
990
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
+
989
1029
#else // C++98 version
990
1030
991
1031
inline void format (std::ostream& out, const char * fmt)
@@ -1011,6 +1051,31 @@ inline void printfln(const char* fmt)
1011
1051
std::cout << ' \n ' ;
1012
1052
}
1013
1053
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
+
1014
1079
#define TINYFORMAT_MAKE_FORMAT_FUNCS (n ) \
1015
1080
\
1016
1081
template <TINYFORMAT_ARGTYPES(n)> \
@@ -1038,6 +1103,36 @@ void printfln(const char* fmt, TINYFORMAT_VARARGS(n)) \
1038
1103
{ \
1039
1104
format (std::cout, fmt, TINYFORMAT_PASSARGS (n)); \
1040
1105
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 ' ; \
1041
1136
}
1042
1137
1043
1138
TINYFORMAT_FOREACH_ARGNUM (TINYFORMAT_MAKE_FORMAT_FUNCS)
0 commit comments