______________________________________________________________________

  Annex D (normative)

  Compatibility features                                [depr]

  ______________________________________________________________________

1 This Clause describes features of the C++ Standard that are  specified
  for compatibility with existing implementations.

  +-------                 BEGIN BOX 1                -------+
  Editorial proposal: Specify these as deprecated features, where depre­
  cated is defined as:

  Normative for the current edition of the Standard, but are not guaran­
  teed to be part of the Standard in future revisions.
  +-------                  END BOX 1                 -------+

  D.1  Standard C library headers                       [depr.c.headers]

1 For  compatibility  with  the  Standard  C  library,  the C++ Standard
  library provides the 18 C headers, as shown in Table 1:

                            Table 1--C Headers

      <assert.h>   <iso646.h>   <setjmp.h>   <stdio.h>    <wchar.h>
      <ctype.h>    <limits.h>   <signal.h>   <stdlib.h>   <wctype.h>
      <errno.h>    <locale.h>   <stdarg.h>   <string.h>
      <float.h>    <math.h>     <stddef.h>   <time.h>

2 Each C header, whose name has the form  name.h,  includes  its  corre­
  sponding  C++  header cname, followed by an explicit using-declaration
  (_namespace.udecl_) for each  name  placed  in  the  standard  library
  namespace by the header (_lib.headers_).

3 [Example:  The  header <cstdlib> provides its declarations and defini­
  tions within the namespace std.  The  header  <stdlib.h>  makes  these
  available in the global name space, much as in the C Standard.   --end
  example]

  +-------                 BEGIN BOX 2                -------+
  Editorial proposal: Add the following paragraph:

  The C++ headers

  --<iostream.h> and

  --<strstream.h>
    are similarly available.
  +-------                  END BOX 2                 -------+

  D.2  Old iostreams members                          [depr.ios.members]

1 The following member names are  in  addition  to  names  specified  in
  Clause _lib.iostreams_:
  namespace std {
    class ios_base {
    public:
      typedef T1  io_state;
      typedef T2 open_mode;
      typedef T3  seek_dir;
      // remainder unchanged
    };
  }

2 The  type io_state is a synonym for an integer type (indicated here as
  T1) that permits certain member functions to overload others on param­
  eters of type iostate and provide the same behavior.

3 The type open_mode is a synonym for an integer type (indicated here as
  T2) that permits certain member functions to overload others on param­
  eters of type openmode and provide the same behavior.

4 The  type seek_dir is a synonym for an integer type (indicated here as
  T3) that permits certain member functions to overload others on param­
  eters of type iostate and provide the same behavior.

5 An  implementation  may  provide the following additional member func­
  tion,    which    has    the    effect     of     calling     sbumpc()
  (_lib.streambuf.pub.get_):
  namespace std {
    template<class charT, class traits = ios_traits<charT> >
    class basic_streambuf {
    public:
      void stossc();
      // remainder unchanged
    };
  }

6 An  implementation  may  provide  the  following member functions that
  overload signatures specified in Clause _lib.iostreams_:

  namespace std {
    template<class charT, class Traits> class basic_ios {
    public:
      void clear(io_state state);
      void setstate(io_state state);
      // remainder unchanged
    };
    class ios_base {
    public:
      void exceptions(io_state);
      // remainder unchanged
    };
    template<class charT, class traits = ios_traits<charT> >
    class basic_streambuf {
    public:
      pos_type pubseekoff(off_type off, ios_base::seek_dir way,
                ios_base::open_mode which = ios_base::in | ios_base::out);
      pos_type pubseekpos(pos_type sp,
                ios_base::open_mode which = ios_base::in | ios_base::out);
      // remainder unchanged
    };
    template <class charT, class traits = ios_traits<charT> >
    class basic_filebuf : public basic_streambuf<charT,traits> {
    public:
      basic_filebuf<charT,traits>* open(const char* s, ios_base::open_mode mode);
      // remainder unchanged
    };
    template <class charT, class traits = file_traits<charT> >
    class basic_ifstream : public basic_istream<charT,traits> {
    public:
      void open(const char* s, open_mode mode = in);
      // remainder unchanged
    };
    template <class charT, class traits = file_traits<charT> >
    class basic_ofstream : public basic_ostream<charT,traits> {
    public:
      void open(const char* s, ios_base::open_mode mode = out | trunc);
      // remainder unchanged
    };
  }

7 The effects of these functions is to  call  the  corresponding  member
  function specified in Clause _lib.iostreams_.

  +-------                 BEGIN BOX 3                -------+
  ISSUE:  Were  these intended to be allowed in the template, or only in
  the specializations for char?
  +-------                  END BOX 3                 -------+

  D.3  char* streams                               [depr.str.strstreams]

1 The header <strstream> (and, as per  _depr.c.headers_,  <strstream.h>)
  defines three types that associate stream buffers with character array
  objects and assist reading and writing such objects.

  D.3.1  Class strstreambuf                          [depr.strstreambuf]
  namespace std {
    class strstreambuf : public streambuf<char> {
    public:
      explicit strstreambuf(streamsize alsize_arg = 0);
      strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*));
      strstreambuf(char* gnext_arg, streamsize n, char* pbeg_arg = 0);
      strstreambuf(const char* gnext_arg, streamsize n);
      strstreambuf(signed char* gnext_arg, streamsize n,
                   signed char* pbeg_arg = 0);
      strstreambuf(const signed char* gnext_arg, streamsize n);
      strstreambuf(unsigned char* gnext_arg, streamsize n,
                   unsigned char* pbeg_arg = 0);
      strstreambuf(const unsigned char* gnext_arg, streamsize n);
      virtual ~strstreambuf();
      void  freeze(bool = 1);
      char* str();
      int   pcount();
    protected:
      virtual int_type overflow (int_type c = ios_traits<char>::eof());
      virtual int_type pbackfail(int_type c = ios_traits<char>::eof());
      virtual int_type underflow();
      virtual pos_type seekoff(off_type off, ios_base::seekdir way,
                               ios_base::openmode which
                                = ios_base::in | ios_base::out);
      virtual pos_type seekpos(pos_type sp, ios_base::openmode which
                                = ios_base::in | ios_base::out);
      virtual streambuf<char>* setbuf(char* s, streamsize n);
    private:
  //  typedef T1 strstate;                exposition only
  //  static const strstate allocated;    exposition only
  //  static const strstate constant;     exposition only
  //  static const strstate dynamic;      exposition only
  //  static const strstate frozen;       exposition only
  //  strstate strmode;                   exposition only
  //  streamsize alsize;                  exposition only
  //  void* (*palloc)(size_t);            exposition only
  //  void (*pfree)(void*);               exposition only
    };
  }

  +-------                 BEGIN BOX 4                -------+
  The following members were removed, even though they appeared on p. 45
  of  94-0083/N0470  and p. 27-78 of the 20 Sep 94 Working Paper, and no
  Resolution specifically called for their removal:

        typedef charT char_type;
        typedef traits::int_type int_type;
        typedef traits::pos_type  pos_type;
        typedef traits::off_type  off_type;
        int_type  eof()     { return traits::eof(); }
        char_type newline() { return traits::newline(); }
  The following members were added, even though they did not  appear  in
  94-0083/N0470:
      strstreambuf(signed char* gnext_arg, streamsize n,
                   signed char* pbeg_arg = 0);
      strstreambuf(const signed char* gnext_arg, streamsize n);
      strstreambuf(unsigned char* gnext_arg, streamsize n,
                   unsigned char* pbeg_arg = 0);
      strstreambuf(const unsigned char* gnext_arg, streamsize n);
  +-------                  END BOX 4                 -------+

1 The class strstreambuf associates the input sequence, and possibly the
  output sequence, with an object of some character  array  type,  whose
  elements  store  arbitrary  values.   The  array  object  has  several
  attributes.

2 [Note: For the sake of exposition, these are represented  as  elements
  of  a  bitmask  type (indicated here as T1) called strstate.  The ele­
  ments are:

  --allocated, set when a dynamic array object has been  allocated,  and
    hence should be freed by the destructor for the strstreambuf object;

  --constant, set when the array object has const elements, so the  out­
    put sequence cannot be written;

  --dynamic,  set when the array object is allocated (or reallocated) as
    necessary to hold a character sequence that can change in length;

  --frozen, set when the program has requested that the array object not
    be altered, reallocated, or freed.   --end note]

3 [Note:  For  the  sake of exposition, the maintained data is presented
  here as:

  --strstate strmode, the attributes of the array object associated with
    the strstreambuf object;

  --int alsize, the suggested minimum size for a dynamic array object;

  --void*  (*palloc)(size_t), points to the function to call to allocate
    a dynamic array object;

  --void (*pfree)(void*), points to the  function  to  call  to  free  a
    dynamic array object.   --end note]

4 Each  object  of  class strstreambuf has a seekable area, delimited by
  the pointers seeklow and seekhigh.  If gnext is a  null  pointer,  the
  seekable  area  is  undefined.   Otherwise,  seeklow  equals  gbeg and
  seekhigh is either pend, if pend is not a null pointer, or gend.

  D.3.1.1  strstreambuf constructors            [depr.strstreambuf.cons]

  explicit strstreambuf(streamsize alsize_arg = 0);

  Effects:
    Constructs an object of class strstreambuf,  initializing  the  base
    class with streambuf().
    The postconditions of this function are indicated in Table 2:

                 Table 2--strstreambuf(streamsize) effects

                         +-------------------------+
                         |Element       Value      |
                         +-------------------------+
                         |strmode   dynamic        |
                         |alsize    alsize_arg     |
                         |palloc    a null pointer |
                         |pfree     a null pointer |
                         +-------------------------+

  strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*));

  Effects:
    Constructs  an  object  of class strstreambuf, initializing the base
    class with streambuf().
    The postconditions of this function are indicated in Table 3:

      Table 3--strstreambuf(void* (*)(size_t),void (*)(void*) effects

                      +-------------------------------+
                      |Element          Value         |
                      +-------------------------------+
                      |strmode   dynamic              |
                      |alsize    an unspecified value |
                      |palloc    palloc_arg           |
                      |pfree     pfree_arg            |
                      +-------------------------------+

  strstreambuf(char* gnext_arg, streamsize n, char *pbeg_arg = 0);
  strstreambuf(signed char* gnext_arg, streamsize n,
                                             signed char *pbeg_arg = 0);
  strstreambuf(unsigned char* gnext_arg, streamsize n,
                                             unsigned char *pbeg_arg = 0);

  Effects:
    Constructs an object of class strstreambuf,  initializing  the  base
    class with streambuf().
    The postconditions of this function are indicated in Table 4:

          Table 4--strstreambuf(charT*,streamsize,charT*) effects

                      +-------------------------------+
                      |Element          Value         |
                      +-------------------------------+
                      |strmode   0                    |
                      |alsize    an unspecified value |
                      |palloc    a null pointer       |
                      |pfree     a null pointer       |
                      +-------------------------------+

1 gnext_arg  shall  point  to the first element of an array object whose
  number of elements N is determined as follows:

  --If n > 0, N is n.

  --If n == 0, N is ::strlen(gnext_arg).

  --If n < 0, N is INT_MAX.1)

2 If pbeg_arg is a null pointer, the function executes:
    setg(gnext_arg, gnext_arg, gnext_arg + N);

3 Otherwise, the function executes:
    setg(gnext_arg, gnext_arg, pbeg_arg);
    setp(pbeg_arg,  pbeg_arg + N);

  strstreambuf(const char* gnext_arg, streamsize n);
  strstreambuf(const signed char* gnext_arg, streamsize n);
  strstreambuf(const unsigned char* gnext_arg, streamsize n);

  Effects:
    Behaves the same as  strstreambuf((char*)gnext_arg,n),  except  that
    the constructor also sets constant in strmode.
  _________________________
  1)  The  function  signature  strlen(const  char*)  is   declared   in
  <cstring>.   (_lib.c.strings_).   The  macro  INT_MAX  is  defined  in
  <climits> (_lib.support.limits_).

  virtual ~strstreambuf();

  Effects:
    Destroys  an  object  of class strstreambuf.  The function frees the
    dynamically allocated array object only if strmode & allocated !=  0
    and  strmode  & frozen == 0.  (Subclause _lib.strstreambuf.virtuals_
    describes how a dynamically allocated array object is freed.)

  D.3.1.2  Member functions                  [depr.strstreambuf.members]

  void freeze(bool freezefl = 1);

  Effects:
    If strmode & dynamic is non-zero, alters the freeze  status  of  the
    dynamic array object as follows:

  --If freezefl is false, the function sets frozen in strmode.

  --Otherwise, it clears frozen in strmode.

  char* str();

  Effects:
    Calls  freeze(),  then  returns  the beginning pointer for the input
    sequence, gbeg.
  Notes:
    The return value can be a null pointer.

  int pcount() const;

  Effects:
    If the next pointer for  the  output  sequence,  pnext,  is  a  null
    pointer,  returns  zero.   Otherwise,  returns the current effective
    length of the array object as the next pointer minus  the  beginning
    pointer for the output sequence, pnext - pbeg.

  D.3.1.3  strstreambuf overridden          [depr.strstreambuf.virtuals]
       virtual functions

  int_type overflow(int_type c = ios_traits<char>::eof());

  +-------                 BEGIN BOX 5                -------+
  This needs to be rewritten in terms of consuming characters to be con­
  sistent with the revised protocol for overflow.
  +-------                  END BOX 5                 -------+

  Effects:
    Appends  the  character  designated  by c to the output sequence, if
    possible, in one of two ways:

  --If c != eof() and if either the output sequence has a write position
    available  or  the  function  makes  a  write position available (as
    described below), assigns c to *pnext++.
    Returns (char)c.

  --If c == eof(), there is no character to append.
    Returns a value other than eof().

1 Returns eof() to indicate failure.
  Notes:
    The function can alter the number of write positions available as  a
    result of any call.
    To  make  a  write  position available, the function reallocates (or
    initially allocates) an array object with  a  sufficient  number  of
    elements  n to hold the current array object (if any), plus at least
    one additional write position.  How many additional write  positions
    are  made  available  is otherwise unspecified.2) If palloc is not a
    null pointer, the function calls (*palloc)(n) to  allocate  the  new
    dynamic  array  object.   Otherwise, it evaluates the expression new
    charT[n].  In either case, if the  allocation  fails,  the  function
    returns eof().  Otherwise, it sets allocated in strmode.

2 To free a previously existing dynamic array object whose first element
  address is p: If pfree is not  a  null  pointer,  the  function  calls
  (*pfree)(p).  Otherwise, it evaluates the expression delete[] p.

3 If  strmode  & dynamic == 0, or if strmode & frozen != 0, the function
  cannot extend the array (reallocate it with greater length) to make  a
  write position available.

  int_type pbackfail(int_type c = ios_traits<char>::eof());

  +-------                 BEGIN BOX 6                -------+
  This needs to be rewritten in terms of consuming characters to be con­
  sistent with the revised protocol for pbackfail.
  +-------                  END BOX 6                 -------+

4 Puts back the character designated by c to the input sequence, if pos­
  sible, in one of three ways:

  --If  c  != eof(), if the input sequence has a putback position avail­
    able, and if (char)c == (char)gnext[-1], assigns gnext - 1 to gnext.
    Returns (char)c.
  _________________________
  2) An implementation should consider alsize in making this decision.

  --If  c  != eof(), if the input sequence has a putback position avail­
    able, and if strmode & constant is zero, assigns c to *--gnext.
    Returns (char)c.

  --If c == eof() and if the  input  sequence  has  a  putback  position
    available, assigns gnext - 1 to gnext.
    Returns (char)c.

5 Returns eof() to indicate failure.
  Notes:
    If  the  function  can succeed in more than one of these ways, it is
    unspecified which way is chosen.  The function can alter the  number
    of putback positions available as a result of any call.

  +-------                 BEGIN BOX 7                -------+
  Cannot distinguish success and failure if c == EOF.
  +-------                  END BOX 7                 -------+

  int_type underflow();

  +-------                 BEGIN BOX 8                -------+
  This needs to be rewritten in terms of consuming characters to be con­
  sistent with the revised protocol for underflow.
  +-------                  END BOX 8                 -------+

  Effects:
    Reads a character from the input sequence, if possible, without mov­
    ing the stream position past it, as follows:

  --If  the  input  sequence  has a read position available the function
    signals success by returning (char*)gnext.

  --Otherwise, if the current write next pointer pnext  is  not  a  null
    pointer and is greater than the current read end pointer gend, makes
    a read position available by: assigning to gend a value greater than
    gnext and no greater than pnext.
    Returns (char)*gnext.

6 Returns eof() to indicate failure.
  Notes:
    The  function  can alter the number of read positions available as a
    result of any call.

  pos_type seekoff(off_type off, seekdir way, openmode which = in | out);

  +-------                 BEGIN BOX 9                -------+
  Check vs. _lib.stringbuf.virtuals_
  +-------                  END BOX 9                 -------+

  Effects:
    Alters the stream position within one of the  controlled  sequences,
    if possible, as indicated in Table 5:

                        Table 5--seekoff positioning

  +-----------------------------------------------------------------------+
  |     Conditions                            Result                      |
  +-----------------------------------------------------------------------+
  (which & ios::in) != 0 positions the input sequence                     |
  +-----------------------------------------------------------------------+
  (which & ios::out) != 0positions the output sequence                    |
  +-----------------------------------------------------------------------+
  |Otherwise,                                                              |
  (which & (ios::in |    positions both the input and the output sequences|
  ios::out)) == (ios::in                                                  |
  | ios::out))                                                            |
  |and way == either                                                       |
  ios::beg or ios::end                                                    |
  +-----------------------------------------------------------------------+
  |Otherwise,             the positioning operation fails.                 |
  +-----------------------------------------------------------------------+

  +-------                BEGIN BOX 10                -------+
  Comment: this condition is unclear.  If the 2nd condition is true,  is
  the  1st  condition  always true?  If so, the 2nd operation may occur,
  mayn't it?
  +-------                 END BOX 10                 -------+

7 For a sequence to be  positioned,  if  its  next  pointer  is  a  null
  pointer,  the  positioning  operation  fails.  Otherwise, the function
  determines newoff as indicated in Table 6:

                          Table 6--newoff values

        +---------------------------------------------------------+
        |      Condition                   newoff Value           |
        +---------------------------------------------------------+
        |way == ios::beg          0                               |
        +---------------------------------------------------------+
        |way == ios::cur          the next pointer minus the be­  |
        |                         ginning pointer (xnext - xbeg)  |
        +---------------------------------------------------------+
        |way == ios::end          seekhigh minus the beginning    |
        |                         pointer (seekhigh - xbeg)       |
        +---------------------------------------------------------+
        |If (newoff + off) <      the positioning operation fails |
        |(seeklow - xbeg),                                        |
        |or (seekhigh - xbeg) <                                   |
        |(newoff + off)                                           |
        +---------------------------------------------------------+

8 Otherwise, the function assigns xbeg  +  newoff  +  off  to  the  next
  pointer xnext.
  Returns:
    pos_type(newoff),  constructed  from the resultant offset newoff (of
    type off_type), that stores the resultant stream position, if possi­
    ble.   If  the  positioning  operation  fails, or if the constructed
    object cannot represent the resultant stream  position,  the  object
    stores an invalid stream position.

  +-------                BEGIN BOX 11                -------+
  Note:  Need posT object which stores an invalid stream position.  Com­
  ment: Not clear if the constructed object cannot represent the  resul­
  tant stream position
  +-------                 END BOX 11                 -------+

  pos_type seekpos(pos_type sp, ios_base::openmode which
                    = ios_base::in | ios_base::out);

  Effects:
    Alters  the  stream position within one of the controlled sequences,
    if possible, to correspond to the stream position stored in  sp  (as
    described below).

  --If (which & ios::in) != 0, positions the input sequence.

  --If (which & ios::out) != 0, positions the output sequence.

  --If  the  function positions neither sequence, the positioning opera­
    tion fails.

9 For a sequence to be  positioned,  if  its  next  pointer  is  a  null
  pointer,  the  positioning  operation  fails.  Otherwise, the function
  determines newoff from sp.offset():

  --If newoff is an invalid stream position, has a  negative  value,  or
    has a value greater than (seekhigh - seeklow), the positioning oper­
    ation fails

  --Otherwise, the function adds newoff to the  beginning  pointer  xbeg
    and stores the result in the next pointer xnext.
  Returns:
    pos_type(newoff),  constructed  from the resultant offset newoff (of
    type off_type), that stores the resultant stream position, if possi­
    ble.   If  the  positioning  operation  fails, or if the constructed
    object cannot represent the resultant stream  position,  the  object
    stores an invalid stream position.
      streambuf<char>* setbuf(char* s, streamsize n);
  Effects:
    Performs  an  operation  that  is  defined separately for each class
    derived from strstreambuf.
  Default behavior:
    the same as for streambuf::setbuf(char*, streamsize).

  D.3.2  Template class istrstream                     [depr.istrstream]
  namespace std {
    class istrstream : public istream<char> {
    public:
      explicit istrstream(const char* s);
      explicit istrstream(char* s);
      istrstream(const char* s, streamsize n);
      istrstream(char* s, streamsize n);
      virtual ~istrstream();
      strstreambuf* rdbuf() const;
      char *str();
    private:
  //  strstreambuf sb;    exposition only
    };
  }

1 The  class  istrstream  supports  the  reading  of  objects  of  class
  strstreambuf.   It supplies a strstreambuf object to control the asso­
  ciated array object.  For the sake of exposition, the maintained  data
  is presented here as:

  --sb, the strstreambuf object.

  D.3.2.1  istrstream constructors                [depr.istrstream.cons]

  explicit istrstream(const char* s);
  explicit istrstream(char* s);

  Effects:
    Constructs  an  object  of  class  istrstream, initializing the base
    class with istream(&sb) and initializing sb with strstreambuf(s,0)).
    s shall designate the first element of an NTBS.

  istrstream(const char* s, streamsize n);

  Effects:
    Constructs  an  object  of  class  istrstream, initializing the base
    class with istream(&sb) and initializing sb with strstreambuf(s,n)).
    s  shall  designate  the first element of an array whose length is n
    elements, and n shall be greater than zero.

  D.3.2.2  Member functions                    [depr.istrstream.members]

  strstreambuf* rdbuf() const;

  Returns:
    (strstreambuf*)&sb.

  char* str();

  Returns:
    rdbuf()->str().

  D.3.3  Template class ostrstream                     [depr.ostrstream]
  namespace std {
    class ostrstream : public ostream<char> {
    public:
      ostrstream();
      ostrstream(char* s, int n, ios_base::openmode mode = ios_base::out);
      virtual ~ostrstream();
      strstreambuf* rdbuf() const;
      void freeze(int freezefl = 1);
      char* str();
      int pcount() const;
    private:
  //  strstreambuf sb;    exposition only
    };
  }

1 The  class  ostrstream  supports  the  writing  of  objects  of  class
  strstreambuf.   It supplies a strstreambuf object to control the asso­
  ciated array object.  For the sake of exposition, the maintained  data
  is presented here as:

  --sb, the strstreambuf object.

  D.3.3.1  ostrstream constructors                [depr.ostrstream.cons]

      ostrstream();

  Effects:
    Constructs  an  object  of  class  ostrstream, initializing the base
    class with ostream(&sb) and initializing sb with strstreambuf()).

  ostrstream(char* s, int n, ios_base::openmode mode = ios_base::out);

  Effects:
    Constructs an object of  class  ostrstream,  initializing  the  base
    class  with  ostream(&sb),  and initializing sb with one of two con­
    structors:

  --If mode & app == 0, then s shall designate the first element  of  an
    array of n elements.
    The constructor is strstreambuf(s, n, s).

  --If  mode  & app != 0, then s shall designate the first element of an
    array of n elements that contains an NTBS  whose  first  element  is
    designated by s.
    The constructor is strstreambuf(s, n, s + ::strlen(s)).3)

  D.3.3.2  Member functions                    [depr.ostrstream.members]

  strstreambuf* rdbuf() const;

  Returns:
    (strstreambuf*)&sb.

  void freeze(int freezefl = 1);

  Effects:
    Calls rdbuf()->freeze(freezefl).

  char* str();

  Returns:
    rdbuf()->str().

  int pcount() const;

  _________________________
  3) The function signature strlen(const char*) is declared in <cstring>
  (_lib.c.strings_).

  Returns:
    rdbuf()->pcount().