numeric.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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 <boost/shared_ptr.hpp>
  16. #include <sstream>
  17. #include <stdlib.h>
  18. #include <time.h>
  19. #include <string.h>
  20. #include <wctype.h>
  21. #include <ctype.h>
  22. #include "all_generator.hpp"
  23. #include "api.hpp"
  24. #include "../util/numeric.hpp"
  25. namespace boost {
  26. namespace locale {
  27. namespace impl_win {
  28. namespace {
  29. std::ostreambuf_iterator<wchar_t> write_it(std::ostreambuf_iterator<wchar_t> out,std::wstring const &s)
  30. {
  31. for(size_t i=0;i<s.size();i++)
  32. *out++ = s[i];
  33. return out;
  34. }
  35. std::ostreambuf_iterator<char> write_it(std::ostreambuf_iterator<char> out,std::wstring const &s)
  36. {
  37. std::string tmp = conv::from_utf(s,"UTF-8");
  38. for(size_t i=0;i<tmp.size();i++)
  39. *out++ = tmp[i];
  40. return out;
  41. }
  42. }
  43. template<typename CharType>
  44. class num_format : public util::base_num_format<CharType>
  45. {
  46. public:
  47. typedef typename std::num_put<CharType>::iter_type iter_type;
  48. typedef std::basic_string<CharType> string_type;
  49. typedef CharType char_type;
  50. num_format(winlocale const &lc,size_t refs = 0) :
  51. util::base_num_format<CharType>(refs),
  52. lc_(lc)
  53. {
  54. }
  55. private:
  56. virtual
  57. iter_type do_format_currency(bool /*intl*/,iter_type out,std::ios_base &ios,char_type fill,long double val) const
  58. {
  59. if(lc_.is_c()) {
  60. std::locale loc = ios.getloc();
  61. int digits = std::use_facet<std::moneypunct<char_type> >(loc).frac_digits();
  62. while(digits > 0) {
  63. val*=10;
  64. digits --;
  65. }
  66. std::ios_base::fmtflags f=ios.flags();
  67. ios.flags(f | std::ios_base::showbase);
  68. out = std::use_facet<std::money_put<char_type> >(loc).put(out,false,ios,fill,val);
  69. ios.flags(f);
  70. return out;
  71. }
  72. else {
  73. std::wstring cur = wcsfmon_l(val,lc_);
  74. return write_it(out,cur);
  75. }
  76. }
  77. private:
  78. winlocale lc_;
  79. }; /// num_format
  80. template<typename CharType>
  81. class time_put_win : public std::time_put<CharType> {
  82. public:
  83. time_put_win(winlocale const &lc, size_t refs = 0) :
  84. std::time_put<CharType>(refs),
  85. lc_(lc)
  86. {
  87. }
  88. virtual ~time_put_win()
  89. {
  90. }
  91. typedef typename std::time_put<CharType>::iter_type iter_type;
  92. typedef CharType char_type;
  93. typedef std::basic_string<char_type> string_type;
  94. virtual iter_type do_put( iter_type out,
  95. std::ios_base &/*ios*/,
  96. CharType /*fill*/,
  97. std::tm const *tm,
  98. char format,
  99. char /*modifier*/) const
  100. {
  101. return write_it(out,wcsftime_l(format,tm,lc_));
  102. }
  103. private:
  104. winlocale lc_;
  105. };
  106. template<typename CharType>
  107. class num_punct_win : public std::numpunct<CharType> {
  108. public:
  109. typedef std::basic_string<CharType> string_type;
  110. num_punct_win(winlocale const &lc,size_t refs = 0) :
  111. std::numpunct<CharType>(refs)
  112. {
  113. numeric_info np = wcsnumformat_l(lc) ;
  114. if(sizeof(CharType) == 1 && np.thousands_sep == L"\xA0")
  115. np.thousands_sep=L" ";
  116. to_str(np.thousands_sep,thousands_sep_);
  117. to_str(np.decimal_point,decimal_point_);
  118. grouping_ = np.grouping;
  119. if(thousands_sep_.size() > 1)
  120. grouping_ = std::string();
  121. if(decimal_point_.size() > 1)
  122. decimal_point_ = CharType('.');
  123. }
  124. void to_str(std::wstring &s1,std::wstring &s2)
  125. {
  126. s2.swap(s1);
  127. }
  128. void to_str(std::wstring &s1,std::string &s2)
  129. {
  130. s2=conv::from_utf(s1,"UTF-8");
  131. }
  132. virtual CharType do_decimal_point() const
  133. {
  134. return *decimal_point_.c_str();
  135. }
  136. virtual CharType do_thousands_sep() const
  137. {
  138. return *thousands_sep_.c_str();
  139. }
  140. virtual std::string do_grouping() const
  141. {
  142. return grouping_;
  143. }
  144. virtual string_type do_truename() const
  145. {
  146. static const char t[]="true";
  147. return string_type(t,t+sizeof(t)-1);
  148. }
  149. virtual string_type do_falsename() const
  150. {
  151. static const char t[]="false";
  152. return string_type(t,t+sizeof(t)-1);
  153. }
  154. private:
  155. string_type decimal_point_;
  156. string_type thousands_sep_;
  157. std::string grouping_;
  158. };
  159. template<typename CharType>
  160. std::locale create_formatting_impl(std::locale const &in,winlocale const &lc)
  161. {
  162. if(lc.is_c()) {
  163. std::locale tmp(in,new std::numpunct_byname<CharType>("C"));
  164. tmp=std::locale(tmp,new std::time_put_byname<CharType>("C"));
  165. tmp = std::locale(tmp,new num_format<CharType>(lc));
  166. return tmp;
  167. }
  168. else {
  169. std::locale tmp(in,new num_punct_win<CharType>(lc));
  170. tmp = std::locale(tmp,new time_put_win<CharType>(lc));
  171. tmp = std::locale(tmp,new num_format<CharType>(lc));
  172. return tmp;
  173. }
  174. }
  175. template<typename CharType>
  176. std::locale create_parsing_impl(std::locale const &in,winlocale const &lc)
  177. {
  178. std::numpunct<CharType> *np = 0;
  179. if(lc.is_c())
  180. np = new std::numpunct_byname<CharType>("C");
  181. else
  182. np = new num_punct_win<CharType>(lc);
  183. std::locale tmp(in,np);
  184. tmp = std::locale(tmp,new util::base_num_parse<CharType>());
  185. return tmp;
  186. }
  187. std::locale create_formatting( std::locale const &in,
  188. winlocale const &lc,
  189. character_facet_type type)
  190. {
  191. switch(type) {
  192. case char_facet:
  193. return create_formatting_impl<char>(in,lc);
  194. case wchar_t_facet:
  195. return create_formatting_impl<wchar_t>(in,lc);
  196. default:
  197. return in;
  198. }
  199. }
  200. std::locale create_parsing( std::locale const &in,
  201. winlocale const &lc,
  202. character_facet_type type)
  203. {
  204. switch(type) {
  205. case char_facet:
  206. return create_parsing_impl<char>(in,lc);
  207. case wchar_t_facet:
  208. return create_parsing_impl<wchar_t>(in,lc);
  209. default:
  210. return in;
  211. }
  212. }
  213. } // impl_std
  214. } // locale
  215. } //boost
  216. // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4