@@ -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