725 lines
19 KiB
C++
725 lines
19 KiB
C++
#ifndef __NUMBRW_CC
|
||
#define __NUMBRW_CC
|
||
#pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
|
||
/****************************************************************************
|
||
*
|
||
* rw/numbrw.cc - Internal classes for numeric formatting and parsing.
|
||
*
|
||
***************************************************************************
|
||
*
|
||
* 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 __STD_RW_NUMBRW_CC__
|
||
#define __STD_RW_NUMBRW_CC__
|
||
|
||
#ifndef _RWSTD_NO_NEW_HEADER
|
||
#include <clocale>
|
||
#else
|
||
#include <locale.h>
|
||
#endif
|
||
|
||
#ifndef _RWSTD_NO_NAMESPACE
|
||
namespace __rwstd {
|
||
#endif
|
||
|
||
#if !defined (_RWSTD_NO_NEW_HEADER) && !defined (_RWSTD_NO_NAMESPACE)
|
||
using std::tm;
|
||
using std::setlocale;
|
||
using std::strftime;
|
||
using std::mktime;
|
||
using std::strlen;
|
||
#endif
|
||
|
||
// ------------------------------------------------
|
||
// Template timepunct_data<charT> member templates.
|
||
// ------------------------------------------------
|
||
|
||
template <class charT>
|
||
timepunct_data<charT>::timepunct_data
|
||
(const timepunct_loc<charT> &init)
|
||
{
|
||
int i;
|
||
for (i=0; i<7; i++) {
|
||
dn_[i][0]=init.get_day(i,false);
|
||
dn_[i][1]=init.get_day(i,true);
|
||
}
|
||
for (i=0; i<12; i++) {
|
||
mn_[i][0]=init.get_month(i,false);
|
||
mn_[i][1]=init.get_month(i,true);
|
||
}
|
||
ampm_[0]=init.get_ampm(false);
|
||
ampm_[1]=init.get_ampm(true);
|
||
bad_=init.get_bad();
|
||
for (i=0; i<100; i++)
|
||
ord_[i]=init.get_ord(i);
|
||
for (i=0; i<sizeof pat_/sizeof pat_[0]; i++)
|
||
pat_[i]=init.get_pattern(i);
|
||
}
|
||
|
||
// struct for storing formatting information in map
|
||
struct __fmt {
|
||
__fmt () {}
|
||
__fmt (int p, int l, char f) : position(p), length(l), fmtChar(f) {}
|
||
int position;
|
||
int length;
|
||
char fmtChar;
|
||
bool operator < (const __fmt& f) {
|
||
return position < f.position;
|
||
}
|
||
};
|
||
|
||
// initialize data member pat_ which holds formatting strings
|
||
template <class charT>
|
||
void timepunct_data<charT>::__initpat (const locale* loc)
|
||
{
|
||
const _RW_STD::string timeFmtChars("YyjSMIHmBbAapdZUWw");
|
||
tm tmb;
|
||
char buf[256];
|
||
__fmt fmtArray[20];
|
||
|
||
// set up tmp
|
||
tmb.tm_sec = 56;
|
||
tmb.tm_min = 54;
|
||
tmb.tm_hour = 22;
|
||
tmb.tm_mday = 30;
|
||
tmb.tm_mon = 10;
|
||
tmb.tm_year = 90;
|
||
tmb.tm_wday = 5;
|
||
tmb.tm_yday = -1;
|
||
tmb.tm_isdst = -1;
|
||
(void) mktime(&tmb);
|
||
const _RW_STD::ctype<charT>& ct =
|
||
#ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
|
||
_RW_STD::use_facet<_RW_STD::ctype<charT> >(*loc);
|
||
#else
|
||
_RW_STD::use_facet(*loc, (_RW_STD::ctype<charT>*)0);
|
||
#endif
|
||
|
||
// Set up passed in locale
|
||
_RW_STD::string oldlocale = setlocale(LC_ALL, 0);
|
||
#ifdef __BORLANDC__
|
||
_RW_STD::string::size_type posd = loc->name().find('=')+1;
|
||
setlocale(LC_ALL, _RW_STD::string(loc->name(),posd,loc->name().find('\n')-posd).c_str());
|
||
#else
|
||
setlocale(LC_ALL, loc->name().c_str());
|
||
#endif // __BORLANDC__
|
||
|
||
// for each composite format character create format string
|
||
const char do_as_pattern[] = "xXcDrT";
|
||
for (unsigned int j = 0; j < strlen(do_as_pattern); j++) {
|
||
// create format string to parse
|
||
_RW_STD::string timeFmtStr("% ");
|
||
timeFmtStr[1] = do_as_pattern[j];
|
||
strftime(buf, sizeof(buf), timeFmtStr.c_str(), &tmb);
|
||
_RW_STD::string timeFmt(buf);
|
||
|
||
// starting at the beginning of the formatted string find each component
|
||
// and save in an ordered structure
|
||
int pos;
|
||
int fmtArrayIndex = 0;
|
||
for (unsigned int i=0; i < timeFmtChars.length(); i++) {
|
||
_RW_STD::string fmtChar("% ");
|
||
fmtChar[1] = timeFmtChars[i];
|
||
strftime(buf, sizeof(buf), fmtChar.data(), &tmb);
|
||
if ((pos = timeFmt.find(buf)) != -1) {
|
||
if (strlen(buf) > 0) {
|
||
fmtArray[fmtArrayIndex++] = __fmt(pos, strlen(buf), timeFmtChars[i]);
|
||
timeFmt.replace(pos, strlen(buf), strlen(buf), ' ');
|
||
}
|
||
}
|
||
}
|
||
|
||
// sort format items
|
||
for (int top = fmtArrayIndex; top > 0; --top) {
|
||
int large = 0;
|
||
for (int i = 0; i < top; ++i) {
|
||
if (fmtArray[i] < fmtArray[large])
|
||
large = i;
|
||
}
|
||
__fmt temp = fmtArray[large];
|
||
fmtArray[large] = fmtArray[top-1];
|
||
fmtArray[top-1] = temp;
|
||
}
|
||
|
||
// put format characters into formatting string
|
||
for (__fmt *p = fmtArray; p < fmtArray + fmtArrayIndex; ++p) {
|
||
timeFmt.replace((*p).position, (*p).length,
|
||
(_RW_STD::string("%").append(1,(*p).fmtChar)));
|
||
}
|
||
|
||
// convert to string_type and insert in array pat_
|
||
string_type cnvt;
|
||
for (unsigned int k = 0; k < timeFmt.length(); k++)
|
||
cnvt = _RW_STD::operator + (cnvt, ct.widen(timeFmt[k]));
|
||
pat_[j] = cnvt;
|
||
|
||
}
|
||
|
||
setlocale(LC_ALL, oldlocale.c_str());
|
||
}
|
||
|
||
template <class charT>
|
||
void timepunct_data<charT>::__initfacet (const locale* loc) {
|
||
int i;
|
||
for (i=0; i<7; i++) {
|
||
dn_defs_[i][0].s=dn_[i][0].c_str();
|
||
dn_defs_[i][0].v=i;
|
||
dn_defs_[i][1].s=dn_[i][1].c_str();
|
||
dn_defs_[i][1].v=i;
|
||
}
|
||
|
||
for (i=0; i<12; i++) {
|
||
mn_defs_[i][0].s=mn_[i][0].c_str();
|
||
mn_defs_[i][0].v=i;
|
||
mn_defs_[i][1].s=mn_[i][1].c_str();
|
||
mn_defs_[i][1].v=i;
|
||
}
|
||
|
||
ampm_defs_[0].s=ampm_[0].c_str();
|
||
ampm_defs_[0].v= 0;
|
||
ampm_defs_[1].s=ampm_[1].c_str();
|
||
ampm_defs_[1].v= 1;
|
||
|
||
dn_map_.num_defs_=7*2;
|
||
dn_map_.defs_=&(dn_defs_[0][0]);
|
||
mn_map_.num_defs_=12*2;
|
||
mn_map_.defs_=&(mn_defs_[0][0]);
|
||
ampm_map_.num_defs_=2;
|
||
ampm_map_.defs_=&(ampm_defs_[0]);
|
||
__initpat(loc);
|
||
}
|
||
// -----------------------------------------------
|
||
// Facet rwstd::timepunct<charT> member templates.
|
||
// -----------------------------------------------
|
||
|
||
#ifndef _RWSTD_NO_NAMESPACE
|
||
} namespace __rwstd { // Leave std, enter __rwstd
|
||
#endif
|
||
|
||
template <class charT>
|
||
_RW_STD::locale::id timepunct<charT>::id;
|
||
|
||
template <class charT>
|
||
void timepunct<charT>::__initfacet (const locale* loc) {
|
||
int n;
|
||
for (n=0; n<7; n++) {
|
||
this->dn_[n][false]=do_dayname(n,false);
|
||
this->dn_[n][true]=do_dayname(n,true);
|
||
}
|
||
for (n=0; n<12; n++) {
|
||
this->mn_[n][false]=do_monthname(n,false);
|
||
this->mn_[n][true]=do_monthname(n,true);
|
||
}
|
||
for (n=0; n<100; n++)
|
||
this->ord_[n]=do_ordinal(n);
|
||
|
||
timepunct_impl<charT>::__initfacet(loc);
|
||
}
|
||
|
||
template <class charT>
|
||
_TYPENAME timepunct<charT>::string_type
|
||
timepunct<charT>::do_dayname (int day, bool abbr) const {
|
||
return this->dn_[day][abbr];
|
||
}
|
||
|
||
template <class charT>
|
||
_TYPENAME timepunct<charT>::string_type
|
||
timepunct<charT>::do_monthname (int mon, bool abbr) const {
|
||
return this->mn_[mon][abbr];
|
||
}
|
||
|
||
template <class charT>
|
||
_TYPENAME timepunct<charT>::string_type
|
||
timepunct<charT>::do_ordinal (int number) const {
|
||
return (number<0 || number>99) ? this->bad_ : this->ord_[number];
|
||
}
|
||
|
||
// -----------------------------------------------
|
||
// Template digit_handler_base_1 member templates.
|
||
// -----------------------------------------------
|
||
|
||
template <class charT>
|
||
digit_handler_base_1<charT>::
|
||
digit_handler_base_1 (const _RW_STD::locale &loc):
|
||
#ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
|
||
ctyp(_RW_STD::use_facet<_RW_STD::ctype<charT> >(loc)),
|
||
dmap(digit_map<charT>::get_digit_map(ctyp)),
|
||
punct(_RW_STD::use_facet<_RW_STD::numpunct<charT> >(loc))
|
||
#else
|
||
ctyp(_RW_STD::use_facet(loc,(_RW_STD::ctype<charT>*)0)),
|
||
dmap(digit_map<charT>::get_digit_map(ctyp)),
|
||
punct(_RW_STD::use_facet(loc,(_RW_STD::numpunct<charT>*)0))
|
||
#endif
|
||
{ }
|
||
|
||
template <class charT>
|
||
digit_handler_base_1<charT>::
|
||
digit_handler_base_1
|
||
(const _RW_STD::locale &loc, const punct_data<charT> &pun):
|
||
#ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
|
||
ctyp(_RW_STD::use_facet<_RW_STD::ctype<charT> >(loc)),
|
||
dmap(digit_map<charT>::get_digit_map(ctyp)),
|
||
#else
|
||
ctyp(_RW_STD::use_facet(loc,(_RW_STD::ctype<charT>*)0)),
|
||
dmap(digit_map<charT>::get_digit_map(ctyp)),
|
||
#endif
|
||
punct(pun)
|
||
{ }
|
||
|
||
// ----------------------------------------------
|
||
// Template digit_reader_base_1 member templates.
|
||
// ----------------------------------------------
|
||
|
||
template <class charT>
|
||
digit_reader_base_1<charT>::
|
||
digit_reader_base_1 (const _RW_STD::locale &loc):
|
||
digit_handler_base_1<charT>(loc)
|
||
{ }
|
||
|
||
template <class charT>
|
||
digit_reader_base_1<charT>::
|
||
digit_reader_base_1 (const _RW_STD::locale &loc,
|
||
const punct_data<charT> &mp):
|
||
digit_handler_base_1<charT>(loc,mp)
|
||
{ }
|
||
|
||
// ---------------------------------------
|
||
// Template digit_reader member templates.
|
||
// ---------------------------------------
|
||
|
||
template <class charT,class InputIterator>
|
||
digit_reader<charT,InputIterator>::
|
||
digit_reader(InputIterator& i,InputIterator& e,_RW_STD::ios_base &b):
|
||
digit_reader_base_1<charT>(b.getloc()),
|
||
io(b), in(i), end(e)
|
||
{ }
|
||
|
||
template <class charT,class InputIterator>
|
||
digit_reader<charT,InputIterator>::
|
||
digit_reader(InputIterator& i,InputIterator& e,_RW_STD::ios_base &b,
|
||
const punct_data<charT> &mp):
|
||
digit_reader_base_1<charT>(b.getloc(),mp),
|
||
io(b), in(i), end(e)
|
||
{ }
|
||
|
||
template <class charT,class InputIterator>
|
||
char* digit_reader<charT,InputIterator>::
|
||
get_digit_string (char *dpos)
|
||
{
|
||
char *eod=dpos;
|
||
int i;
|
||
|
||
while (!at_end() && (i=this->dmap.eval(*in))>=0 && i<this->radix) {
|
||
if (eod==this->digits+sizeof this->digits)
|
||
this->error|=this->too_many_digits;
|
||
else
|
||
*eod++=(char) i;
|
||
++in;
|
||
}
|
||
|
||
return eod;
|
||
}
|
||
|
||
template <class charT,class InputIterator>
|
||
char* digit_reader<charT,InputIterator>::
|
||
get_int_digits (void)
|
||
{
|
||
charT c;
|
||
char *eod=this->digits;
|
||
const charT* ctype_punct=this->dmap.get_punct();
|
||
|
||
if (!at_end() && this->is_signed)
|
||
// If a sign is present, set negative if it's a minus sign.
|
||
do {
|
||
if ((c=*in)==ctype_punct[this->minus])
|
||
this->negative=true;
|
||
else if (c!=ctype_punct[this->plus])
|
||
break;
|
||
// Eat white space after the sign. Standard seems to mandate this
|
||
// regardless of whether ios_base::skipws is set.
|
||
do
|
||
++in;
|
||
while (!at_end() && this->ctyp.is(_RW_STD::ctype_base::space,*in));
|
||
this->advanced=true;
|
||
} while (0);
|
||
|
||
if (!this->radix) {
|
||
bool noradix = false;
|
||
switch (io.flags() & _RW_STD::ios_base::basefield) {
|
||
case _RW_STD::ios_base::dec:
|
||
this->radix=10;
|
||
break;
|
||
case _RW_STD::ios_base::hex:
|
||
this->radix=16;
|
||
break;
|
||
case _RW_STD::ios_base::oct:
|
||
this->radix=8;
|
||
break;
|
||
default:
|
||
noradix = true;
|
||
}
|
||
if (noradix || (io.flags() & _RW_STD::ios_base::showbase))
|
||
{
|
||
// No radix was forced by the ios_base flags, so poke around for a radix
|
||
// specifier on the front of the input value.
|
||
if (noradix)
|
||
this->radix=10;
|
||
if (!at_end() && *in==ctype_punct[this->zero]) {
|
||
this->radix=8;
|
||
++in;
|
||
*eod++=0;
|
||
this->advanced=true;
|
||
if (!at_end() &&
|
||
((c=*in)==ctype_punct[this->x] || c==ctype_punct[this->X]))
|
||
{
|
||
this->radix=16;
|
||
++in;
|
||
eod--; // Leading 0 was not a digit after all.
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
grouping=this->get_grouping();
|
||
if (!*grouping)
|
||
eod=get_digit_string(eod);
|
||
else {
|
||
gpos=groups;
|
||
thousands_sep=this->get_thousands_sep();
|
||
eod=get_digit_groups(eod);
|
||
if (!this->error && --gpos>groups) {
|
||
// Digit grouping is optional, but if present it must be right.
|
||
const char *gdef=grouping;
|
||
do {
|
||
if (*gdef!=*gpos && *gdef!=CHAR_MAX)
|
||
break;
|
||
else
|
||
if (gdef[1])
|
||
gdef++;
|
||
} while (--gpos>groups);
|
||
|
||
if (gpos>groups || *gpos>*gdef)
|
||
this->error|=this->bad_grouping;
|
||
}
|
||
}
|
||
|
||
if (eod>this->digits)
|
||
this->advanced=true;
|
||
return eod;
|
||
}
|
||
|
||
template <class charT,class InputIterator>
|
||
char* digit_reader<charT,InputIterator>::
|
||
get_float_digits (void)
|
||
{
|
||
charT c;
|
||
this->radix=10;
|
||
char *eod=get_int_digits();
|
||
|
||
const charT *ctyp_punct=this->dmap.get_punct();
|
||
|
||
this->frac_beg=eod;
|
||
if (!this->error && !at_end() && *in==this->get_decimal_point()) {
|
||
in++;
|
||
eod=get_digit_string(eod);
|
||
}
|
||
|
||
if (eod==this->digits)
|
||
this->error|=this->no_digits;
|
||
|
||
this->exp_beg=eod;
|
||
this->exp_negative=false;
|
||
if (!this->error && !at_end() &&
|
||
((c=*in)==ctyp_punct[this->e] || c==ctyp_punct[this->E]))
|
||
{
|
||
in++;
|
||
if (at_end())
|
||
this->error|=this->bad_exponent;
|
||
else {
|
||
if ((c=*in)==ctyp_punct[this->plus])
|
||
in++;
|
||
else if (c==ctyp_punct[this->minus]) {
|
||
this->exp_negative=true;
|
||
in++;
|
||
}
|
||
|
||
int save_radix=this->radix;
|
||
this->radix=10;
|
||
eod=get_digit_string(eod);
|
||
this->radix=save_radix;
|
||
if (eod==this->exp_beg)
|
||
this->error|=this->bad_exponent;
|
||
}
|
||
}
|
||
|
||
return eod;
|
||
}
|
||
|
||
template <class charT,class InputIterator>
|
||
char *digit_reader<charT,InputIterator>::
|
||
get_pointer_digits (void)
|
||
{
|
||
this->radix=16;
|
||
char *eod=get_int_digits();
|
||
return eod;
|
||
}
|
||
|
||
template <class charT,class InputIterator>
|
||
char* digit_reader<charT,InputIterator>::
|
||
get_digit_groups (char *dpos)
|
||
{
|
||
char *eod=get_digit_string(dpos);
|
||
|
||
if (gpos==groups+sizeof groups)
|
||
this->error|=this->too_many_groups;
|
||
else {
|
||
int i=eod-dpos;
|
||
if (i >= CHAR_MAX)
|
||
this->error|=this->group_too_long;
|
||
else {
|
||
*gpos++=i;
|
||
if (i!=0 && !at_end() && *in==thousands_sep) {
|
||
++in;
|
||
eod=get_digit_groups(eod);
|
||
}
|
||
}
|
||
}
|
||
|
||
return eod;
|
||
}
|
||
|
||
template <class charT,class InputIterator>
|
||
int digit_reader<charT,InputIterator>::
|
||
get_keyword (const keyword_map<charT> &mapit)
|
||
{
|
||
const keyword_def<charT> *canp=mapit.defs_;
|
||
const keyword_def<charT> *endp=mapit.defs_+mapit.num_defs_;
|
||
keyword_def<charT> cans[40],*ansp=cans;
|
||
|
||
charT c;
|
||
const charT *p;
|
||
int result;
|
||
|
||
while (1) {
|
||
if (at_end()) {
|
||
for ( ; canp<endp; canp++)
|
||
if (!*canp->s)
|
||
return canp->v;
|
||
return -1;
|
||
}
|
||
c=*in;
|
||
result=-1;
|
||
for ( ; canp<endp; canp++) {
|
||
p=canp->s;
|
||
if (c==*p) {
|
||
ansp->s=++p;
|
||
ansp->v=canp->v;
|
||
ansp++;
|
||
} else if (*p==0)
|
||
result=ansp->v; // abbreviation
|
||
}
|
||
|
||
if (ansp==cans)
|
||
return result;
|
||
in++;
|
||
if (ansp==cans+1) {
|
||
for (p=cans[0].s; *p; p++) {
|
||
if (at_end() || *in!=*p)
|
||
return -1;
|
||
in++;
|
||
}
|
||
return cans[0].v;
|
||
}
|
||
|
||
endp=ansp;
|
||
ansp=cans;
|
||
canp=cans;
|
||
}
|
||
}
|
||
|
||
// ----------------------------------------------
|
||
// Template digit_writer_base_1 member templates.
|
||
// ----------------------------------------------
|
||
|
||
template <class charT>
|
||
digit_writer_base_1<charT>::
|
||
digit_writer_base_1(_RW_STD::ios_base &b,const _RW_STD::locale &loc)
|
||
: digit_writer_base(b), digit_handler_base_1<charT>(loc)
|
||
{ }
|
||
|
||
template <class charT>
|
||
digit_writer_base_1<charT>::
|
||
digit_writer_base_1(_RW_STD::ios_base &b,const punct_data<charT> &mp)
|
||
: digit_writer_base(b),digit_handler_base_1<charT>(b.getloc(),mp)
|
||
{
|
||
flags&=~(_RW_STD::ios_base::floatfield | _RW_STD::ios_base::showpos);
|
||
flags|=_RW_STD::ios_base::fixed;
|
||
radix=10;
|
||
precision=0;
|
||
}
|
||
|
||
// ---------------------------------------
|
||
// Template digit_writer member templates.
|
||
// ---------------------------------------
|
||
|
||
template <class charT,class OutputIterator>
|
||
digit_writer<charT,OutputIterator>::
|
||
digit_writer (OutputIterator &o, _RW_STD::ios_base &b)
|
||
: digit_writer_base_1<charT>(b,b.getloc()), out(o)
|
||
{ }
|
||
|
||
template <class charT,class OutputIterator>
|
||
digit_writer<charT,OutputIterator>::
|
||
digit_writer (OutputIterator &o, _RW_STD::ios_base &b,
|
||
const punct_data<charT> &mp)
|
||
: digit_writer_base_1<charT>(b,mp), out(o)
|
||
{ }
|
||
|
||
template <class charT, class OutputIterator>
|
||
void digit_writer<charT,OutputIterator>::put_digits (charT fill)
|
||
{
|
||
char *p=this->start;
|
||
bool has_sign=false,has_point=false;
|
||
if (p<this->end && (*p==' ' || *p=='-' || *p=='+'))
|
||
has_sign=true;
|
||
|
||
// Locate the end of the integral digits.
|
||
char *dec;
|
||
if (!this->fractional)
|
||
dec=this->end;
|
||
else {
|
||
dec=this->start;
|
||
if (has_sign) dec++;
|
||
for ( ; dec<this->end; dec++)
|
||
if (*dec<'0' || *dec>'9') {
|
||
if (*dec!='e' && *dec!='E')
|
||
has_point=true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Calculate the number and pattern of separators needed if any.
|
||
charT separator;
|
||
int unGrouped=dec-this->start;
|
||
if (has_sign)
|
||
unGrouped--;
|
||
if (this->radix==10 && this->separable) {
|
||
unGrouped=calc_groups(unGrouped,this->get_grouping());
|
||
if (this->num_groups)
|
||
separator=this->get_thousands_sep();
|
||
}
|
||
|
||
// Compute the number of fill charT-s needed, and where they should be put.
|
||
int leftFill=0,internalFill=0,rightFill=0;
|
||
if (this->width>0) {
|
||
int w=this->width - (this->end - this->start) - this->num_groups;
|
||
this->width=0;
|
||
if (w>0) {
|
||
switch (this->adjust) {
|
||
case digit_writer_base::left:
|
||
rightFill=w;
|
||
break;
|
||
case digit_writer_base::internal:
|
||
internalFill=w;
|
||
break;
|
||
default:
|
||
leftFill=w;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Widen the sign + digits + exponent string.
|
||
//charT wide_digits[sizeof digit_writer_base::buffer];
|
||
charT wide_digits[400];
|
||
this->ctyp.widen(this->start,this->end,wide_digits);
|
||
|
||
// Write the widened string with fill and decorations to output.
|
||
charT *digit_pos=wide_digits;
|
||
while (leftFill--)
|
||
*out++=fill;
|
||
if (has_sign)
|
||
*out++=*digit_pos++; // the widened sign
|
||
while (internalFill--)
|
||
*out++=fill;
|
||
while (unGrouped--)
|
||
*out++=*digit_pos++;
|
||
while (this->num_groups--) {
|
||
*out++=separator;
|
||
while (this->group[0]--)
|
||
*out++=*digit_pos++;
|
||
this->group++;
|
||
}
|
||
|
||
if (has_point) {
|
||
*out++=this->get_decimal_point();
|
||
digit_pos++;
|
||
}
|
||
|
||
unGrouped=this->end-dec;
|
||
if (has_point)
|
||
unGrouped--;
|
||
while (unGrouped-->0)
|
||
*out++=*digit_pos++;
|
||
|
||
while (rightFill--)
|
||
*out++=fill;
|
||
}
|
||
|
||
template <class charT, class OutputIterator>
|
||
void digit_writer<charT,OutputIterator>::
|
||
put_keyword (const string_type &k, charT fill)
|
||
{
|
||
int leftFill=0,rightFill=0;
|
||
int n=this->width-k.length();
|
||
if (n>0) {
|
||
switch (this->adjust) {
|
||
case digit_writer_base::left:
|
||
rightFill=n;
|
||
break;
|
||
case digit_writer_base::internal:
|
||
default:
|
||
leftFill=n;
|
||
}
|
||
if (leftFill)
|
||
do *out++=fill;
|
||
while (--leftFill);
|
||
}
|
||
|
||
const charT *p=k.c_str(),*end=p+k.length();
|
||
while (p<end)
|
||
*out++=*p++;
|
||
|
||
if (rightFill)
|
||
do *out++=fill;
|
||
while (--rightFill);
|
||
}
|
||
|
||
#ifndef _RWSTD_NO_NAMESPACE
|
||
} // namespace __rwstd
|
||
#endif
|
||
|
||
#endif // __STD_RW_NUMBRW_CC__
|
||
|
||
#pragma option pop
|
||
#endif /* __NUMBRW_CC */
|