home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / Xenon / C++ / FreeCommandLineTools.exe / Include / Rw / numbrw.cc < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-31  |  19.6 KB  |  725 lines

  1. #ifndef __NUMBRW_CC
  2. #define __NUMBRW_CC
  3. #pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
  4. /****************************************************************************
  5.  *
  6.  * rw/numbrw.cc - Internal classes for numeric formatting and parsing.
  7.  *
  8.  ***************************************************************************
  9.  *
  10.  * Copyright (c) 1994-1999 Rogue Wave Software, Inc.  All Rights Reserved.
  11.  *
  12.  * This computer software is owned by Rogue Wave Software, Inc. and is
  13.  * protected by U.S. copyright laws and other laws and by international
  14.  * treaties.  This computer software is furnished by Rogue Wave Software,
  15.  * Inc. pursuant to a written license agreement and may be used, copied,
  16.  * transmitted, and stored only in accordance with the terms of such
  17.  * license and with the inclusion of the above copyright notice.  This
  18.  * computer software or any other copies thereof may not be provided or
  19.  * otherwise made available to any other person.
  20.  *
  21.  * U.S. Government Restricted Rights.  This computer software is provided
  22.  * with Restricted Rights.  Use, duplication, or disclosure by the
  23.  * Government is subject to restrictions as set forth in subparagraph (c)
  24.  * (1) (ii) of The Rights in Technical Data and Computer Software clause
  25.  * at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
  26.  * Commercial Computer Software รป Restricted Rights at 48 CFR 52.227-19,
  27.  * as applicable.  Manufacturer is Rogue Wave Software, Inc., 5500
  28.  * Flatiron Parkway, Boulder, Colorado 80301 USA.
  29.  *
  30.  ***************************************************************************/
  31.  
  32. #ifndef __STD_RW_NUMBRW_CC__
  33. #define __STD_RW_NUMBRW_CC__
  34.  
  35. #ifndef _RWSTD_NO_NEW_HEADER
  36. #include <clocale>
  37. #else
  38. #include <locale.h>
  39. #endif
  40.  
  41. #ifndef _RWSTD_NO_NAMESPACE
  42. namespace __rwstd {
  43. #endif
  44.  
  45. #if !defined (_RWSTD_NO_NEW_HEADER) && !defined (_RWSTD_NO_NAMESPACE)
  46.   using std::tm;
  47.   using std::setlocale;
  48.   using std::strftime;
  49.   using std::mktime;
  50.   using std::strlen;
  51. #endif
  52.  
  53. // ------------------------------------------------
  54. // Template timepunct_data<charT> member templates.
  55. // ------------------------------------------------
  56.  
  57. template <class charT>
  58. timepunct_data<charT>::timepunct_data
  59.     (const timepunct_loc<charT> &init)
  60. {
  61.   int i;
  62.   for (i=0; i<7; i++) {
  63.     dn_[i][0]=init.get_day(i,false);
  64.     dn_[i][1]=init.get_day(i,true);
  65.   }
  66.   for (i=0; i<12; i++) {
  67.     mn_[i][0]=init.get_month(i,false);
  68.     mn_[i][1]=init.get_month(i,true);
  69.   }
  70.   ampm_[0]=init.get_ampm(false);
  71.   ampm_[1]=init.get_ampm(true);
  72.   bad_=init.get_bad();
  73.   for (i=0; i<100; i++)
  74.     ord_[i]=init.get_ord(i);
  75.   for (i=0; i<sizeof pat_/sizeof pat_[0]; i++)
  76.     pat_[i]=init.get_pattern(i);
  77. }
  78.  
  79. // struct for storing formatting information in map
  80. struct __fmt {
  81.   __fmt () {}
  82.   __fmt (int p, int l, char f) : position(p), length(l), fmtChar(f) {}
  83.   int position;
  84.   int length;
  85.   char fmtChar;
  86.   bool operator < (const __fmt& f) {
  87.     return position < f.position;
  88.   }
  89. };
  90.  
  91. // initialize data member pat_ which holds formatting strings
  92. template <class charT>
  93. void timepunct_data<charT>::__initpat (const locale* loc)
  94. {
  95.   const _RW_STD::string timeFmtChars("YyjSMIHmBbAapdZUWw");
  96.   tm tmb;
  97.   char buf[256];
  98.   __fmt fmtArray[20];
  99.  
  100.   // set up tmp
  101.   tmb.tm_sec = 56;
  102.   tmb.tm_min = 54;
  103.   tmb.tm_hour = 22;
  104.   tmb.tm_mday = 30;
  105.   tmb.tm_mon = 10;
  106.   tmb.tm_year = 90;
  107.   tmb.tm_wday = 5;
  108.   tmb.tm_yday = -1;
  109.   tmb.tm_isdst = -1;
  110.   (void) mktime(&tmb);
  111.   const _RW_STD::ctype<charT>& ct =
  112. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  113.     _RW_STD::use_facet<_RW_STD::ctype<charT> >(*loc);
  114. #else
  115.     _RW_STD::use_facet(*loc, (_RW_STD::ctype<charT>*)0);
  116. #endif
  117.  
  118.   // Set up passed in locale
  119.   _RW_STD::string oldlocale = setlocale(LC_ALL, 0);
  120. #ifdef __BORLANDC__
  121.   _RW_STD::string::size_type posd = loc->name().find('=')+1;
  122.   setlocale(LC_ALL, _RW_STD::string(loc->name(),posd,loc->name().find('\n')-posd).c_str());
  123. #else
  124.     setlocale(LC_ALL, loc->name().c_str());
  125. #endif // __BORLANDC__
  126.  
  127.   // for each composite format character create format string
  128.   const char do_as_pattern[] = "xXcDrT";
  129.   for (unsigned int j = 0; j < strlen(do_as_pattern); j++) {
  130.     // create format string to parse
  131.     _RW_STD::string timeFmtStr("% ");
  132.     timeFmtStr[1] = do_as_pattern[j];
  133.     strftime(buf, sizeof(buf), timeFmtStr.c_str(), &tmb);
  134.     _RW_STD::string timeFmt(buf);
  135.  
  136.     // starting at the beginning of the formatted string find each component
  137.     // and save in an ordered structure
  138.     int pos;
  139.     int fmtArrayIndex = 0;
  140.     for (unsigned int i=0; i < timeFmtChars.length(); i++) {
  141.       _RW_STD::string fmtChar("% ");
  142.       fmtChar[1] = timeFmtChars[i];
  143.       strftime(buf, sizeof(buf), fmtChar.data(), &tmb);
  144.       if ((pos = timeFmt.find(buf)) != -1) {
  145.         if (strlen(buf) > 0) {
  146.           fmtArray[fmtArrayIndex++] = __fmt(pos, strlen(buf), timeFmtChars[i]);
  147.           timeFmt.replace(pos, strlen(buf), strlen(buf), ' ');
  148.         }
  149.       }
  150.     }
  151.  
  152.     // sort format items
  153.     for (int top = fmtArrayIndex; top > 0; --top) {
  154.       int large = 0;
  155.       for (int i = 0; i < top; ++i) {
  156.     if (fmtArray[i] < fmtArray[large])
  157.       large = i;
  158.       }
  159.       __fmt temp = fmtArray[large];
  160.       fmtArray[large] = fmtArray[top-1];
  161.       fmtArray[top-1] = temp;
  162.     }
  163.  
  164.     // put format characters into formatting string
  165.     for (__fmt *p = fmtArray; p < fmtArray + fmtArrayIndex; ++p) {
  166.       timeFmt.replace((*p).position, (*p).length,
  167.               (_RW_STD::string("%").append(1,(*p).fmtChar)));
  168.     }
  169.  
  170.     // convert to string_type and insert in array pat_
  171.     string_type cnvt;
  172.     for (unsigned int k = 0; k < timeFmt.length(); k++)
  173.       cnvt = _RW_STD::operator + (cnvt, ct.widen(timeFmt[k]));
  174.     pat_[j] = cnvt;
  175.  
  176.   }
  177.  
  178.   setlocale(LC_ALL, oldlocale.c_str());
  179. }
  180.  
  181. template <class charT>
  182. void timepunct_data<charT>::__initfacet (const locale* loc) {
  183.   int i;
  184.   for (i=0; i<7; i++) {
  185.     dn_defs_[i][0].s=dn_[i][0].c_str();
  186.     dn_defs_[i][0].v=i;
  187.     dn_defs_[i][1].s=dn_[i][1].c_str();
  188.     dn_defs_[i][1].v=i;
  189.   }
  190.  
  191.   for (i=0; i<12; i++) {
  192.     mn_defs_[i][0].s=mn_[i][0].c_str();
  193.     mn_defs_[i][0].v=i;
  194.     mn_defs_[i][1].s=mn_[i][1].c_str();
  195.     mn_defs_[i][1].v=i;
  196.   }
  197.  
  198.   ampm_defs_[0].s=ampm_[0].c_str();
  199.   ampm_defs_[0].v= 0;
  200.   ampm_defs_[1].s=ampm_[1].c_str();
  201.   ampm_defs_[1].v= 1;
  202.  
  203.   dn_map_.num_defs_=7*2;
  204.   dn_map_.defs_=&(dn_defs_[0][0]);
  205.   mn_map_.num_defs_=12*2;
  206.   mn_map_.defs_=&(mn_defs_[0][0]);
  207.   ampm_map_.num_defs_=2;
  208.   ampm_map_.defs_=&(ampm_defs_[0]);
  209.   __initpat(loc);
  210. }
  211. // -----------------------------------------------
  212. // Facet rwstd::timepunct<charT> member templates.
  213. // -----------------------------------------------
  214.  
  215. #ifndef _RWSTD_NO_NAMESPACE
  216. } namespace __rwstd { // Leave std, enter __rwstd
  217. #endif
  218.  
  219. template <class charT>
  220. _RW_STD::locale::id timepunct<charT>::id;
  221.  
  222. template <class charT>
  223. void timepunct<charT>::__initfacet (const locale* loc) {
  224.   int n;
  225.   for (n=0; n<7; n++) {
  226.     this->dn_[n][false]=do_dayname(n,false);
  227.     this->dn_[n][true]=do_dayname(n,true);
  228.   }
  229.   for (n=0; n<12; n++) {
  230.     this->mn_[n][false]=do_monthname(n,false);
  231.     this->mn_[n][true]=do_monthname(n,true);
  232.   }
  233.   for (n=0; n<100; n++)
  234.     this->ord_[n]=do_ordinal(n);
  235.  
  236.   timepunct_impl<charT>::__initfacet(loc);
  237. }
  238.  
  239. template <class charT>
  240. _TYPENAME timepunct<charT>::string_type
  241. timepunct<charT>::do_dayname (int day, bool abbr) const {
  242.   return this->dn_[day][abbr];
  243. }
  244.  
  245. template <class charT>
  246. _TYPENAME timepunct<charT>::string_type
  247. timepunct<charT>::do_monthname (int mon, bool abbr) const {
  248.   return this->mn_[mon][abbr];
  249. }
  250.  
  251. template <class charT>
  252. _TYPENAME timepunct<charT>::string_type
  253. timepunct<charT>::do_ordinal (int number) const {
  254.   return (number<0 || number>99) ? this->bad_ : this->ord_[number];
  255. }
  256.  
  257. // -----------------------------------------------
  258. // Template digit_handler_base_1 member templates.
  259. // -----------------------------------------------
  260.  
  261. template <class charT>
  262. digit_handler_base_1<charT>::
  263. digit_handler_base_1 (const _RW_STD::locale &loc):
  264. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  265.     ctyp(_RW_STD::use_facet<_RW_STD::ctype<charT> >(loc)),
  266.     dmap(digit_map<charT>::get_digit_map(ctyp)),
  267.     punct(_RW_STD::use_facet<_RW_STD::numpunct<charT> >(loc))
  268. #else
  269.     ctyp(_RW_STD::use_facet(loc,(_RW_STD::ctype<charT>*)0)),
  270.     dmap(digit_map<charT>::get_digit_map(ctyp)),
  271.     punct(_RW_STD::use_facet(loc,(_RW_STD::numpunct<charT>*)0))
  272. #endif
  273. { }
  274.  
  275. template <class charT>
  276. digit_handler_base_1<charT>::
  277. digit_handler_base_1
  278.     (const _RW_STD::locale &loc, const punct_data<charT> &pun):
  279. #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  280.     ctyp(_RW_STD::use_facet<_RW_STD::ctype<charT> >(loc)),
  281.     dmap(digit_map<charT>::get_digit_map(ctyp)),
  282. #else
  283.     ctyp(_RW_STD::use_facet(loc,(_RW_STD::ctype<charT>*)0)),
  284.     dmap(digit_map<charT>::get_digit_map(ctyp)),
  285. #endif
  286.     punct(pun)
  287. { }
  288.  
  289. // ----------------------------------------------
  290. // Template digit_reader_base_1 member templates.
  291. // ----------------------------------------------
  292.  
  293. template <class charT>
  294. digit_reader_base_1<charT>::
  295. digit_reader_base_1 (const _RW_STD::locale &loc):
  296.     digit_handler_base_1<charT>(loc)
  297. { }
  298.  
  299. template <class charT>
  300. digit_reader_base_1<charT>::
  301. digit_reader_base_1 (const _RW_STD::locale &loc,
  302.     const punct_data<charT> &mp):
  303.     digit_handler_base_1<charT>(loc,mp)
  304. { }
  305.  
  306. // ---------------------------------------
  307. // Template digit_reader member templates.
  308. // ---------------------------------------
  309.  
  310. template <class charT,class InputIterator>
  311. digit_reader<charT,InputIterator>::
  312. digit_reader(InputIterator& i,InputIterator& e,_RW_STD::ios_base &b):
  313.     digit_reader_base_1<charT>(b.getloc()),
  314.     io(b), in(i), end(e)
  315. { }
  316.  
  317. template <class charT,class InputIterator>
  318. digit_reader<charT,InputIterator>::
  319. digit_reader(InputIterator& i,InputIterator& e,_RW_STD::ios_base &b,
  320.     const punct_data<charT> &mp):
  321.     digit_reader_base_1<charT>(b.getloc(),mp),
  322.     io(b), in(i), end(e)
  323. { }
  324.  
  325. template <class charT,class InputIterator>
  326. char* digit_reader<charT,InputIterator>::
  327.     get_digit_string (char *dpos)
  328. {
  329.   char *eod=dpos;
  330.   int i;
  331.  
  332.   while (!at_end() && (i=this->dmap.eval(*in))>=0 && i<this->radix) {
  333.     if (eod==this->digits+sizeof this->digits)
  334.       this->error|=this->too_many_digits;
  335.     else
  336.       *eod++=(char) i;
  337.     ++in;
  338.   }
  339.  
  340.   return eod;
  341. }
  342.  
  343. template <class charT,class InputIterator>
  344. char* digit_reader<charT,InputIterator>::
  345.     get_int_digits (void)
  346. {
  347.   charT c;
  348.   char *eod=this->digits;
  349.   const charT* ctype_punct=this->dmap.get_punct();
  350.  
  351.   if (!at_end() && this->is_signed)
  352.     // If a sign is present, set negative if it's a minus sign.
  353.     do {
  354.       if ((c=*in)==ctype_punct[this->minus])
  355.         this->negative=true;
  356.       else if (c!=ctype_punct[this->plus])
  357.         break;
  358.       // Eat white space after the sign.  Standard seems to mandate this
  359.       // regardless of whether ios_base::skipws is set.
  360.       do
  361.         ++in;
  362.       while (!at_end() && this->ctyp.is(_RW_STD::ctype_base::space,*in));
  363.       this->advanced=true;
  364.     } while (0);
  365.  
  366.   if (!this->radix) {
  367.     bool noradix = false;
  368.     switch (io.flags() & _RW_STD::ios_base::basefield) {
  369.      case _RW_STD::ios_base::dec:
  370.       this->radix=10;
  371.       break;
  372.      case _RW_STD::ios_base::hex:
  373.       this->radix=16;
  374.       break;
  375.      case _RW_STD::ios_base::oct:
  376.       this->radix=8;
  377.       break;
  378.      default:
  379.       noradix = true;
  380.     }
  381.     if (noradix || (io.flags() & _RW_STD::ios_base::showbase))
  382.     {
  383.       // No radix was forced by the ios_base flags, so poke around for a radix
  384.       // specifier on the front of the input value.
  385.       if (noradix)
  386.         this->radix=10;
  387.       if (!at_end() && *in==ctype_punct[this->zero]) {
  388.         this->radix=8;
  389.         ++in;
  390.         *eod++=0;
  391.         this->advanced=true;
  392.         if (!at_end() &&
  393.             ((c=*in)==ctype_punct[this->x] || c==ctype_punct[this->X]))
  394.         {
  395.           this->radix=16;
  396.           ++in;
  397.           eod--; // Leading 0 was not a digit after all.
  398.         }
  399.       }
  400.     }
  401.   }
  402.  
  403.   grouping=this->get_grouping();
  404.   if (!*grouping)
  405.     eod=get_digit_string(eod);
  406.   else {
  407.     gpos=groups;
  408.     thousands_sep=this->get_thousands_sep();
  409.     eod=get_digit_groups(eod);
  410.     if (!this->error && --gpos>groups) {
  411.       // Digit grouping is optional, but if present it must be right.
  412.       const char *gdef=grouping;
  413.       do {
  414.         if (*gdef!=*gpos && *gdef!=CHAR_MAX)
  415.           break;
  416.         else
  417.           if (gdef[1])
  418.             gdef++;
  419.       } while (--gpos>groups);
  420.  
  421.       if (gpos>groups || *gpos>*gdef)
  422.         this->error|=this->bad_grouping;
  423.     }
  424.   }
  425.  
  426.   if (eod>this->digits)
  427.     this->advanced=true;
  428.   return eod;
  429. }
  430.  
  431. template <class charT,class InputIterator>
  432. char* digit_reader<charT,InputIterator>::
  433.     get_float_digits (void)
  434. {
  435.   charT c;
  436.   this->radix=10;
  437.   char *eod=get_int_digits();
  438.  
  439.   const charT *ctyp_punct=this->dmap.get_punct();
  440.  
  441.   this->frac_beg=eod;
  442.   if (!this->error && !at_end() && *in==this->get_decimal_point()) {
  443.     in++;
  444.     eod=get_digit_string(eod);
  445.   }
  446.  
  447.   if (eod==this->digits)
  448.     this->error|=this->no_digits;
  449.  
  450.   this->exp_beg=eod;
  451.   this->exp_negative=false;
  452.   if (!this->error && !at_end() &&
  453.       ((c=*in)==ctyp_punct[this->e] || c==ctyp_punct[this->E]))
  454.   {
  455.     in++;
  456.     if (at_end())
  457.       this->error|=this->bad_exponent;
  458.     else {
  459.       if ((c=*in)==ctyp_punct[this->plus])
  460.         in++;
  461.       else if (c==ctyp_punct[this->minus]) {
  462.         this->exp_negative=true;
  463.         in++;
  464.       }
  465.  
  466.       int save_radix=this->radix;
  467.       this->radix=10;
  468.       eod=get_digit_string(eod);
  469.       this->radix=save_radix;
  470.       if (eod==this->exp_beg)
  471.         this->error|=this->bad_exponent;
  472.     }
  473.   }
  474.  
  475.   return eod;
  476. }
  477.  
  478. template <class charT,class InputIterator>
  479. char *digit_reader<charT,InputIterator>::
  480.     get_pointer_digits (void)
  481. {
  482.   this->radix=16;
  483.   char *eod=get_int_digits();
  484.   return eod;
  485. }
  486.  
  487. template <class charT,class InputIterator>
  488. char* digit_reader<charT,InputIterator>::
  489.     get_digit_groups (char *dpos)
  490. {
  491.   char *eod=get_digit_string(dpos);
  492.  
  493.   if (gpos==groups+sizeof groups)
  494.     this->error|=this->too_many_groups;
  495.   else {
  496.     int i=eod-dpos;
  497.     if (i >= CHAR_MAX)
  498.       this->error|=this->group_too_long;
  499.     else {
  500.       *gpos++=i;
  501.       if (i!=0 && !at_end() && *in==thousands_sep) {
  502.         ++in;
  503.         eod=get_digit_groups(eod);
  504.       }
  505.     }
  506.   }
  507.  
  508.   return eod;
  509. }
  510.  
  511. template <class charT,class InputIterator>
  512. int digit_reader<charT,InputIterator>::
  513.     get_keyword (const keyword_map<charT> &mapit)
  514. {
  515.   const keyword_def<charT> *canp=mapit.defs_;
  516.   const keyword_def<charT> *endp=mapit.defs_+mapit.num_defs_;
  517.   keyword_def<charT> cans[40],*ansp=cans;
  518.  
  519.   charT c;
  520.   const charT *p;
  521.   int result;
  522.  
  523.   while (1) {
  524.     if (at_end()) {
  525.       for ( ; canp<endp; canp++)
  526.         if (!*canp->s)
  527.           return canp->v;
  528.       return -1;
  529.     }
  530.     c=*in;
  531.     result=-1;
  532.     for ( ; canp<endp; canp++) {
  533.       p=canp->s;
  534.       if (c==*p) {
  535.         ansp->s=++p;
  536.         ansp->v=canp->v;
  537.         ansp++;
  538.       } else if (*p==0)
  539.         result=ansp->v; // abbreviation
  540.     }
  541.  
  542.     if (ansp==cans)
  543.       return result;
  544.     in++;
  545.     if (ansp==cans+1) {
  546.       for (p=cans[0].s; *p; p++) {
  547.         if (at_end() || *in!=*p)
  548.           return -1;
  549.         in++;
  550.       }
  551.       return cans[0].v;
  552.     }
  553.  
  554.     endp=ansp;
  555.     ansp=cans;
  556.     canp=cans;
  557.   }
  558. }
  559.  
  560. // ----------------------------------------------
  561. // Template digit_writer_base_1 member templates.
  562. // ----------------------------------------------
  563.  
  564. template <class charT>
  565. digit_writer_base_1<charT>::
  566. digit_writer_base_1(_RW_STD::ios_base &b,const _RW_STD::locale &loc) 
  567.  : digit_writer_base(b), digit_handler_base_1<charT>(loc)
  568. { }
  569.  
  570. template <class charT>
  571. digit_writer_base_1<charT>::
  572. digit_writer_base_1(_RW_STD::ios_base &b,const punct_data<charT> &mp)
  573.  : digit_writer_base(b),digit_handler_base_1<charT>(b.getloc(),mp)
  574. {
  575.   flags&=~(_RW_STD::ios_base::floatfield | _RW_STD::ios_base::showpos);
  576.   flags|=_RW_STD::ios_base::fixed;
  577.   radix=10;
  578.   precision=0;
  579. }
  580.  
  581. // ---------------------------------------
  582. // Template digit_writer member templates.
  583. // ---------------------------------------
  584.  
  585. template <class charT,class OutputIterator>
  586. digit_writer<charT,OutputIterator>::
  587. digit_writer (OutputIterator &o, _RW_STD::ios_base &b)
  588.  : digit_writer_base_1<charT>(b,b.getloc()), out(o) 
  589. { }
  590.  
  591. template <class charT,class OutputIterator>
  592. digit_writer<charT,OutputIterator>::
  593. digit_writer (OutputIterator &o, _RW_STD::ios_base &b,
  594.     const punct_data<charT> &mp)
  595.  : digit_writer_base_1<charT>(b,mp), out(o) 
  596. { }
  597.  
  598. template <class charT, class OutputIterator>
  599. void digit_writer<charT,OutputIterator>::put_digits (charT fill)
  600. {
  601.   char *p=this->start;
  602.   bool has_sign=false,has_point=false;
  603.   if (p<this->end && (*p==' ' || *p=='-' || *p=='+'))
  604.     has_sign=true;
  605.  
  606.   // Locate the end of the integral digits.
  607.   char *dec;
  608.   if (!this->fractional)
  609.     dec=this->end;
  610.   else {
  611.     dec=this->start;
  612.     if (has_sign) dec++;
  613.     for ( ; dec<this->end; dec++)
  614.       if (*dec<'0' || *dec>'9') {
  615.         if (*dec!='e' && *dec!='E')
  616.           has_point=true;
  617.         break;
  618.       }
  619.   }
  620.  
  621.   // Calculate the number and pattern of separators needed if any.
  622.   charT separator;
  623.   int unGrouped=dec-this->start;
  624.   if (has_sign)
  625.     unGrouped--;
  626.   if (this->radix==10 && this->separable) {
  627.     unGrouped=calc_groups(unGrouped,this->get_grouping());
  628.     if (this->num_groups)
  629.       separator=this->get_thousands_sep();
  630.   }
  631.  
  632.   // Compute the number of fill charT-s needed, and where they should be put.
  633.   int leftFill=0,internalFill=0,rightFill=0;
  634.   if (this->width>0) {
  635.     int w=this->width - (this->end - this->start) - this->num_groups;
  636.     this->width=0;
  637.     if (w>0) {
  638.       switch (this->adjust) {
  639.        case digit_writer_base::left:
  640.         rightFill=w;
  641.         break;
  642.        case digit_writer_base::internal:
  643.         internalFill=w;
  644.         break;
  645.        default:
  646.         leftFill=w;
  647.       }
  648.     }
  649.   }
  650.  
  651.   // Widen the sign + digits + exponent string.
  652. //charT wide_digits[sizeof digit_writer_base::buffer];
  653.   charT wide_digits[400];
  654.   this->ctyp.widen(this->start,this->end,wide_digits);
  655.  
  656.   // Write the widened string with fill and decorations to output.
  657.   charT *digit_pos=wide_digits;
  658.   while (leftFill--)
  659.     *out++=fill;
  660.   if (has_sign)
  661.     *out++=*digit_pos++;    // the widened sign
  662.   while (internalFill--)
  663.     *out++=fill;
  664.   while (unGrouped--)
  665.     *out++=*digit_pos++;
  666.   while (this->num_groups--) {
  667.     *out++=separator;
  668.     while (this->group[0]--)
  669.       *out++=*digit_pos++;
  670.     this->group++;
  671.   }
  672.  
  673.   if (has_point) {
  674.     *out++=this->get_decimal_point();
  675.     digit_pos++;
  676.   }
  677.  
  678.   unGrouped=this->end-dec;
  679.   if (has_point)
  680.     unGrouped--;
  681.   while (unGrouped-->0)
  682.     *out++=*digit_pos++;
  683.  
  684.   while (rightFill--)
  685.     *out++=fill;
  686. }
  687.  
  688. template <class charT, class OutputIterator>
  689. void digit_writer<charT,OutputIterator>::
  690.     put_keyword (const string_type &k, charT fill)
  691. {
  692.   int leftFill=0,rightFill=0;
  693.   int n=this->width-k.length();
  694.   if (n>0) {
  695.     switch (this->adjust) {
  696.      case digit_writer_base::left:
  697.       rightFill=n;
  698.       break;
  699.      case digit_writer_base::internal:
  700.      default:
  701.       leftFill=n;
  702.     }
  703.     if (leftFill)
  704.       do *out++=fill;
  705.       while (--leftFill);
  706.   }
  707.  
  708.   const charT *p=k.c_str(),*end=p+k.length();
  709.   while (p<end)
  710.     *out++=*p++;
  711.  
  712.   if (rightFill)
  713.     do *out++=fill;
  714.     while (--rightFill);
  715. }
  716.  
  717. #ifndef _RWSTD_NO_NAMESPACE
  718. } // namespace __rwstd
  719. #endif
  720.  
  721. #endif // __STD_RW_NUMBRW_CC__
  722.  
  723. #pragma option pop
  724. #endif /* __NUMBRW_CC */
  725.