/****************************************************************************
 *
 * rw/numbrw - Internal classes for numeric formatting and parsing.
 *
 ***************************************************************************
 *
 *  Copyright 2000 Compaq Computer Corporation
 *
 *  COMPAQ Registered in U.S. Patent and Trademark Office.
 *
 *  Confidential computer software. Valid license from Compaq required for
 *  possession, use or copying. Consistent with FAR 12.211 and 12.212,
 *  Commercial Computer Software, Computer Software Documentation, and
 *  Technical Data for Commercial Items are licensed to the U.S. Government
 *  under vendor's standard commercial license.
 *
 ****************************************************************************
 *
 * (c) Copyright 1994, 1998 Rogue Wave Software, Inc.
 * ALL RIGHTS RESERVED
 *
 * The software and information contained herein are proprietary to, and
 * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
 * intends to preserve as trade secrets such software and information.
 * This software is furnished 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 software and information or any other copies thereof may
 * not be provided or otherwise made available to any other person.
 *
 * Notwithstanding any other lease or license that may pertain to, or
 * accompany the delivery of, this computer software and information, the
 * rights of the Government regarding its use, reproduction and disclosure
 * are as set forth in Section 52.227-19 of the FARS Computer
 * Software-Restricted Rights clause.
 * 
 * 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.
 * Contractor/Manufacturer is Rogue Wave Software, Inc.,
 * P.O. Box 2328, Corvallis, Oregon 97339.
 *
 * This computer software and information is distributed with "restricted
 * rights."  Use, duplication or disclosure is subject to restrictions as
 * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
 * Computer Software-Restricted Rights (April 1985)."  If the Clause at
 * 18-52.227-74 "Rights in Data General" is specified in the contract,
 * then the "Alternate III" clause applies.
 *
 ***************************************************************************/

#ifndef __STD_RW_LOCNUMRW
#define __STD_RW_LOCNUMRW

#ifndef _RWSTD_NO_NEW_HEADER
#include <ctime>
#else
#include <time.h>
#endif

#if defined(__DECCXX) && defined(__linux__) && !defined(__DECFIXCXXL1283)
#include <fcntl.h>
#include <unistd.h>
#endif

#if defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1283)
#include <cxxstd_prefix>
#endif

#if defined(__DECCXX)
#   ifdef __PRAGMA_ENVIRONMENT
#      pragma __environment __save
#      pragma __environment __cxx_header_defaults
#   endif
#endif

#if defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1158)
#pragma __extern_prefix __save
#pragma __extern_prefix "CXXL$" 
#endif


#ifndef _RWSTD_NO_NAMESPACE
namespace _RWrwstd {
#endif

// -------------------------------------------------------
// Implementation class template -- timepunct_init<charT>.
// -------------------------------------------------------

// Structure used to initialize the private data members of timepunct<charT>.
template <class charT>
class _RWSTDExportTemplate timepunct_init
{
public:
  const charT *dn_[7][2];       // Day names and abbreviations
  const charT *mn_[12][2];      // Month names and abbreviations
  const charT *ampm_[2];        // AM/PM strings
  const charT *bad_;            // Bad value output signal
  const charT *ord_[100];       // Ordinal numbers
  const charT *pat_[6];         // Patterns for formats "xXcDrT" resp.
};

template <class charT>
class _RWSTDExport timepunct_loc;

_RWSTD_TEMPLATE
class _RWSTDExport timepunct_loc<char> 
{
  typedef _RW_STD::basic_string<char,_RW_STD::char_traits<char>,_RW_STD::allocator<char> > string_type;
  const timepunct_init<char>& ti_;

 public:
  timepunct_loc (const timepunct_init<char> &i)
    : ti_(i) 
  {}

  const string_type get_day(int i, bool abbr) const;
  const string_type get_month(int i, bool abbr) const;
  const string_type get_ampm(bool afternoon) const;
  const string_type get_bad() const  { return ti_.bad_; }
  const string_type get_ord(int i) const { return ti_.ord_[i]; }
  const string_type get_pattern(int i) const { return ti_.pat_[i]; }
};

#ifndef _RWSTD_NO_WIDE_CHAR
_RWSTD_TEMPLATE
class _RWSTDExport timepunct_loc<wchar_t> 
{
  typedef _RW_STD::basic_string<wchar_t,_RW_STD::char_traits<wchar_t>,_RW_STD::allocator<wchar_t> > string_type;
  const timepunct_init<wchar_t>& ti_;

 public:
  timepunct_loc (const timepunct_init<wchar_t> &i)
    : ti_(i) 
  {}

#ifndef _RWSTD_NO_WSTR
  const string_type get_day(int i, bool abbr) const;
  const string_type get_month(int i, bool abbr) const;
  const string_type get_ampm(bool afternoon) const;
#else
  const string_type get_day(int i, bool abbr) const { return ti_.dn_[i][abbr]; }
  const string_type get_month(int i, bool abbr) const { return ti_.mn_[i][abbr]; }
  const string_type get_ampm(bool afternoon) const { return ti_.ampm_[afternoon]; }
#endif //  _RWSTD_NO_WSTR
  const string_type get_bad() const  { return ti_.bad_; }
  const string_type get_ord(int i) const { return ti_.ord_[i]; }
  const string_type get_pattern(int i) const { return ti_.pat_[i]; }
};
#endif // _RWSTD_NO_WIDE_CHAR


template <class charT>
class _RWSTDExportTemplate timepunct_loc
{
  typedef _RW_STD::basic_string<charT,_RW_STD::char_traits<charT>,_RW_STD::allocator<charT> > string_type;
  const timepunct_init<charT>& ti_;

 public:
  timepunct_loc (const timepunct_init<charT> &i)
    : ti_(i) 
  {}

  const string_type get_day(int i, bool abbr) const  { return ti_.dn_[i][abbr]; }
  const string_type get_month(int i, bool abbr) const { return ti_.mn_[i][abbr]; }
  const string_type get_ampm(bool afternoon) const { return ti_.ampm_[afternoon]; }
  const string_type get_bad() const  { return ti_.bad_; }
  const string_type get_ord(int i) const { return ti_.ord_[i]; }
  const string_type get_pattern(int i) const { return ti_.pat_[i]; }
};

// -------------------------------------------------------
// Implementation class template -- timepunct_data<charT>.
// -------------------------------------------------------

// timepunct<charT> derives from this (via rwstd::timepunct_impl) to get its
// private data members.

template <class charT>
class _RWSTDExportTemplate timepunct_data {
  friend class timepunct<charT>;
  friend class keyword_cracker<charT>;
 public:
  typedef _RW_STD::basic_string<charT,_RW_STD::char_traits<charT>,_RW_STD::allocator<charT> > string_type;
 private:

  string_type dn_[7][2];
  string_type mn_[12][2];
  string_type ampm_[2];
  string_type bad_;
  string_type ord_[100];
  string_type pat_[6];

  keyword_def<charT> dn_defs_[7][2];
  keyword_map<charT> dn_map_;
  keyword_def<charT> mn_defs_[12][2];
  keyword_map<charT> mn_map_;

 protected:
  timepunct_data (const timepunct_loc<charT> &i);

#if defined(__DECCXX) && !defined(__DECFIXCXXL957)
  void _RWinitfacet (const locale*);
#else
  void _RWinit_facet (const locale*);
#endif
};

// -------------------------------------------------------
// Implementation class template -- timepunct_impl<charT>.
// -------------------------------------------------------

// timepunct<charT> derives from this to get the parts of its behavior that
// must be specialized on the character type.  Currently the only specialized
// behavior is the initialization logic in the constructor.

template <class charT>
class _RWSTDExportTemplate timepunct_impl :
    public timepunct_data<charT>
{
 protected:
  timepunct_impl(void);
};

_RWSTD_TEMPLATE
class _RWSTDExport timepunct_impl<char>:                 // Specialization
    public timepunct_data<char>
{
#ifndef _MSC_VER
  static _RWSTDExport timepunct_init<char> _RWivals;      // Vendor-supplied
#else
  static timepunct_init<char> _RWivals;
#endif

 protected:
  timepunct_impl (void):
    timepunct_data<char>(timepunct_loc<char>(_RWivals)) { }
};

#ifndef _RWSTD_NO_WIDE_CHAR
_RWSTD_TEMPLATE
class _RWSTDExport timepunct_impl<wchar_t>:              // Specialization
    public timepunct_data<wchar_t>
{
#ifndef _MSC_VER
  static _RWSTDExport timepunct_init<wchar_t> _RWivals;   // Vendor-supplied
#else
  static timepunct_init<wchar_t> _RWivals;
#endif

 protected:
  timepunct_impl(void):
      timepunct_data<wchar_t>(timepunct_loc<wchar_t>(_RWivals)) { }
};
#endif // _RWSTD_NO_WIDE_CHAR


// ----------------------------------------------------
// Time and date punctuation facet -- timepunct<charT>.
// ----------------------------------------------------

template <class charT>
class _RWSTDExportTemplate timepunct : public _RW_STD::locale::facet,
    public timepunct_impl<charT>
{
 public:
  typedef charT char_type;
  typedef _RW_STD::basic_string<charT,_RW_STD::char_traits<charT>,_RW_STD::allocator<charT> >
    string_type;

  _EXPLICIT timepunct (size_t refs=0):
      _RW_STD::locale::facet(refs,_RW_STD::locale::time) { }

  string_type dayname (int day, bool abbreviated) const
      { return do_dayname(day,abbreviated); }
  string_type monthname (int month, bool abbreviated) const
      { return do_monthname(month,abbreviated); }
  string_type ordinal (int number) const
      { return do_ordinal(number); }

  static _RW_STD::locale::id id;

  // Implementation:
  enum { _RWfacet_cat = _RW_STD::locale::time, _RWok_implicit = 1 };

 protected:
  virtual ~timepunct() { }

  virtual string_type do_dayname (int day, bool abbreviated) const;
  virtual string_type do_monthname (int month, bool abbreviated) const;
  virtual string_type do_ordinal (int number) const;

 private:

#if defined(__DECCXX) && !defined(__DECFIXCXXL957)
  void _RWinitfacet (const locale*);
#else
  void _RWinit_facet (const locale*);
#endif

  #ifdef _RWSTD_NO_MEMBER_TEMPLATES
  _RW_STD::locale::id &_RWget_id (void) const { return id; }
  #endif
};


#if defined(__DECCXX) && !defined(__DECFIXCXXL646)

// --------------------------------------------------
// Standard derived facet -- timepunct_byname<charT>.
// --------------------------------------------------

template <class charT>
class timepunct_byname: public timepunct<charT> {
 public:
  _EXPLICIT timepunct_byname (const char*, size_t refs=0);

 protected:
  virtual ~timepunct_byname();

// Virtual member functions inherited from timepunct<charT>:
// virtual string_type do_dayname (int day, bool abbreviated) const;
// virtual string_type do_monthname (int month, bool abbreviated) const;
// virtual string_type do_ordinal (int number) const;
};

// --------------------------------------------------------
// Standard facet specialization -- timepunct_byname<char>.
// --------------------------------------------------------

template <>
class timepunct_byname<char> : public timepunct<char> {

 public:
  _EXPLICIT timepunct_byname (const char*, size_t refs=0);

 protected:
  virtual ~timepunct_byname();

  virtual string_type do_dayname (int day, bool abbreviated) const;
  virtual string_type do_monthname (int month, bool abbreviated) const;
// Virtual member functions inherited from timepunct<charT>:
// virtual string_type do_ordinal (int number) const;

 private:
  char* WeekDayName[7][2];
  char* MonthName[12][2];
};

// -----------------------------------------------------------
// Standard facet specialization -- timepunct_byname<wchar_t>.
// -----------------------------------------------------------

#ifndef _RWSTD_NO_WIDE_CHAR  
#ifndef _RWSTD_NO_WSTR

template <>
class timepunct_byname<wchar_t> : public timepunct<wchar_t> {

 public:
  _EXPLICIT timepunct_byname (const char*, size_t refs=0);

 protected:
  virtual ~timepunct_byname();

  virtual string_type do_dayname (int day, bool abbreviated) const;
  virtual string_type do_monthname (int month, bool abbreviated) const;
// Virtual member functions inherited from timepunct<charT>:
// virtual string_type do_ordinal (int number) const;

 private:
  wchar_t* WeekDayName[7][2];
  wchar_t* MonthName[12][2];
};

#endif // _RWSTD_NO_WSTR
#endif // _RWSTD_NO_WIDE_CHAR

#endif // 646

// --------------------------------------------------------
// Implementation class template -- keyword_cracker<charT>.
// --------------------------------------------------------

// Gives derived classes a backdoor way to get the private keyword_map and
// other members out of numpunct and timepunct facets.

template <class charT>
class _RWSTDExportTemplate keyword_cracker {
 public:
  static const keyword_map<charT>& get_tf_map
      (const _RW_STD::numpunct<charT> &nump)
      { return nump.tf_map_; }
  static const keyword_map<charT>& get_day_map
      (const timepunct<charT>& timp)
      { return timp.dn_map_; }
  static const keyword_map<charT>& get_month_map
      (const timepunct<charT>& timp)
      { return timp.mn_map_; }
#ifndef _RWSTD_NO_NAMESPACE
  static const _TYPENAME _RW_STD::numpunct<charT>::string_type& get_tf_string
#else
  static const _TYPENAME numpunct<charT>::string_type& get_tf_string
#endif
      (const _RW_STD::numpunct<charT>& nump,bool v)
      { return v? nump.tn_ : nump.fn_; }
  static const _TYPENAME timepunct<charT>::string_type&
      get_day_string
      (const timepunct<charT>& timp,unsigned n,bool abbr)
      { return n<7? timp.dn_[n][abbr] : timp.bad_; }
  static const _TYPENAME timepunct<charT>::string_type&
      get_month_string
      (const timepunct<charT>& timp,unsigned n,bool abbr)
      { return n<12? timp.mn_[n][abbr] : timp.bad_; }
  static const _TYPENAME timepunct<charT>::string_type&
      get_ampm_string
      (const timepunct<charT>& timp,bool pm)
      { return timp.ampm_[pm]; }
  static const _TYPENAME timepunct<charT>::string_type&
      get_ord_string
      (const timepunct<charT>& timp,unsigned n)
      { return n<99? timp.ord_[n] : timp.bad_; }
  static const _TYPENAME timepunct<charT>::string_type&
      get_patt_string
      (const timepunct<charT>& timp,unsigned n)
      { return n<6? timp.pat_[n] : timp.bad_; }
};

// -------------------------------------------------------------
// Implementation class template -- digit_handler_base_1<charT>.
// -------------------------------------------------------------

// Contains charT-dependent functionality that is common to the digit_reader
// and digit_writer classes, particularly related to getting access to ctype
// and punct facets they both use.

template <class charT>
class _RWSTDExportTemplate digit_handler_base_1:
    public keyword_cracker<charT>
{
 public:
  const _RW_STD::ctype<charT> &ctyp;
  const digit_map<charT>& dmap;
  const punct_data<charT>& punct;

  // Constructor for general numerics, gets punct from loc's numpunct facet.
  digit_handler_base_1 (const _RW_STD::locale &loc);

  // Constructor for money, passed punct_data is in fact a moneypunct facet.
  digit_handler_base_1 (const _RW_STD::locale &loc,const punct_data<charT>&);
};

// ------------------------------------------
// Implementation class -- digit_reader_base.
// ------------------------------------------

// Contains digit_reader members that do not depend on the digit_reader
// template parameters, particularly for converting strings of char digits
// to long and floating-point binary values.

class _RWSTDExport digit_reader_base : public digit_map_base
{
 public:
  enum {
    good              = 0x0000,
    no_digits         = 0x0001,
    too_many_digits   = 0x0002,
    too_many_groups   = 0x0004,
    group_too_long    = 0x0008,
    group_is_empty    = 0x0010,
    bad_grouping      = 0x0020,
    bad_exponent      = 0x0040,
    overflow          = 0x0080,
    bad_curr_symbol   = 0x0100,
    bad_sign          = 0x0200
  };

  enum {
#if defined(__DECCXX) && !defined(__DECFIXCXXL870) // see 870.5
    // LDBL_MAX_10_EXP on steel + 200
    digit_buf_size = 4932+200
#else
    digit_buf_size = LDBL_MAX_10_EXP+200
#endif
  };

  // Fields defining digits to be converted, usually filled in by derived
  // class before calling one of the conversion methods below.
  int error;                    // Bit-field
  int radix;                    // 8, 10, or 16, 0=not yet determined
  bool is_signed;               // Sign allowed in input
  bool negative;                // Minus sign was present
  bool advanced;                // Iterator was advanced
  bool reached_end;             // Needed a char, but iterator matched end
  bool exp_negative;            // Minus sign was present on exponent
  char *frac_beg;               // Start of fractional part of digits
  char *exp_beg;                // Start of exponent in digits
  char digits[digit_buf_size];  // Binary digits (i.e. 0,1,2 not '0','1','2')

  digit_reader_base (void): error(good), radix(0),
      is_signed(true), negative(false), advanced(false), reached_end(false)
  { }

  unsigned long to_ulong (char *end);
  unsigned long to_ulong_dec (char *beg,char *end);

#ifdef _RWSTD_LONG_LONG
  unsigned _RWSTD_LONG_LONG to_ulong_ulong (char *end);
#endif

  void *to_pointer (char *end);
#if (defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1247) && (defined(__G_FLOAT) && __G_FLOAT==0))
#  pragma __extern_prefix __save
#  pragma __extern_prefix __CXXSTD_FLOAT_FUNC_PREFIX
#endif
  float to_float (char *end);
  double to_double (char *end);

#if defined(__DECCXX) && !defined(__DECFIXCXXL870) && !defined(_RWSTD_NO_LONG_DOUBLE)
  // inlined from vendor.cpp for 128 long double support
  inline long double to_long_double (char *end) {
    long double result=0.0;
    to_floating_point(end,"%Le",&result);
    return result;
  }
#else
  long double to_long_double (char *end);
#endif
#if (defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1247) && (defined(__G_FLOAT) && __G_FLOAT==0))
#  pragma __extern_prefix __restore
#endif

 private:
#if (defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1247) && (defined(__G_FLOAT) && __G_FLOAT==0))
#  pragma __extern_prefix __save
#  pragma __extern_prefix __CXXSTD_FLOAT_FUNC_PREFIX
#endif

#if defined(__DECCXX) && !defined(__DECFIXCXXL1463)
  void to_floating_point (const char *end, const char *pattern, void *result);
#else
  void to_floating_point (char *end, char *pattern, void *result);
#endif

#if defined(__DECCXX) && !defined(__DECFIXCXXL870) && !defined(_RWSTD_NO_LONG_DOUBLE)

#if defined(__DECCXX) && !defined(__DECFIXCXXL1463)
  void to_floating_point (const char *end, const char *pattern, long double *result);
#else
  void to_floating_point (char *end, char *pattern, long double *result);
#endif

#endif
#if (defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1247) && (defined(__G_FLOAT) && __G_FLOAT==0))
#  pragma __extern_prefix __restore
#endif
};

// ------------------------------------------------------------
// Implementation class template -- digit_reader_base_1<charT>.
// ------------------------------------------------------------

// Contains parts of digit_reader that depend on charT but not on the iterator
// type.

template <class charT>
class _RWSTDExportTemplate digit_reader_base_1 :
    public digit_reader_base,
    public digit_handler_base_1<charT>
{
 public:
  typedef _RW_STD::basic_string<charT,_RW_STD::char_traits<charT>,_RW_STD::allocator<charT> > string_type;

 protected:
  // Constructor for general numerics, gets punct from loc's numpunct<charT>.
  digit_reader_base_1 (const _RW_STD::locale &loc);

  // Constructor for use by derived money_reader, caller passes punct, which
  // in fact is loc's moneypunct<charT,true|false> facet.
  digit_reader_base_1 (const _RW_STD::locale &loc, const punct_data<charT>&);

  // These could be moved to digit_handler_base_1<charT> ...
  charT get_decimal_point() const { return this->punct.dp_; }
  charT get_thousands_sep() const { return this->punct.ts_; }
  const char *get_grouping() const { return this->punct.gr_.c_str(); }
};

// -------------------------------------------------------------------
// Implementation class template -- digit_reader<charT,InputIterator>.
// -------------------------------------------------------------------

// Facets that do numeric input use temporary objects of this class to
// extract keywords and strings of digits and punctuation from the input
// stream.

template <class charT,class InputIterator>
class _RWSTDExportTemplate digit_reader :
    public digit_reader_base_1<charT>
{
 public:
  // Constructor for reading general numerics.
  digit_reader (InputIterator& in,InputIterator& end,
      _RW_STD::ios_base &io);

 protected:
  // Constructor for use by derived money_reader class.
  digit_reader (InputIterator& in,InputIterator& end,
      _RW_STD::ios_base &io,const punct_data<charT>&);

 public:
  char *get_int_digits (void);      // Get integer-format digits
  char *get_float_digits (void);    // Get floating point-format digits
  char *get_pointer_digits (void);  // Get pointer-format digits

  // Parse keyword from input, return associated integer value
  int get_keyword (const keyword_map<charT>&);

 protected:
  _RW_STD::ios_base &io;
  InputIterator& in;
  InputIterator& end;

  const char *grouping;
  charT thousands_sep;
  char groups[40];
  char *gpos;

  // Helper functions
  char *get_digit_string (char*);       // Get a string of digits
  char *get_digit_groups (char*);       // Get grouped digits (recursive)

  inline bool at_end (void) {           // Test for end of stream, and
    if (in==end) {                      //  remember whether end was
      this->reached_end=true;           //  ever reached
      return true;
    }
    return false;
  }
};


// ------------------------------------------
// Implementation class -- digit_writer_base.
// ------------------------------------------

// Contains the parts of digit_writer that do not depend on the template
// parameters.

class _RWSTDExport digit_writer_base :
    public digit_map_base
{
 public:
  digit_writer_base (_RW_STD::ios_base &b);

  void get_pattern(char *p, char *prefix, bool is_signed);
  bool get_f_pattern(char *p, char prefix);
  void digitize (const void*);
  void digitize (unsigned short);
  void digitize (short);
  void digitize (unsigned int);
  void digitize (int);
  void digitize (unsigned long);
  void digitize (long);
#ifdef _RWSTD_LONG_LONG
  void digitize (unsigned _RWSTD_LONG_LONG);
  void digitize (_RWSTD_LONG_LONG);
#endif

#if defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1247) && (!defined(__G_FLOAT) || (__G_FLOAT==0)) 
#  pragma __extern_prefix __save
#  pragma __extern_prefix __CXXSTD_FLOAT_FUNC_PREFIX
#endif
  void digitize (double);
#ifndef _RWSTD_NO_LONG_DOUBLE
  void digitize (long double);
#endif
#if defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1247) && (!defined(__G_FLOAT) || (__G_FLOAT==0)) 
#  pragma __extern_prefix __restore
#endif

  _RW_STD::ios_base &io;
  _RW_STD::ios_base::fmtflags flags;
  int precision,width,radix,iprecision,num_groups;
  enum { left, internal, right } adjust;
  bool fractional,separable;
  char *start,*end,*group;
  char buffer[400];
  char groups[150];

  int calc_groups (int,const char*);
};

// ------------------------------------------------------------
// Implementation class template -- digit_writer_base_1<charT>.
// ------------------------------------------------------------

// Contains parts of digit_writer<charT,OutputWriter> that depend only on the
// charT parameter.

template <class charT>
class _RWSTDExportTemplate digit_writer_base_1 :
    public digit_writer_base,
    public digit_handler_base_1<charT>
{
 public:
  typedef _RW_STD::basic_string<charT,_RW_STD::char_traits<charT>,_RW_STD::allocator<charT> > string_type;

 protected:
  // Constructor for general numerics, gets punct from loc's numpunct<charT>.
  digit_writer_base_1
      (_RW_STD::ios_base&,const _RW_STD::locale&);

  // Constructor for money, passed punct is really a moneypunct<charT,Intl>.
  digit_writer_base_1  (_RW_STD::ios_base&,const punct_data<charT>&);

  // These could be moved to digit_handler_base_1<charT> ...
  charT get_decimal_point() const { return this->punct.dp_; }
  charT get_thousands_sep() const { return this->punct.ts_; }
  const char *get_grouping() const { return this->punct.gr_.c_str(); }
};

// --------------------------------------------------------------------
// Implementation class template -- digit_writer<charT,OutputIterator>.
// --------------------------------------------------------------------

// Facets that do numeric output use temporary objects of this type (on the
// stack) to convert numeric quantities into sequences of digits and other
// punctuation.

template <class charT,class OutputIterator>
class _RWSTDExportTemplate digit_writer :
    public digit_writer_base_1<charT>
{
 public:
  typedef _RW_STD::basic_string<charT,_RW_STD::char_traits<charT>,_RW_STD::allocator<charT> > string_type;

  // Constructor for general numerics.
  digit_writer (OutputIterator&,_RW_STD::ios_base&);

 protected:
  // Constructor for use by derived money_writer classes, passed punct_data is
  // really a moneypunct<charT,Intl> facet.
  digit_writer (OutputIterator&,_RW_STD::ios_base&,
      const punct_data<charT>&);

 public:
  void put_digits (charT fill);
  void put_keyword (const string_type&,charT fill);

 protected:
  OutputIterator &out;
};


#ifndef _RWSTD_NO_NAMESPACE
} // namespace _RWrwstd
#endif

#ifndef __FORCE_INSTANTIATIONS
// numbrw
#pragma do_not_instantiate _RWrwstd::digit_handler_base_1<char>::digit_handler_base_1(const std::locale &)
#pragma do_not_instantiate _RWrwstd::digit_reader_base_1<char>::digit_reader_base_1(const std::locale &)
#pragma do_not_instantiate _RWrwstd::digit_reader<char, std::istreambuf_iterator<char, std::char_traits<char> > >::digit_reader(std::istreambuf_iterator<char, std::char_traits<char> > &, std::istreambuf_iterator<char, std::char_traits<char> > &, std::ios_base &)
#pragma do_not_instantiate char *_RWrwstd::digit_reader<char, std::istreambuf_iterator<char, std::char_traits<char> > >::get_int_digits()
#pragma do_not_instantiate char *_RWrwstd::digit_reader<char, std::istreambuf_iterator<char, std::char_traits<char> > >::get_pointer_digits()
#pragma do_not_instantiate int _RWrwstd::digit_reader<char, std::istreambuf_iterator<char, std::char_traits<char> > >::get_keyword(const _RWrwstd::keyword_map<char> &)
#pragma do_not_instantiate char *_RWrwstd::digit_reader<char, std::istreambuf_iterator<char, std::char_traits<char> > >::get_digit_string(char *)
#pragma do_not_instantiate char *_RWrwstd::digit_reader<char, std::istreambuf_iterator<char, std::char_traits<char> > >::get_digit_groups(char *)
#endif

#if defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1158)
#   pragma __extern_prefix __restore
#endif

#ifdef _RWSTD_COMPILE_INSTANTIATE
#include <numbrw.cc>
#endif

#if defined(__DECCXX)
#   ifdef __PRAGMA_ENVIRONMENT
#      pragma __environment __restore
#   endif
#endif

#endif

