Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygen_monetary.c
Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 1999 00003 * Silicon Graphics Computer Systems, Inc. 00004 * 00005 * Copyright (c) 1999 00006 * Boris Fomitchev 00007 * 00008 * This material is provided "as is", with absolutely no warranty expressed 00009 * or implied. Any use is at your own risk. 00010 * 00011 * Permission to use or copy this software for any purpose is hereby granted 00012 * without fee, provided the above notices are retained on all copies. 00013 * Permission to modify the code and to distribute modified code is granted, 00014 * provided the above notices are retained, and a notice that the code was 00015 * modified is included with the above copyright notice. 00016 * 00017 */ 00018 #ifndef _STLP_MONETARY_C 00019 #define _STLP_MONETARY_C 00020 00021 # ifndef _STLP_INTERNAL_MONETARY_H 00022 # include <stl/_monetary.h> 00023 # endif 00024 00025 #ifndef _STLP_INTERNAL_IOS_H 00026 # include <stl/_ios.h> 00027 #endif 00028 00029 #ifndef _STLP_INTERNAL_NUM_PUT_H 00030 # include <stl/_num_put.h> 00031 #endif 00032 00033 #ifndef _STLP_INTERNAL_NUM_GET_H 00034 # include <stl/_num_get.h> 00035 #endif 00036 00037 _STLP_BEGIN_NAMESPACE 00038 00039 template <class _CharT, class _InputIterator> 00040 locale::id money_get<_CharT, _InputIterator>::id; 00041 00042 template <class _CharT, class _OutputIterator> 00043 locale::id money_put<_CharT, _OutputIterator>::id; 00044 00045 // money_get facets 00046 00047 _STLP_MOVE_TO_PRIV_NAMESPACE 00048 00049 // helper functions for do_get 00050 template <class _InIt1, class _InIt2> 00051 pair<_InIt1, bool> __get_string( _InIt1 __first, _InIt1 __last, 00052 _InIt2 __str_first, _InIt2 __str_last) { 00053 while ( __first != __last && __str_first != __str_last && *__first == *__str_first ) { 00054 ++__first; 00055 ++__str_first; 00056 } 00057 return make_pair(__first, __str_first == __str_last); 00058 } 00059 00060 template <class _InIt, class _OuIt, class _CharT> 00061 bool 00062 __get_monetary_value(_InIt& __first, _InIt __last, _OuIt __out_ite, 00063 const ctype<_CharT>& _c_type, 00064 _CharT __point, int __frac_digits, _CharT __sep, 00065 const string& __grouping, bool &__syntax_ok) { 00066 if (__first == __last || !_c_type.is(ctype_base::digit, *__first)) 00067 return false; 00068 00069 char __group_sizes[128]; 00070 char* __group_sizes_end = __grouping.empty()? 0 : __group_sizes; 00071 char __current_group_size = 0; 00072 00073 while (__first != __last) { 00074 if (_c_type.is(ctype_base::digit, *__first)) { 00075 ++__current_group_size; 00076 *__out_ite++ = *__first++; 00077 } 00078 else if (__group_sizes_end) { 00079 if (*__first == __sep) { 00080 *__group_sizes_end++ = __current_group_size; 00081 __current_group_size = 0; 00082 ++__first; 00083 } 00084 else break; 00085 } 00086 else 00087 break; 00088 } 00089 00090 if (__grouping.empty()) 00091 __syntax_ok = true; 00092 else { 00093 if (__group_sizes_end != __group_sizes) 00094 *__group_sizes_end++ = __current_group_size; 00095 00096 __syntax_ok = __valid_grouping(__group_sizes, __group_sizes_end, 00097 __grouping.data(), __grouping.data()+ __grouping.size()); 00098 00099 if (__first == __last || *__first != __point) { 00100 for (int __digits = 0; __digits != __frac_digits; ++__digits) 00101 *__out_ite++ = _CharT('0'); 00102 return true; // OK not to have decimal point 00103 } 00104 } 00105 00106 ++__first; 00107 00108 int __digits = 0; 00109 00110 while (__first != __last && _c_type.is(ctype_base::digit, *__first)) { 00111 *__out_ite++ = *__first++; 00112 ++__digits; 00113 } 00114 00115 __syntax_ok = __syntax_ok && (__digits == __frac_digits); 00116 00117 return true; 00118 } 00119 00120 00121 template <class _CharT, class _InputIter, class _StrType> 00122 _InputIter __money_do_get(_InputIter __s, _InputIter __end, bool __intl, 00123 ios_base& __str, ios_base::iostate& __err, 00124 _StrType& __digits, bool &__is_positive, _CharT* /*__dummy*/) { 00125 if (__s == __end) { 00126 __err |= ios_base::eofbit; 00127 return __s; 00128 } 00129 00130 typedef _CharT char_type; 00131 typedef _StrType string_type; 00132 typedef _InputIter iter_type; 00133 typedef moneypunct<char_type, false> _Punct; 00134 typedef moneypunct<char_type, true> _Punct_intl; 00135 typedef ctype<char_type> _Ctype; 00136 00137 locale __loc = __str.getloc(); 00138 const _Punct& __punct = use_facet<_Punct>(__loc) ; 00139 const _Punct_intl& __punct_intl = use_facet<_Punct_intl>(__loc) ; 00140 const _Ctype& __c_type = use_facet<_Ctype>(__loc) ; 00141 00142 money_base::pattern __format = __intl ? __punct_intl.neg_format() 00143 : __punct.neg_format(); 00144 string_type __ns = __intl ? __punct_intl.negative_sign() 00145 : __punct.negative_sign(); 00146 string_type __ps = __intl ? __punct_intl.positive_sign() 00147 : __punct.positive_sign(); 00148 int __i; 00149 bool __symbol_required = (__str.flags() & ios_base::showbase) != 0; 00150 string_type __buf; 00151 back_insert_iterator<string_type> __out_ite(__buf); 00152 00153 for (__i = 0; __i < 4; ++__i) { 00154 switch (__format.field[__i]) { 00155 case money_base::space: 00156 if (!__c_type.is(ctype_base::space, *__s)) { 00157 __err = ios_base::failbit; 00158 return __s; 00159 } 00160 ++__s; 00161 case money_base::none: 00162 while (__s != __end && __c_type.is(ctype_base::space, *__s)) 00163 ++__s; 00164 break; 00165 case money_base::symbol: { 00166 string_type __curs = __intl ? __punct_intl.curr_symbol() 00167 : __punct.curr_symbol(); 00168 pair<iter_type, bool> 00169 __result = __get_string(__s, __end, __curs.begin(), __curs.end()); 00170 if (!__result.second && __symbol_required) 00171 __err = ios_base::failbit; 00172 __s = __result.first; 00173 break; 00174 } 00175 case money_base::sign: { 00176 if (__s == __end) { 00177 if (__ps.empty()) 00178 break; 00179 if (__ns.empty()) { 00180 __is_positive = false; 00181 break; 00182 } 00183 __err = ios_base::failbit; 00184 return __s; 00185 } 00186 else { 00187 if (__ps.empty()) { 00188 if (__ns.empty()) 00189 break; 00190 if (*__s == __ns[0]) { 00191 ++__s; 00192 __is_positive = false; 00193 } 00194 break; 00195 } 00196 else { 00197 if (*__s == __ps[0]) { 00198 ++__s; 00199 break; 00200 } 00201 if (__ns.empty()) 00202 break; 00203 if (*__s == __ns[0]) { 00204 ++__s; 00205 __is_positive = false; 00206 break; 00207 } 00208 __err = ios_base::failbit; 00209 } 00210 } 00211 return __s; 00212 } 00213 case money_base::value: { 00214 char_type __point = __intl ? __punct_intl.decimal_point() 00215 : __punct.decimal_point(); 00216 int __frac_digits = __intl ? __punct_intl.frac_digits() 00217 : __punct.frac_digits(); 00218 string __grouping = __intl ? __punct_intl.grouping() 00219 : __punct.grouping(); 00220 bool __syntax_ok = true; 00221 00222 bool __result; 00223 00224 char_type __sep = __grouping.empty() ? char_type() : 00225 __intl ? __punct_intl.thousands_sep() : __punct.thousands_sep(); 00226 00227 __result = __get_monetary_value(__s, __end, __out_ite, __c_type, 00228 __point, __frac_digits, 00229 __sep, 00230 __grouping, __syntax_ok); 00231 00232 if (!__syntax_ok) 00233 __err |= ios_base::failbit; 00234 if (!__result) { 00235 __err = ios_base::failbit; 00236 return __s; 00237 } 00238 break; 00239 00240 } // Close money_base::value case 00241 } // Close switch statement 00242 } // Close for loop 00243 00244 if (__is_positive) { 00245 if (__ps.size() > 1) { 00246 pair<_InputIter, bool> 00247 __result = __get_string(__s, __end, __ps.begin() + 1, __ps.end()); 00248 __s = __result.first; 00249 if (!__result.second) 00250 __err |= ios::failbit; 00251 } 00252 if (!(__err & ios_base::failbit)) 00253 __digits = __buf; 00254 } 00255 else { 00256 if (__ns.size() > 1) { 00257 pair<_InputIter, bool> 00258 __result = __get_string(__s, __end, __ns.begin() + 1, __ns.end()); 00259 __s = __result.first; 00260 if (!__result.second) 00261 __err |= ios::failbit; 00262 } 00263 if (!(__err & ios::failbit)) { 00264 __digits = __c_type.widen('-'); 00265 __digits += __buf; 00266 } 00267 } 00268 if (__s == __end) 00269 __err |= ios::eofbit; 00270 00271 return __s; 00272 } 00273 00274 _STLP_MOVE_TO_STD_NAMESPACE 00275 00276 //===== methods ====== 00277 template <class _CharT, class _InputIter> 00278 _InputIter 00279 money_get<_CharT, _InputIter>::do_get(_InputIter __s, _InputIter __end, bool __intl, 00280 ios_base& __str, ios_base::iostate& __err, 00281 _STLP_LONGEST_FLOAT_TYPE& __units) const { 00282 string_type __buf; 00283 bool __is_positive = true; 00284 __s = _STLP_PRIV __money_do_get(__s, __end, __intl, __str, __err, __buf, __is_positive, (_CharT*)0); 00285 00286 if (__err == ios_base::goodbit || __err == ios_base::eofbit) { 00287 typename string_type::iterator __b = __buf.begin(), __e = __buf.end(); 00288 00289 if (!__is_positive) ++__b; 00290 // Can't use atold, since it might be wchar_t. Don't get confused by name below : 00291 // it's perfectly capable of reading long double. 00292 _STLP_PRIV __get_decimal_integer(__b, __e, __units, (_CharT*)0); 00293 00294 if (!__is_positive) { 00295 __units = -__units; 00296 } 00297 } 00298 00299 return __s; 00300 } 00301 00302 template <class _CharT, class _InputIter> 00303 _InputIter 00304 money_get<_CharT, _InputIter>::do_get(iter_type __s, iter_type __end, bool __intl, 00305 ios_base& __str, ios_base::iostate& __err, 00306 string_type& __digits) const { 00307 bool __is_positive = true; 00308 return _STLP_PRIV __money_do_get(__s, __end, __intl, __str, __err, __digits, __is_positive, (_CharT*)0); 00309 } 00310 00311 // money_put facets 00312 00313 _STLP_MOVE_TO_PRIV_NAMESPACE 00314 00315 template <class _CharT, class _OutputIter, class _Str_Type, class _Str> 00316 _OutputIter __money_do_put(_OutputIter __s, bool __intl, ios_base& __str, 00317 _CharT __fill, const _Str& __digits, bool __check_digits, 00318 _Str_Type * /*__dummy*/) { 00319 typedef _CharT char_type; 00320 typedef _Str_Type string_type; 00321 typedef ctype<char_type> _Ctype; 00322 typedef moneypunct<char_type, false> _Punct; 00323 typedef moneypunct<char_type, true> _Punct_intl; 00324 00325 locale __loc = __str.getloc(); 00326 const _Ctype& __c_type = use_facet<_Ctype>(__loc) ; 00327 const _Punct& __punct = use_facet<_Punct>(__loc) ; 00328 const _Punct_intl& __punct_intl = use_facet<_Punct_intl>(__loc) ; 00329 00330 // some special characters 00331 char_type __minus = __c_type.widen('-'); 00332 char_type __plus = __c_type.widen('+'); 00333 char_type __space = __c_type.widen(' '); 00334 char_type __zero = __c_type.widen('0'); 00335 char_type __point = __intl ? __punct_intl.decimal_point() 00336 : __punct.decimal_point(); 00337 00338 char_type __sep = __intl ? __punct_intl.thousands_sep() 00339 : __punct.thousands_sep(); 00340 00341 string __grouping = __intl ? __punct_intl.grouping() 00342 : __punct.grouping(); 00343 00344 int __frac_digits = __intl ? __punct_intl.frac_digits() 00345 : __punct.frac_digits(); 00346 00347 string_type __curr_sym = __intl ? __punct_intl.curr_symbol() 00348 : __punct.curr_symbol(); 00349 00350 // if there are no digits we are going to return __s. If there 00351 // are digits, but not enough to fill the frac_digits, we are 00352 // going to add zeros. I don't know whether this is right or 00353 // not. 00354 if (__digits.empty()) 00355 return __s; 00356 00357 typename string_type::const_iterator __digits_first = __digits.begin(); 00358 typename string_type::const_iterator __digits_last = __digits.end(); 00359 00360 bool __is_negative = *__digits_first == __minus; 00361 if (__is_negative) 00362 ++__digits_first; 00363 00364 #if !defined (__BORLANDC__) 00365 string_type __sign = __intl ? __is_negative ? __punct_intl.negative_sign() 00366 : __punct_intl.positive_sign() 00367 : __is_negative ? __punct.negative_sign() 00368 : __punct.positive_sign(); 00369 #else 00370 string_type __sign; 00371 if (__intl) { 00372 if (__is_negative) 00373 __sign = __punct_intl.negative_sign(); 00374 else 00375 __sign = __punct_intl.positive_sign(); 00376 } 00377 else { 00378 if (__is_negative) 00379 __sign = __punct.negative_sign(); 00380 else 00381 __sign = __punct.positive_sign(); 00382 } 00383 #endif 00384 00385 if (__check_digits) { 00386 typename string_type::const_iterator __cp = __digits_first; 00387 while (__cp != __digits_last && __c_type.is(ctype_base::digit, *__cp)) 00388 ++__cp; 00389 if (__cp == __digits_first) 00390 return __s; 00391 __digits_last = __cp; 00392 } 00393 00394 // If grouping is required, we make a copy of __digits and 00395 // insert the grouping. 00396 _STLP_BASIC_IOSTRING(char_type) __new_digits; 00397 if (!__grouping.empty()) { 00398 __new_digits.assign(__digits_first, __digits_last); 00399 __insert_grouping(__new_digits, 00400 __new_digits.size() - __frac_digits, 00401 __grouping, 00402 __sep, __plus, __minus, 0); 00403 __digits_first = __new_digits.begin(); // <<-- 00404 __digits_last = __new_digits.end(); // <<-- 00405 } 00406 00407 // Determine the amount of padding required, if any. 00408 streamsize __width = __str.width(); 00409 00410 #if defined (_STLP_DEBUG) && (defined(__HP_aCC) && (__HP_aCC <= 1)) 00411 size_t __value_length = operator -(__digits_last, __digits_first); 00412 #else 00413 size_t __value_length = __digits_last - __digits_first; 00414 #endif 00415 00416 size_t __length = __value_length + __sign.size(); 00417 00418 if (__frac_digits != 0) 00419 ++__length; 00420 00421 bool __generate_curr = (__str.flags() & ios_base::showbase) !=0; 00422 if (__generate_curr) 00423 __length += __curr_sym.size(); 00424 money_base::pattern __format = __intl ? (__is_negative ? __punct_intl.neg_format() 00425 : __punct_intl.pos_format()) 00426 : (__is_negative ? __punct.neg_format() 00427 : __punct.pos_format()); 00428 { 00429 //For the moment the following is commented for decoding reason. 00430 //No reason to add a space last if the money symbol do not have to be display 00431 //if (__format.field[3] == (char) money_base::symbol && !__generate_curr) { 00432 // if (__format.field[2] == (char) money_base::space) { 00433 // __format.field[2] = (char) money_base::none; 00434 // } 00435 //} 00436 //space can only be second or third and only once (22.2.6.3-1): 00437 if ((__format.field[1] == (char) money_base::space) || 00438 (__format.field[2] == (char) money_base::space)) 00439 ++__length; 00440 } 00441 00442 const bool __need_fill = (((sizeof(streamsize) > sizeof(size_t)) && (__STATIC_CAST(streamsize, __length) < __width)) || 00443 ((sizeof(streamsize) <= sizeof(size_t)) && (__length < __STATIC_CAST(size_t, __width)))); 00444 streamsize __fill_amt = __need_fill ? __width - __length : 0; 00445 00446 ios_base::fmtflags __fill_pos = __str.flags() & ios_base::adjustfield; 00447 00448 if (__fill_amt != 0 && 00449 !(__fill_pos & (ios_base::left | ios_base::internal))) 00450 __s = _STLP_PRIV __fill_n(__s, __fill_amt, __fill); 00451 00452 for (int __i = 0; __i < 4; ++__i) { 00453 char __ffield = __format.field[__i]; 00454 switch (__ffield) { 00455 case money_base::space: 00456 *__s++ = __space; 00457 case money_base::none: 00458 if (__fill_amt != 0 && __fill_pos == ios_base::internal) 00459 __s = _STLP_PRIV __fill_n(__s, __fill_amt, __fill); 00460 break; 00461 case money_base::symbol: 00462 if (__generate_curr) 00463 __s = _STLP_STD::copy(__curr_sym.begin(), __curr_sym.end(), __s); 00464 break; 00465 case money_base::sign: 00466 if (!__sign.empty()) 00467 *__s++ = __sign[0]; 00468 break; 00469 case money_base::value: 00470 if (__frac_digits == 0) { 00471 __s = _STLP_STD::copy(__digits_first, __digits_last, __s); 00472 } else { 00473 if ((int)__value_length <= __frac_digits) { 00474 // if we see '9' here, we should out 0.09 00475 *__s++ = __zero; // integer part is zero 00476 *__s++ = __point; // decimal point 00477 __s = _STLP_PRIV __fill_n(__s, __frac_digits - __value_length, __zero); // zeros 00478 __s = _STLP_STD::copy(__digits_first, __digits_last, __s); // digits 00479 } else { 00480 __s = _STLP_STD::copy(__digits_first, __digits_last - __frac_digits, __s); 00481 if (__frac_digits != 0) { 00482 *__s++ = __point; 00483 __s = _STLP_STD::copy(__digits_last - __frac_digits, __digits_last, __s); 00484 } 00485 } 00486 } 00487 break; 00488 } //Close for switch 00489 } // Close for loop 00490 00491 // Ouput rest of sign if necessary. 00492 if (__sign.size() > 1) 00493 __s = _STLP_STD::copy(__sign.begin() + 1, __sign.end(), __s); 00494 if (__fill_amt != 0 && 00495 !(__fill_pos & (ios_base::right | ios_base::internal))) 00496 __s = _STLP_PRIV __fill_n(__s, __fill_amt, __fill); 00497 00498 return __s; 00499 } 00500 00501 _STLP_MOVE_TO_STD_NAMESPACE 00502 00503 template <class _CharT, class _OutputIter> 00504 _OutputIter 00505 money_put<_CharT, _OutputIter> 00506 ::do_put(_OutputIter __s, bool __intl, ios_base& __str, 00507 char_type __fill, _STLP_LONGEST_FLOAT_TYPE __units) const { 00508 _STLP_BASIC_IOSTRING(char_type) __digits; 00509 _STLP_PRIV __get_money_digits(__digits, __str, __units); 00510 return _STLP_PRIV __money_do_put(__s, __intl, __str, __fill, __digits, false, __STATIC_CAST(string_type*, 0)); 00511 } 00512 00513 template <class _CharT, class _OutputIter> 00514 _OutputIter 00515 money_put<_CharT, _OutputIter> 00516 ::do_put(_OutputIter __s, bool __intl, ios_base& __str, 00517 char_type __fill, const string_type& __digits) const { 00518 return _STLP_PRIV __money_do_put(__s, __intl, __str, __fill, __digits, true, __STATIC_CAST(string_type*, 0)); 00519 } 00520 00521 _STLP_END_NAMESPACE 00522 00523 #endif /* _STLP_MONETARY_C */ 00524 00525 // Local Variables: 00526 // mode:C++ 00527 // End: Generated on Sun May 27 2012 04:29:18 for ReactOS by
1.7.6.1
|