ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.