home *** CD-ROM | disk | FTP | other *** search
- #ifndef __MONEY_CC
- #define __MONEY_CC
- #pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
- /***************************************************************************
- *
- * money.cc - Definitions for the Standard Library money facets
- *
- ***************************************************************************
- *
- * Copyright (c) 1994-1999 Rogue Wave Software, Inc. All Rights Reserved.
- *
- * This computer software is owned by Rogue Wave Software, Inc. and is
- * protected by U.S. copyright laws and other laws and by international
- * treaties. This computer software is furnished by Rogue Wave Software,
- * Inc. pursuant to a written license agreement and may be used, copied,
- * transmitted, and stored only in accordance with the terms of such
- * license and with the inclusion of the above copyright notice. This
- * computer software or any other copies thereof may not be provided or
- * otherwise made available to any other person.
- *
- * U.S. Government Restricted Rights. This computer software is provided
- * with Restricted Rights. Use, duplication, or disclosure by the
- * Government is subject to restrictions as set forth in subparagraph (c)
- * (1) (ii) of The Rights in Technical Data and Computer Software clause
- * at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
- * Commercial Computer Software รป Restricted Rights at 48 CFR 52.227-19,
- * as applicable. Manufacturer is Rogue Wave Software, Inc., 5500
- * Flatiron Parkway, Boulder, Colorado 80301 USA.
- *
- **************************************************************************/
-
- #ifndef _RWSTD_NO_NAMESPACE
- namespace __rwstd {
- #endif
-
- // -------------------------------------------------
- // Template moneypunct_data<charT> member templates.
- // -------------------------------------------------
-
- template <class charT>
- moneypunct_data<charT>::moneypunct_data
- (moneypunct_init<charT> *init)
- {
- if (!init) {
- this->dp_=charT('.');
- this->ts_=charT(',');
- fd_=0;
- } else {
- this->dp_=init->dp_;
- this->ts_=init->ts_;
- this->gr_=init->gr_;
- cs_=init->cs_;
- ps_=init->ps_;
- ns_=init->ns_;
- fd_=init->fd_;
- pf_=init->pf_;
- nf_=init->nf_;
-
- if (init->del_)
- delete[] (char*) init;
- }
- }
-
- template <class charT>
- void moneypunct_data<charT>::__initfacetbase (const locale*) { }
-
- template <class charT>
- moneypunct_init<charT>*
- _RWSTDExportTemplate fixup_moneypunct_init
- (moneypunct_init<char> *init,charT*)
- {
- moneypunct_init<charT> *result = NULL;
- #if !defined (_RWSTD_NO_NAMESPACE) && !defined (_RWSTD_NO_NEW_HEADER)
- using std::mbstate_t;
- #endif
-
- if (init) {
- const _RW_STD::codecvt<charT,char,mbstate_t> &cvt =
- #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
- _RW_STD::use_facet<_RW_STD::codecvt<charT,char,mbstate_t> >(_RW_STD::locale::classic());
- #else
- _RW_STD::use_facet(_RW_STD::locale::classic(),(_RW_STD::codecvt<charT,char,mbstate_t>*)0);
- #endif
-
- typedef _RW_STD::basic_string<charT,_RW_STD::char_traits<charT>,_RW_STD::allocator<charT> > s_type;
- s_type cs_=cvt.in(init->cs_);
- s_type ps_=cvt.in(init->ps_);
- s_type ns_=cvt.in(init->ns_);
-
- size_t extra_chars = _RW_STD::char_traits<char>::length(init->gr_);
-
- size_t extra_charTs = cs_.length()+ps_.length()+ns_.length()+3;
-
- result=(moneypunct_init<charT>*)
- new char[sizeof(*result)+extra_chars+extra_charTs*sizeof(charT)];
-
- result->del_=true;
- result->dp_=charT(init->dp_);
- result->ts_=charT(init->ts_);
- result->fd_=init->fd_;
- result->pf_=init->pf_;
- result->nf_=init->nf_;
-
- size_t n;
- charT *p=(charT*) (result+1);
- result->cs_=_RW_STD::char_traits<charT>::copy(p,cs_.c_str(),n=cs_.length());
- *(p+=n)++=0;
- result->ps_=_RW_STD::char_traits<charT>::copy(p,ps_.c_str(),n=ps_.length());
- *(p+=n)++=0;
- result->ns_=_RW_STD::char_traits<charT>::copy(p,ns_.c_str(),n=ns_.length());
- *(p+=n)++=0;
-
- result->gr_= _RW_STD::char_traits<char>::copy((char*)(p+n),init->gr_,
- _RW_STD::char_traits<char>::length(init->gr_));
- }
-
- if (init->del_)
- delete[] (char*) init;
-
- return result;
- }
-
- template <class charT>
- moneypunct_init<charT>*
- moneypunct_data<charT>::get_init_by_name_
- (const char *name,bool intl)
- {
- return fixup_moneypunct_init (__get_named_init(name,intl),(charT*)0);
- }
-
- // ------------------------------------------------------------
- // Template class money_handler_base_1<charT> member templates.
- // ------------------------------------------------------------
-
- template <class charT>
- const moneypunct_data<charT>&
- money_handler_base_1<charT>::get_punct_data
- (const _RW_STD::locale &loc,bool intl)
- {
- #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
- if (intl)
- return _RW_STD::use_facet<_RW_STD::moneypunct<charT,true> >(loc);
- else
- return _RW_STD::use_facet<_RW_STD::moneypunct<charT,false> >(loc);
- #else
- if (intl) // casts required for some compilers
- #if defined(__TURBOC__) && (__TURBOC__ > 0x540)
- return moneypunct_data<charT>( _RW_STD::use_facet(loc,(_RW_STD::moneypunct<charT,true>*)0));
- #else
- return _RW_STD::use_facet(loc,(_RW_STD::moneypunct<charT,true>*)0);
- #endif
- else
- #if defined(__TURBOC__) && (__TURBOC__ > 0x540)
- return moneypunct_data<charT>(_RW_STD::use_facet(loc,(_RW_STD::moneypunct<charT,false>*)0));
- #else
- return _RW_STD::use_facet(loc,(_RW_STD::moneypunct<charT,false>*)0);
- #endif
- #endif
- }
-
- // -----------------------------------------------------------
- // Template class money_reader_base_1<charT> member templates.
- // -----------------------------------------------------------
-
- template <class charT>
- money_reader_base_1<charT>::
- money_reader_base_1 (digit_reader_base_1<charT> &r,
- const moneypunct_data<charT> &mp)
- : money_handler_base_1<charT>(mp), reader(r)
- { }
-
- template <class charT>
- void money_reader_base_1<charT>::get_money_string
- (string_type &result,const char *eod)
- {
- int len=eod-reader.digits;
- if (reader.negative)
- len++;
-
- result.resize(0);
- result.reserve(len);
-
- if (reader.negative)
- result+=reader.dmap.punct_chars[digit_map_base::minus];
-
- const char *d=reader.digits;
- const char *end=eod-1;
- while (d<end && *d==0) d++;
- for ( ; d<=end; d++)
- result+=reader.dmap.digit_chars[*d];
- }
-
- // -------------------------------------------------------------------------
- // Template class money_reader_base_2<charT,InputIterator> member templates.
- // -------------------------------------------------------------------------
-
- template <class charT,class InputIterator>
- money_reader_base_2<charT,InputIterator>::
- money_reader_base_2 (InputIterator &i,InputIterator &e,
- _RW_STD::ios_base &b,const moneypunct_data<charT> &mp)
- : digit_reader<charT,InputIterator>(i,e,b,mp),
- money_reader_base_1<charT>(this_as_digit_reader(),mp)
- {
- this->radix=10;
- this->is_signed=false;
- }
-
- template <class charT,class InputIterator>
- char* money_reader_base_2<charT,InputIterator>::
- get_money_digits (void)
- {
- charT c;
- // Always parse input according to negative format.
- const _RW_STD::money_base::pattern &patt=this->get_neg_format();
-
- // If this ends up non-NULL, it points to trailing sign char(s) that are
- // required at the end of the pattern.
- const charT *sign=NULL;
-
- bool need_curr=(this->io.flags()&_RW_STD::ios_base::showbase)? true : false;
- bool got_curr=false;
- int fracs=this->get_frac_digits();
-
- char *eod=this->digits;
- const char *p=patt.field,*pend=p+sizeof patt.field-1;
-
- for ( ; !this->error && p<=pend; p++) {
- switch (*p) {
- case _RW_STD::money_base::space:
- case _RW_STD::money_base::none:
- while (!this->at_end() && this->ctyp.is(_RW_STD::ctype_base::space,*this->in))
- this->in++;
- break;
-
- case _RW_STD::money_base::symbol:
- if (!this->at_end()) {
- const charT *curr=this->get_curr_symbol().c_str();
- if ((c=*this->in)==*curr) {
- // We ate a character, so rest of symbol must be present.
- need_curr=true;
- do {
- this->in++;
- if (*++curr==charT('\0')) {
- got_curr=true;
- break;
- }
- } while (!this->at_end() && (c=*this->in)==*curr);
- }
- }
- if (need_curr && !got_curr)
- this->error|=this->bad_curr_symbol;
- break;
-
- case _RW_STD::money_base::sign:
- if (!this->at_end()) {
- sign=this->get_negative_sign().c_str();
- if ((c=*this->in)==*sign) {
- this->negative=true;
- sign++;
- this->in++;
- } else {
- sign=this->get_positive_sign().c_str();
- if (c==*sign) {
- sign++;
- this->in++;
- } else
- sign=NULL;
- }
- }
- break;
-
- case _RW_STD::money_base::value:
- eod=this->get_int_digits();
- if (!this->error && fracs && !this->at_end() &&
- *this->in==this->get_decimal_point())
- {
- this->in++;
- char *frac_start=eod;
- eod=this->get_digit_string(eod);
- if (!this->error) {
- fracs-=(eod-frac_start);
- if (fracs<0) {
- // Too many fractional digits in input. We truncate. The
- // alternative would be to return an error.
- eod+=fracs;
- fracs=0;
- }
- }
- }
- if (eod==this->digits)
- this->error|=this->no_digits;
- else if (!this->error && fracs>0) {
- // Add trailing zeros until the correct number of fractional digits
- // is reached.
- if (this->digits+sizeof this->digits-eod < fracs)
- this->error|=this->too_many_digits;
- else {
- do *eod++=0;
- while (--fracs);
- }
- }
- break;
- }
- }
-
- if (sign && !this->error)
- // We ate one charT of a sign earlier, rest of sign must be present at end.
- while (*sign)
- if (!this->at_end() && *this->in==*sign++)
- this->in++;
- else {
- this->error|=this->bad_sign;
- break;
- }
-
- this->frac_beg=this->exp_beg=eod;
- return eod;
- }
-
- // ------------------------------------------------------------
- // Template money_reader<charT,InputIterator> member templates.
- // ------------------------------------------------------------
-
- template <class charT,class InputIterator>
- money_reader<charT,InputIterator>::
- money_reader (InputIterator &i,InputIterator &e,
- _RW_STD::ios_base &b,bool intl):
- money_reader_base_2<charT,InputIterator>
- (i,e,b,money_handler_base_1<charT>::
- get_punct_data(b.getloc(),intl))
- { }
-
- // -----------------------------------------------------
- // Template money_writer_base_1<charT> member templates.
- // -----------------------------------------------------
-
- template <class charT>
- money_writer_base_1<charT>::money_writer_base_1
- (digit_writer_base_1<charT> &w,
- const moneypunct_data<charT> &mp)
- : money_handler_base_1<charT>(mp), writer(w)
- { }
-
- template <class charT>
- void money_writer_base_1<charT>::put_money (charT fill)
- {
- bool negative;
- if (*writer.start=='-') {
- negative=true;
- writer.start++;
- } else {
- negative=false;
- if (*writer.start=='+' || *writer.start==' ')
- writer.start++;
- }
-
- charT wide_digits[sizeof writer.buffer];
- writer.ctyp.widen(writer.start,writer.end,wide_digits);
- put_money_sub(wide_digits,wide_digits+(writer.end-writer.start),
- negative,fill);
- }
-
- template <class charT>
- void money_writer_base_1<charT>::put_money
- (const string_type& digits,charT fill)
- {
- const charT *punct =
- digit_map<charT>::get_digit_map(writer.ctyp)
- .get_punct();
-
- const charT *start=digits.c_str();
- bool negative;
- if (*start==punct[digit_map_base::minus]) {
- negative=true;
- start++;
- } else
- negative=false;
-
- const charT *end=writer.ctyp.scan_not(_RW_STD::ctype_base::digit,start,
- digits.c_str()+digits.length());
-
- put_money_sub(start,end,negative,fill);
- }
-
- // --------------------------------------------------------------------
- // Template money_writer_base_2<charT,OutputIterator> member templates.
- // --------------------------------------------------------------------
-
- template <class charT,class OutputIterator>
- money_writer_base_2<charT,OutputIterator>::money_writer_base_2
- (OutputIterator &os,_RW_STD::ios_base &io,
- const moneypunct_data<charT> &mp)
- : digit_writer<charT,OutputIterator> (os,io,mp),
- money_writer_base_1<charT> (this_as_digit_writer(),mp)
- { }
-
- template <class charT, class OutputIterator>
- void money_writer_base_2<charT,OutputIterator>::put_money_sub
- (const charT *start,const charT *end,bool negative,charT fill)
- {
- const _RW_STD::money_base::pattern *patt;
- const string_type *sign;
- if (negative) {
- patt=&this->get_neg_format();
- sign=&this->get_negative_sign();
- } else {
- patt=&this->get_pos_format();
- sign=&this->get_positive_sign();
- }
-
- int frac_digits=this->get_frac_digits();
- int int_digits=end-start-frac_digits;
- int unGrouped,zero_pad;
-
- if (int_digits<0) {
- zero_pad=-int_digits;
- int_digits=0;
- } else
- zero_pad=0;
-
- charT sep;
- if (int_digits>0) {
- unGrouped=calc_groups(int_digits,this->get_grouping());
- if (this->num_groups)
- sep=this->get_thousands_sep();
- } else
- unGrouped=0;
-
- const char *p,*pend=patt->field+sizeof patt->field;
- int leftFill=0,internalFill=0,rightFill=0;
-
- if (this->width) {
- int n=0;
- for (p=patt->field; p<pend; p++) {
- switch (*p) {
- case _RW_STD::money_base::space:
- n++;
- break;
- case _RW_STD::money_base::symbol:
- if (this->flags& _RW_STD::ios_base::showbase)
- n+=this->get_curr_symbol().length();
- break;
- case _RW_STD::money_base::sign:
- n+=sign->length();
- break;
- case _RW_STD::money_base::value:
- n+=int_digits+this->num_groups;
- if (frac_digits)
- n+=frac_digits+1;
- break;
- }
- }
-
- if ((n-=this->width)>0) {
- switch (this->adjust) {
- case digit_writer_base::left:
- rightFill=n;
- break;
- case digit_writer_base::internal:
- internalFill=n;
- break;
- default:
- leftFill=n;
- }
- }
-
- this->width=0;
- }
-
- if (leftFill)
- do *this->out++=fill;
- while (--leftFill);
-
- const charT *schar=sign->c_str();
- for (p=patt->field; p<pend; p++)
- switch (*p) {
- case _RW_STD::money_base::symbol:
- if (this->flags& _RW_STD::ios_base::showbase)
- put_keyword(this->get_curr_symbol(),fill);
- break;
- case _RW_STD::money_base::sign:
- if (*schar)
- *this->out++=*schar++;
- break;
- case _RW_STD::money_base::value:
- while (unGrouped--)
- *this->out++=*start++;
- while (this->num_groups--) {
- *this->out++=sep;
- while ((*this->group)--)
- *this->out++=*start++;
- this->group++;
- }
- if (frac_digits) {
- *this->out++=this->get_decimal_point();
- while (zero_pad--) {
- frac_digits--;
- *this->out++=this->ctyp.widen('0');
- }
- while (frac_digits-->0)
- *this->out++=*start++;
- }
- break;
- case _RW_STD::money_base::space:
- if (!internalFill) {
- *this->out++=this->ctyp.widen(' ');
- break;
- }
- // Fall through ...
- case _RW_STD::money_base::none:
- if (internalFill)
- do *this->out++=fill;
- while (--internalFill);
- break;
- }
-
- while (*schar)
- *this->out++=*schar++;
-
- if (rightFill+=internalFill) {
- do *this->out++=fill;
- while (--rightFill);
- }
- }
-
- // -------------------------------------------------------------
- // Template money_writer<charT,OutputIterator> member templates.
- // -------------------------------------------------------------
-
- template <class charT,class OutputIterator>
- money_writer<charT,OutputIterator>::money_writer
- (OutputIterator &os,_RW_STD::ios_base &io,bool intl)
- : money_writer_base_2<charT,OutputIterator>
- (os,io,money_handler_base_1<charT>::
- get_punct_data(io.getloc(),intl))
- { }
- #ifndef _RWSTD_NO_NAMESPACE
- } namespace std {
- #endif
-
- // ------------------------------------------------------
- // Facet money_get<charT,InputIterator> member templates.
- // ------------------------------------------------------
-
- template <class charT, class InputIterator>
- locale::id money_get<charT,InputIterator>::id;
-
- template <class charT, class InputIterator>
- money_get<charT,InputIterator>::~money_get() { }
-
- // Warning -- these functions do not input actual monetary value; they just
- // input numbers that represent monetary value.
-
- template <class charT, class InputIterator>
- InputIterator money_get<charT,InputIterator>::do_get
- (InputIterator in, InputIterator end, bool intl, ios_base& io,
- ios_base::iostate& err, long double& units) const
- {
- __RWSTD::money_reader<charT,InputIterator> reader(in,end,io,intl);
- long double v=reader.to_long_double(reader.get_money_digits());
- err=ios_base::goodbit;
-
- if (reader.error)
- err=ios_base::failbit;
- else
- units=v;
-
- if (reader.reached_end)
- err|=ios_base::eofbit;
-
- return in;
- }
-
- template <class charT, class InputIterator>
- InputIterator money_get<charT,InputIterator>::do_get
- (InputIterator in, InputIterator end, bool intl, ios_base &io,
- ios_base::iostate &err, string_type &digit_string) const
- {
- __RWSTD::money_reader<charT,InputIterator> reader(in,end,io,intl);
- const char *eod=reader.get_money_digits();
- err=ios_base::goodbit;
-
- if (reader.error)
- err=ios_base::failbit;
- else
- reader.get_money_string(digit_string,eod);
-
- if (reader.reached_end)
- err|=ios_base::eofbit;
-
- return in;
- }
-
- // -------------------------------------------------------
- // Facet money_put<charT,OutputIterator> member templates.
- // -------------------------------------------------------
-
- template <class charT, class OutputIterator>
- locale::id money_put<charT,OutputIterator>::id;
-
- template <class charT, class OutputIterator>
- money_put<charT,OutputIterator>::~money_put() { }
-
- template <class charT, class OutputIterator>
- OutputIterator money_put<charT,OutputIterator>::do_put
- (OutputIterator out, bool intl, ios_base& io, charT fill,
- #ifndef _RWSTD_NO_LONG_DOUBLE
- long double quant) const
- #else
- double quant) const
- #endif
-
- {
- __RWSTD::money_writer<charT,OutputIterator> writer(out,io,intl);
- writer.digitize(quant);
- writer.put_money(fill);
- return out;
- }
-
- template <class charT, class OutputIterator>
- OutputIterator money_put<charT,OutputIterator>::do_put
- (OutputIterator out, bool intl, ios_base& io, charT fill,
- const string_type& digits) const
- {
- __RWSTD::money_writer<charT,OutputIterator> writer(out,io,intl);
- writer.put_money(digits,fill);
- return out;
- }
-
- // ----------------------------------------------
- // Facet moneypunct<charT,Intl> member templates.
- // ----------------------------------------------
-
- template <class charT, bool Intl>
- locale::id moneypunct<charT,Intl>::id;
-
- #ifndef _RWSTD_NO_STI_SIMPLE
- template <class charT, bool Intl>
- const bool moneypunct<charT,Intl>::intl;
- #endif
-
- template <class charT, bool Intl>
- moneypunct<charT,Intl>::~moneypunct () { }
-
- template <class charT, bool Intl>
- charT moneypunct<charT,Intl>::do_decimal_point () const
- { return this->dp_; }
-
- template <class charT, bool Intl>
- charT moneypunct<charT,Intl>::do_thousands_sep () const
- { return this->ts_; }
-
- template <class charT, bool Intl>
- string moneypunct<charT,Intl>::do_grouping () const
- { return this->gr_; }
-
- template <class charT, bool Intl>
- _TYPENAME moneypunct<charT,Intl>::string_type
- moneypunct<charT,Intl>::do_curr_symbol () const
- { return this->cs_; }
-
- template <class charT, bool Intl>
- _TYPENAME moneypunct<charT,Intl>::string_type
- moneypunct<charT,Intl>::do_positive_sign () const
- { return this->ps_; }
-
- template <class charT, bool Intl>
- _TYPENAME moneypunct<charT,Intl>::string_type
- moneypunct<charT,Intl>::do_negative_sign () const
- { return this->ns_; }
-
- template <class charT, bool Intl>
- int moneypunct<charT,Intl>::do_frac_digits () const
- { return this->fd_; }
-
- template <class charT, bool Intl>
- money_base::pattern
- moneypunct<charT,Intl>::do_pos_format () const
- { return this->pf_; }
-
- template <class charT, bool Intl>
- money_base::pattern
- moneypunct<charT,Intl>::do_neg_format () const
- { return this->nf_; }
-
- template <class charT, bool Intl>
- void moneypunct<charT,Intl>::__initfacet (const locale* loc) {
- this->dp_=do_decimal_point();
- this->ts_=do_thousands_sep();
- this->gr_=do_grouping();
- this->cs_=do_curr_symbol();
- this->ps_=do_positive_sign();
- this->ns_=do_negative_sign();
- this->fd_=do_frac_digits();
- this->pf_=do_pos_format();
- this->nf_=do_neg_format();
- this->__initfacetbase(loc);
- }
-
- // --------------------------------------------------------------------------
- // Money punctuation by-name member templates: moneypunct_byname<charT,Intl>
- // --------------------------------------------------------------------------
-
- template <class charT, bool Intl>
- moneypunct_byname<charT,Intl>::moneypunct_byname (const char *n,size_t refs):
- moneypunct<charT,Intl>(refs,get_init_by_name_(n,moneypunct<charT,Intl>::intl))
- { }
-
- template <class charT, bool Intl>
- moneypunct_byname<charT,Intl>::~moneypunct_byname()
- { }
- #ifndef _RWSTD_NO_NAMESPACE
- }
- #endif
-
- #pragma option pop
- #endif /* __MONEY_CC */
-