#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 member templates. // ------------------------------------------------- template moneypunct_data::moneypunct_data (moneypunct_init *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 void moneypunct_data::__initfacetbase (const locale*) { } template moneypunct_init* _RWSTDExportTemplate fixup_moneypunct_init (moneypunct_init *init,charT*) { moneypunct_init *result = NULL; #if !defined (_RWSTD_NO_NAMESPACE) && !defined (_RWSTD_NO_NEW_HEADER) using std::mbstate_t; #endif if (init) { const _RW_STD::codecvt &cvt = #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE _RW_STD::use_facet<_RW_STD::codecvt >(_RW_STD::locale::classic()); #else _RW_STD::use_facet(_RW_STD::locale::classic(),(_RW_STD::codecvt*)0); #endif typedef _RW_STD::basic_string,_RW_STD::allocator > 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::length(init->gr_); size_t extra_charTs = cs_.length()+ps_.length()+ns_.length()+3; result=(moneypunct_init*) 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::copy(p,cs_.c_str(),n=cs_.length()); *(p+=n)++=0; result->ps_=_RW_STD::char_traits::copy(p,ps_.c_str(),n=ps_.length()); *(p+=n)++=0; result->ns_=_RW_STD::char_traits::copy(p,ns_.c_str(),n=ns_.length()); *(p+=n)++=0; result->gr_= _RW_STD::char_traits::copy((char*)(p+n),init->gr_, _RW_STD::char_traits::length(init->gr_)); } if (init->del_) delete[] (char*) init; return result; } template moneypunct_init* moneypunct_data::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 member templates. // ------------------------------------------------------------ template const moneypunct_data& money_handler_base_1::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 >(loc); else return _RW_STD::use_facet<_RW_STD::moneypunct >(loc); #else if (intl) // casts required for some compilers #if defined(__TURBOC__) && (__TURBOC__ > 0x540) return moneypunct_data( _RW_STD::use_facet(loc,(_RW_STD::moneypunct*)0)); #else return _RW_STD::use_facet(loc,(_RW_STD::moneypunct*)0); #endif else #if defined(__TURBOC__) && (__TURBOC__ > 0x540) return moneypunct_data(_RW_STD::use_facet(loc,(_RW_STD::moneypunct*)0)); #else return _RW_STD::use_facet(loc,(_RW_STD::moneypunct*)0); #endif #endif } // ----------------------------------------------------------- // Template class money_reader_base_1 member templates. // ----------------------------------------------------------- template money_reader_base_1:: money_reader_base_1 (digit_reader_base_1 &r, const moneypunct_data &mp) : money_handler_base_1(mp), reader(r) { } template void money_reader_base_1::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 member templates. // ------------------------------------------------------------------------- template money_reader_base_2:: money_reader_base_2 (InputIterator &i,InputIterator &e, _RW_STD::ios_base &b,const moneypunct_data &mp) : digit_reader(i,e,b,mp), money_reader_base_1(this_as_digit_reader(),mp) { this->radix=10; this->is_signed=false; } template char* money_reader_base_2:: 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 member templates. // ------------------------------------------------------------ template money_reader:: money_reader (InputIterator &i,InputIterator &e, _RW_STD::ios_base &b,bool intl): money_reader_base_2 (i,e,b,money_handler_base_1:: get_punct_data(b.getloc(),intl)) { } // ----------------------------------------------------- // Template money_writer_base_1 member templates. // ----------------------------------------------------- template money_writer_base_1::money_writer_base_1 (digit_writer_base_1 &w, const moneypunct_data &mp) : money_handler_base_1(mp), writer(w) { } template void money_writer_base_1::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 void money_writer_base_1::put_money (const string_type& digits,charT fill) { const charT *punct = digit_map::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 member templates. // -------------------------------------------------------------------- template money_writer_base_2::money_writer_base_2 (OutputIterator &os,_RW_STD::ios_base &io, const moneypunct_data &mp) : digit_writer (os,io,mp), money_writer_base_1 (this_as_digit_writer(),mp) { } template void money_writer_base_2::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; pflags& _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; pflags& _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 member templates. // ------------------------------------------------------------- template money_writer::money_writer (OutputIterator &os,_RW_STD::ios_base &io,bool intl) : money_writer_base_2 (os,io,money_handler_base_1:: get_punct_data(io.getloc(),intl)) { } #ifndef _RWSTD_NO_NAMESPACE } namespace std { #endif // ------------------------------------------------------ // Facet money_get member templates. // ------------------------------------------------------ template locale::id money_get::id; template money_get::~money_get() { } // Warning -- these functions do not input actual monetary value; they just // input numbers that represent monetary value. template InputIterator money_get::do_get (InputIterator in, InputIterator end, bool intl, ios_base& io, ios_base::iostate& err, long double& units) const { __RWSTD::money_reader 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 InputIterator money_get::do_get (InputIterator in, InputIterator end, bool intl, ios_base &io, ios_base::iostate &err, string_type &digit_string) const { __RWSTD::money_reader 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 member templates. // ------------------------------------------------------- template locale::id money_put::id; template money_put::~money_put() { } template OutputIterator money_put::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 writer(out,io,intl); writer.digitize(quant); writer.put_money(fill); return out; } template OutputIterator money_put::do_put (OutputIterator out, bool intl, ios_base& io, charT fill, const string_type& digits) const { __RWSTD::money_writer writer(out,io,intl); writer.put_money(digits,fill); return out; } // ---------------------------------------------- // Facet moneypunct member templates. // ---------------------------------------------- template locale::id moneypunct::id; #ifndef _RWSTD_NO_STI_SIMPLE template const bool moneypunct::intl; #endif template moneypunct::~moneypunct () { } template charT moneypunct::do_decimal_point () const { return this->dp_; } template charT moneypunct::do_thousands_sep () const { return this->ts_; } template string moneypunct::do_grouping () const { return this->gr_; } template _TYPENAME moneypunct::string_type moneypunct::do_curr_symbol () const { return this->cs_; } template _TYPENAME moneypunct::string_type moneypunct::do_positive_sign () const { return this->ps_; } template _TYPENAME moneypunct::string_type moneypunct::do_negative_sign () const { return this->ns_; } template int moneypunct::do_frac_digits () const { return this->fd_; } template money_base::pattern moneypunct::do_pos_format () const { return this->pf_; } template money_base::pattern moneypunct::do_neg_format () const { return this->nf_; } template void moneypunct::__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 // -------------------------------------------------------------------------- template moneypunct_byname::moneypunct_byname (const char *n,size_t refs): moneypunct(refs,get_init_by_name_(n,moneypunct::intl)) { } template moneypunct_byname::~moneypunct_byname() { } #ifndef _RWSTD_NO_NAMESPACE } #endif #pragma option pop #endif /* __MONEY_CC */