]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/locale/src/std/numeric.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / locale / src / std / numeric.cpp
1 //
2 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 #define BOOST_LOCALE_SOURCE
9 #include <locale>
10 #include <string>
11 #include <ios>
12 #include <boost/locale/formatting.hpp>
13 #include <boost/locale/generator.hpp>
14 #include <boost/locale/encoding.hpp>
15 #include <sstream>
16 #include <stdlib.h>
17
18 #include "../util/numeric.hpp"
19 #include "all_generator.hpp"
20
21 namespace boost {
22 namespace locale {
23 namespace impl_std {
24
25 template<typename CharType>
26 class time_put_from_base : public std::time_put<CharType> {
27 public:
28 time_put_from_base(std::locale const &base, size_t refs = 0) :
29 std::time_put<CharType>(refs),
30 base_(base)
31 {
32 }
33 typedef typename std::time_put<CharType>::iter_type iter_type;
34
35 virtual iter_type do_put(iter_type out,std::ios_base &/*ios*/,CharType fill,std::tm const *tm,char format,char modifier) const
36 {
37 std::basic_stringstream<CharType> ss;
38 ss.imbue(base_);
39 return std::use_facet<std::time_put<CharType> >(base_).put(out,ss,fill,tm,format,modifier);
40 }
41 private:
42 std::locale base_;
43 };
44
45 class utf8_time_put_from_wide : public std::time_put<char> {
46 public:
47 utf8_time_put_from_wide(std::locale const &base, size_t refs = 0) :
48 std::time_put<char>(refs),
49 base_(base)
50 {
51 }
52 virtual iter_type do_put(iter_type out,std::ios_base &/*ios*/,char fill,std::tm const *tm,char format,char modifier = 0) const
53 {
54 std::basic_ostringstream<wchar_t> wtmps;
55 wtmps.imbue(base_);
56 std::use_facet<std::time_put<wchar_t> >(base_).put(wtmps,wtmps,wchar_t(fill),tm,wchar_t(format),wchar_t(modifier));
57 std::wstring wtmp=wtmps.str();
58 std::string const tmp = conv::from_utf<wchar_t>(wtmp,"UTF-8");
59 for(unsigned i=0;i<tmp.size();i++) {
60 *out++ = tmp[i];
61 }
62 return out;
63 }
64 private:
65 std::locale base_;
66 };
67
68 class utf8_numpunct_from_wide : public std::numpunct<char> {
69 public:
70 utf8_numpunct_from_wide(std::locale const &base,size_t refs = 0) : std::numpunct<char>(refs)
71 {
72 typedef std::numpunct<wchar_t> wfacet_type;
73 wfacet_type const &wfacet = std::use_facet<wfacet_type>(base);
74
75 truename_ = conv::from_utf<wchar_t>(wfacet.truename(),"UTF-8");
76 falsename_ = conv::from_utf<wchar_t>(wfacet.falsename(),"UTF-8");
77
78 wchar_t tmp_decimal_point = wfacet.decimal_point();
79 wchar_t tmp_thousands_sep = wfacet.thousands_sep();
80 std::string tmp_grouping = wfacet.grouping();
81
82 if( 32 <= tmp_thousands_sep && tmp_thousands_sep <=126 &&
83 32 <= tmp_decimal_point && tmp_decimal_point <=126)
84 {
85 thousands_sep_ = static_cast<char>(tmp_thousands_sep);
86 decimal_point_ = static_cast<char>(tmp_decimal_point);
87 grouping_ = tmp_grouping;
88 }
89 else if(32 <= tmp_decimal_point && tmp_decimal_point <=126 && tmp_thousands_sep == 0xA0) {
90 // workaround common bug - substitute NBSP with ordinary space
91 thousands_sep_ = ' ';
92 decimal_point_ = static_cast<char>(tmp_decimal_point);
93 grouping_ = tmp_grouping;
94 }
95 else if(32 <= tmp_decimal_point && tmp_decimal_point <=126)
96 {
97 thousands_sep_=',';
98 decimal_point_ = static_cast<char>(tmp_decimal_point);
99 grouping_=std::string();
100 }
101 else {
102 thousands_sep_ = ',';
103 decimal_point_ = '.';
104 grouping_=std::string();
105 }
106 }
107
108 virtual char do_decimal_point() const
109 {
110 return decimal_point_;
111 }
112 virtual char do_thousands_sep() const
113 {
114 return thousands_sep_;
115 }
116 virtual std::string do_grouping() const
117 {
118 return grouping_;
119 }
120 virtual std::string do_truename() const
121 {
122 return truename_;
123 }
124 virtual std::string do_falsename() const
125 {
126 return falsename_;
127 }
128 private:
129 std::string truename_;
130 std::string falsename_;
131 char thousands_sep_;
132 char decimal_point_;
133 std::string grouping_;
134
135 };
136
137 template<bool Intl>
138 class utf8_moneypunct_from_wide : public std::moneypunct<char,Intl> {
139 public:
140 utf8_moneypunct_from_wide(std::locale const &base,size_t refs = 0) : std::moneypunct<char,Intl>(refs)
141 {
142 typedef std::moneypunct<wchar_t,Intl> wfacet_type;
143 wfacet_type const &wfacet = std::use_facet<wfacet_type>(base);
144
145 curr_symbol_ = conv::from_utf<wchar_t>(wfacet.curr_symbol(),"UTF-8");
146 positive_sign_ = conv::from_utf<wchar_t>(wfacet.positive_sign(),"UTF-8");
147 negative_sign_ = conv::from_utf<wchar_t>(wfacet.negative_sign(),"UTF-8");
148 frac_digits_ = wfacet.frac_digits();
149 pos_format_ = wfacet.pos_format();
150 neg_format_ = wfacet.neg_format();
151
152 wchar_t tmp_decimal_point = wfacet.decimal_point();
153 wchar_t tmp_thousands_sep = wfacet.thousands_sep();
154 std::string tmp_grouping = wfacet.grouping();
155 if( 32 <= tmp_thousands_sep && tmp_thousands_sep <=126 &&
156 32 <= tmp_decimal_point && tmp_decimal_point <=126)
157 {
158 thousands_sep_ = static_cast<char>(tmp_thousands_sep);
159 decimal_point_ = static_cast<char>(tmp_decimal_point);
160 grouping_ = tmp_grouping;
161 }
162 else if(32 <= tmp_decimal_point && tmp_decimal_point <=126 && tmp_thousands_sep == 0xA0) {
163 // workaround common bug - substitute NBSP with ordinary space
164 thousands_sep_ = ' ';
165 decimal_point_ = static_cast<char>(tmp_decimal_point);
166 grouping_ = tmp_grouping;
167 }
168 else if(32 <= tmp_decimal_point && tmp_decimal_point <=126)
169 {
170 thousands_sep_=',';
171 decimal_point_ = static_cast<char>(tmp_decimal_point);
172 grouping_=std::string();
173 }
174 else {
175 thousands_sep_ = ',';
176 decimal_point_ = '.';
177 grouping_=std::string();
178 }
179 }
180
181 virtual char do_decimal_point() const
182 {
183 return decimal_point_;
184 }
185
186 virtual char do_thousands_sep() const
187 {
188 return thousands_sep_;
189 }
190
191 virtual std::string do_grouping() const
192 {
193 return grouping_;
194 }
195
196 virtual std::string do_curr_symbol() const
197 {
198 return curr_symbol_;
199 }
200 virtual std::string do_positive_sign () const
201 {
202 return positive_sign_;
203 }
204 virtual std::string do_negative_sign() const
205 {
206 return negative_sign_;
207 }
208
209 virtual int do_frac_digits() const
210 {
211 return frac_digits_;
212 }
213
214 virtual std::money_base::pattern do_pos_format() const
215 {
216 return pos_format_;
217 }
218
219 virtual std::money_base::pattern do_neg_format() const
220 {
221 return neg_format_;
222 }
223
224 private:
225 char thousands_sep_;
226 char decimal_point_;
227 std::string grouping_;
228 std::string curr_symbol_;
229 std::string positive_sign_;
230 std::string negative_sign_;
231 int frac_digits_;
232 std::money_base::pattern pos_format_,neg_format_;
233
234 };
235
236 class utf8_numpunct : public std::numpunct_byname<char> {
237 public:
238 typedef std::numpunct_byname<char> base_type;
239 utf8_numpunct(char const *name,size_t refs = 0) :
240 std::numpunct_byname<char>(name,refs)
241 {
242 }
243 virtual char do_thousands_sep() const
244 {
245 unsigned char bs = base_type::do_thousands_sep();
246 if(bs > 127)
247 if(bs == 0xA0)
248 return ' ';
249 else
250 return 0;
251 else
252 return bs;
253 }
254 virtual std::string do_grouping() const
255 {
256 unsigned char bs = base_type::do_thousands_sep();
257 if(bs > 127 && bs != 0xA0)
258 return std::string();
259 return base_type::do_grouping();
260 }
261 };
262
263 template<bool Intl>
264 class utf8_moneypunct : public std::moneypunct_byname<char,Intl> {
265 public:
266 typedef std::moneypunct_byname<char,Intl> base_type;
267 utf8_moneypunct(char const *name,size_t refs = 0) :
268 std::moneypunct_byname<char,Intl>(name,refs)
269 {
270 }
271 virtual char do_thousands_sep() const
272 {
273 unsigned char bs = base_type::do_thousands_sep();
274 if(bs > 127)
275 if(bs == 0xA0)
276 return ' ';
277 else
278 return 0;
279 else
280 return bs;
281 }
282 virtual std::string do_grouping() const
283 {
284 unsigned char bs = base_type::do_thousands_sep();
285 if(bs > 127 && bs != 0xA0)
286 return std::string();
287 return base_type::do_grouping();
288 }
289 };
290
291
292 template<typename CharType>
293 std::locale create_basic_parsing(std::locale const &in,std::string const &locale_name)
294 {
295 std::locale tmp = std::locale(in,new std::numpunct_byname<CharType>(locale_name.c_str()));
296 tmp = std::locale(tmp,new std::moneypunct_byname<CharType,true>(locale_name.c_str()));
297 tmp = std::locale(tmp,new std::moneypunct_byname<CharType,false>(locale_name.c_str()));
298 tmp = std::locale(tmp,new std::ctype_byname<CharType>(locale_name.c_str()));
299 return tmp;
300 }
301
302 template<typename CharType>
303 std::locale create_basic_formatting(std::locale const &in,std::string const &locale_name)
304 {
305 std::locale tmp = create_basic_parsing<CharType>(in,locale_name);
306 std::locale base(locale_name.c_str());
307 tmp = std::locale(tmp,new time_put_from_base<CharType>(base));
308 return tmp;
309 }
310
311
312 std::locale create_formatting( std::locale const &in,
313 std::string const &locale_name,
314 character_facet_type type,
315 utf8_support utf)
316 {
317 switch(type) {
318 case char_facet:
319 {
320 if(utf == utf8_from_wide ) {
321 std::locale base = std::locale(locale_name.c_str());
322
323 std::locale tmp = std::locale(in,new utf8_time_put_from_wide(base));
324 tmp = std::locale(tmp,new utf8_numpunct_from_wide(base));
325 tmp = std::locale(tmp,new utf8_moneypunct_from_wide<true>(base));
326 tmp = std::locale(tmp,new utf8_moneypunct_from_wide<false>(base));
327 return std::locale(tmp,new util::base_num_format<char>());
328 }
329 else if(utf == utf8_native) {
330 std::locale base = std::locale(locale_name.c_str());
331
332 std::locale tmp = std::locale(in,new time_put_from_base<char>(base));
333 tmp = std::locale(tmp,new utf8_numpunct(locale_name.c_str()));
334 tmp = std::locale(tmp,new utf8_moneypunct<true>(locale_name.c_str()));
335 tmp = std::locale(tmp,new utf8_moneypunct<false>(locale_name.c_str()));
336 return std::locale(tmp,new util::base_num_format<char>());
337 }
338 else if(utf == utf8_native_with_wide) {
339 std::locale base = std::locale(locale_name.c_str());
340
341 std::locale tmp = std::locale(in,new time_put_from_base<char>(base));
342 tmp = std::locale(tmp,new utf8_numpunct_from_wide(base));
343 tmp = std::locale(tmp,new utf8_moneypunct_from_wide<true>(base));
344 tmp = std::locale(tmp,new utf8_moneypunct_from_wide<false>(base));
345 return std::locale(tmp,new util::base_num_format<char>());
346 }
347 else
348 {
349 std::locale tmp = create_basic_formatting<char>(in,locale_name);
350 tmp = std::locale(tmp,new util::base_num_format<char>());
351 return tmp;
352 }
353 }
354 case wchar_t_facet:
355 {
356 std::locale tmp = create_basic_formatting<wchar_t>(in,locale_name);
357 tmp = std::locale(tmp,new util::base_num_format<wchar_t>());
358 return tmp;
359 }
360 #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
361 case char16_t_facet:
362 {
363 std::locale tmp = create_basic_formatting<char16_t>(in,locale_name);
364 tmp = std::locale(tmp,new util::base_num_format<char16_t>());
365 return tmp;
366 }
367 #endif
368 #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
369 case char32_t_facet:
370 {
371 std::locale tmp = create_basic_formatting<char32_t>(in,locale_name);
372 tmp = std::locale(tmp,new util::base_num_format<char32_t>());
373 return tmp;
374 }
375 #endif
376 default:
377 return in;
378 }
379 }
380
381 std::locale create_parsing( std::locale const &in,
382 std::string const &locale_name,
383 character_facet_type type,
384 utf8_support utf)
385 {
386 switch(type) {
387 case char_facet:
388 {
389 if(utf == utf8_from_wide ) {
390 std::locale base = std::locale::classic();
391
392 base = std::locale(base,new std::numpunct_byname<wchar_t>(locale_name.c_str()));
393 base = std::locale(base,new std::moneypunct_byname<wchar_t,true>(locale_name.c_str()));
394 base = std::locale(base,new std::moneypunct_byname<wchar_t,false>(locale_name.c_str()));
395
396 std::locale tmp = std::locale(in,new utf8_numpunct_from_wide(base));
397 tmp = std::locale(tmp,new utf8_moneypunct_from_wide<true>(base));
398 tmp = std::locale(tmp,new utf8_moneypunct_from_wide<false>(base));
399 return std::locale(tmp,new util::base_num_parse<char>());
400 }
401 else if(utf == utf8_native) {
402 std::locale tmp = std::locale(in,new utf8_numpunct(locale_name.c_str()));
403 tmp = std::locale(tmp,new utf8_moneypunct<true>(locale_name.c_str()));
404 tmp = std::locale(tmp,new utf8_moneypunct<false>(locale_name.c_str()));
405 return std::locale(tmp,new util::base_num_parse<char>());
406 }
407 else if(utf == utf8_native_with_wide) {
408 std::locale base = std::locale(locale_name.c_str());
409
410 std::locale tmp = std::locale(in,new utf8_numpunct_from_wide(base));
411 tmp = std::locale(tmp,new utf8_moneypunct_from_wide<true>(base));
412 tmp = std::locale(tmp,new utf8_moneypunct_from_wide<false>(base));
413 return std::locale(tmp,new util::base_num_parse<char>());
414 }
415 else
416 {
417 std::locale tmp = create_basic_parsing<char>(in,locale_name);
418 tmp = std::locale(in,new util::base_num_parse<char>());
419 return tmp;
420 }
421 }
422 case wchar_t_facet:
423 {
424 std::locale tmp = create_basic_parsing<wchar_t>(in,locale_name);
425 tmp = std::locale(in,new util::base_num_parse<wchar_t>());
426 return tmp;
427 }
428 #ifdef BOOST_LOCALE_ENABLE_CHAR16_T
429 case char16_t_facet:
430 {
431 std::locale tmp = create_basic_parsing<char16_t>(in,locale_name);
432 tmp = std::locale(in,new util::base_num_parse<char16_t>());
433 return tmp;
434 }
435 #endif
436 #ifdef BOOST_LOCALE_ENABLE_CHAR32_T
437 case char32_t_facet:
438 {
439 std::locale tmp = create_basic_parsing<char32_t>(in,locale_name);
440 tmp = std::locale(in,new util::base_num_parse<char32_t>());
441 return tmp;
442 }
443 #endif
444 default:
445 return in;
446 }
447 }
448
449
450 } // impl_std
451 } // locale
452 } //boost
453
454
455
456 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4