14
14
# include < climits>
15
15
# include < cmath>
16
16
# include < exception>
17
-
18
- # if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
19
- # include < locale>
20
- # endif
21
17
#endif
22
18
23
19
#if defined(_WIN32) && !defined(FMT_USE_WRITE_CONSOLE)
26
22
27
23
#include " format.h"
28
24
25
+ #ifdef FMT_USE_LOCALE
26
+ // Use the provided definition.
27
+ #elif defined(FMT_STATIC_THOUSANDS_SEPARATOR)
28
+ # define FMT_USE_LOCALE 0
29
+ #else
30
+ # define FMT_USE_LOCALE 1
31
+ #endif
32
+ #if FMT_USE_LOCALE
33
+ # include < locale>
34
+ #elif !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
35
+ # define FMT_STATIC_THOUSANDS_SEPARATOR ' ,'
36
+ #endif
37
+
29
38
FMT_BEGIN_NAMESPACE
30
39
namespace detail {
31
40
@@ -77,53 +86,56 @@ inline void fwrite_fully(const void* ptr, size_t count, FILE* stream) {
77
86
FMT_THROW (system_error (errno, FMT_STRING (" cannot write to file" )));
78
87
}
79
88
80
- #ifndef FMT_STATIC_THOUSANDS_SEPARATOR
89
+ #if FMT_USE_LOCALE
90
+ using std::locale;
91
+ using std::numpunct;
92
+ using std::use_facet;
93
+ #else
94
+ struct locale {};
95
+ template <typename Char> struct numpunct {
96
+ auto grouping () const -> std::string { return " \03 " ; }
97
+ auto thousands_sep () const -> Char { return FMT_STATIC_THOUSANDS_SEPARATOR; }
98
+ auto decimal_point () const -> Char { return ' .' ; }
99
+ };
100
+ template <typename Facet> Facet use_facet (locale) { return {}; }
101
+ #endif // FMT_USE_LOCALE
102
+
81
103
template <typename Locale>
82
104
locale_ref::locale_ref (const Locale& loc) : locale_(&loc) {
83
- static_assert (std::is_same<Locale, std:: locale>::value, " " );
105
+ static_assert (std::is_same<Locale, locale>::value, " " );
84
106
}
85
107
86
108
template <typename Locale> auto locale_ref::get () const -> Locale {
87
- static_assert (std::is_same<Locale, std:: locale>::value, " " );
88
- return locale_ ? *static_cast <const std:: locale*>(locale_) : std:: locale ();
109
+ static_assert (std::is_same<Locale, locale>::value, " " );
110
+ return locale_ ? *static_cast <const locale*>(locale_) : locale ();
89
111
}
90
112
91
113
template <typename Char>
92
114
FMT_FUNC auto thousands_sep_impl (locale_ref loc) -> thousands_sep_result<Char> {
93
- auto & facet = std:: use_facet<std:: numpunct<Char>>(loc.get <std:: locale>());
115
+ auto && facet = use_facet<numpunct<Char>>(loc.get <locale>());
94
116
auto grouping = facet.grouping ();
95
117
auto thousands_sep = grouping.empty () ? Char () : facet.thousands_sep ();
96
118
return {std::move (grouping), thousands_sep};
97
119
}
98
120
template <typename Char>
99
121
FMT_FUNC auto decimal_point_impl (locale_ref loc) -> Char {
100
- return std::use_facet<std::numpunct<Char>>(loc.get <std::locale>())
101
- .decimal_point ();
102
- }
103
- #else
104
- template <typename Char>
105
- FMT_FUNC auto thousands_sep_impl (locale_ref) -> thousands_sep_result<Char> {
106
- return {" \03 " , FMT_STATIC_THOUSANDS_SEPARATOR};
122
+ return use_facet<numpunct<Char>>(loc.get <locale>()).decimal_point ();
107
123
}
108
- template <typename Char> FMT_FUNC Char decimal_point_impl (locale_ref) {
109
- return ' .' ;
110
- }
111
- #endif
112
124
113
125
FMT_FUNC auto write_loc (appender out, loc_value value,
114
126
const format_specs& specs, locale_ref loc) -> bool {
115
- #ifdef FMT_STATIC_THOUSANDS_SEPARATOR
116
- value.visit (loc_writer<>{
117
- out, specs, std::string (1 , FMT_STATIC_THOUSANDS_SEPARATOR), " \3 " , " ." });
118
- return true ;
119
- #else
127
+ #if FMT_USE_LOCALE
120
128
auto locale = loc.get <std::locale>();
121
129
// We cannot use the num_put<char> facet because it may produce output in
122
130
// a wrong encoding.
123
131
using facet = format_facet<std::locale>;
124
132
if (std::has_facet<facet>(locale))
125
- return std:: use_facet<facet>(locale).put (out, value, specs);
133
+ return use_facet<facet>(locale).put (out, value, specs);
126
134
return facet (locale).put (out, value, specs);
135
+ #else
136
+ value.visit (loc_writer<>{
137
+ out, specs, std::string (1 , FMT_STATIC_THOUSANDS_SEPARATOR), " \3 " , " ." });
138
+ return true ;
127
139
#endif
128
140
}
129
141
} // namespace detail
@@ -134,13 +146,13 @@ FMT_FUNC void report_error(const char* message) {
134
146
135
147
template <typename Locale> typename Locale::id format_facet<Locale>::id;
136
148
137
- #ifndef FMT_STATIC_THOUSANDS_SEPARATOR
138
149
template <typename Locale> format_facet<Locale>::format_facet(Locale& loc) {
139
- auto & numpunct = std ::use_facet<std ::numpunct<char >>(loc);
140
- grouping_ = numpunct .grouping ();
141
- if (!grouping_.empty ()) separator_ = std::string (1 , numpunct .thousands_sep ());
150
+ auto & np = detail ::use_facet<detail ::numpunct<char >>(loc);
151
+ grouping_ = np .grouping ();
152
+ if (!grouping_.empty ()) separator_ = std::string (1 , np .thousands_sep ());
142
153
}
143
154
155
+ #if FMT_USE_LOCALE
144
156
template <>
145
157
FMT_API FMT_FUNC auto format_facet<std::locale>::do_put(
146
158
appender out, loc_value val, const format_specs& specs) const -> bool {
@@ -1019,7 +1031,8 @@ template <> struct cache_accessor<double> {
1019
1031
{0xe4d5e82392a40515 , 0x0fabaf3feaa5334b },
1020
1032
{0xb8da1662e7b00a17 , 0x3d6a751f3b936244 },
1021
1033
{0x95527a5202df0ccb , 0x0f37801e0c43ebc9 },
1022
- {0xf13e34aabb430a15 , 0x647726b9e7c68ff0 }
1034
+ { 0xf13e34aabb430a15 ,
1035
+ 0x647726b9e7c68ff0 }
1023
1036
#endif
1024
1037
};
1025
1038
0 commit comments