This repository has been archived on 2024-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
CodeBlocksPortable/Borland/BCC55/Include/Rw/money.cc

718 lines
21 KiB
C++
Raw Normal View History

#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 <EFBFBD> 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 */