______________________________________________________________________

  21   Strings library                           [lib.strings]

  ______________________________________________________________________

1 This clause describes components for manipulating sequences of  "char­
  acters,"  where  characters may be of type char, wchar_t, or of a type
  defined in a C++ program.

2 The following subclauses describe string classes, and  null-terminated
  sequence utilities, as summarized in Table 1:

                     Table 1--Strings library summary

     +---------------------------------------------------------------+
     |                    Subclause                        Header(s) |
     +---------------------------------------------------------------+
     |_lib.string.classes_ String classes                  <string>  |
     +---------------------------------------------------------------+
     |                                                     <cctype>  |
     |                                                     <cwctype> |
     |_lib.c.strings_ Null-terminated sequence utilities   <cstring> |
     |                                                     <cwchar>  |
     |                                                     <cstdlib> |
     +---------------------------------------------------------------+

  21.1  String classes                              [lib.string.classes]

  Header <string> synopsis

  #include <memory>       // for allocator

  namespace std {
  // subclause _lib.template.string_, basic_string:
    template<class charT> struct string_char_traits;
    template<class charT, class traits = string_char_traits<charT>,
             class Allocator = allocator> class basic_string;

    template<class charT, class traits, class Allocator>
      basic_string<charT,traits,Allocator>
        operator+(const basic_string<charT,traits,Allocator>& lhs,
                  const basic_string<charT,traits,Allocator>& rhs);
    template<class charT, class traits, class Allocator>
      basic_string<charT,traits,Allocator>
        operator+(const charT* lhs,
                  const basic_string<charT,traits,Allocator>& rhs);
    template<class charT, class traits, class Allocator>
      basic_string<charT,traits,Allocator>
        operator+(charT lhs, const basic_string<charT,traits,Allocator>& rhs);
    template<class charT, class traits, class Allocator>
      basic_string<charT,traits,Allocator>
        operator+(const basic_string<charT,traits,Allocator>& lhs,
                  const_pointer rhs);
    template<class charT, class traits, class Allocator>
      basic_string<charT,traits,Allocator>
        operator+(const basic_string<charT,traits,Allocator>& lhs, charT rhs);
    template<class charT, class traits, class Allocator>
      bool operator==(const basic_string<charT,traits,Allocator>& lhs,
                      const basic_string<charT,traits,Allocator>& rhs);
    template<class charT, class traits, class Allocator>
      bool operator==(const charT* lhs,
                      const basic_string<charT,traits,Allocator>& rhs);
    template<class charT, class traits, class Allocator>
      bool operator==(const basic_string<charT,traits,Allocator>& lhs,
                      const charT* rhs);
    template<class charT, class traits, class Allocator>
      bool operator!=(const basic_string<charT,traits,Allocator>& lhs,
                      const basic_string<charT,traits,Allocator>& rhs);
    template<class charT, class traits, class Allocator>
      bool operator!=(const charT* lhs,
                      const basic_string<charT,traits,Allocator>& rhs);
    template<class charT, class traits, class Allocator>
      bool operator!=(const basic_string<charT,traits,Allocator>& lhs,
                      const charT* rhs);
    template<class charT, class traits, class Allocator>
      bool operator< (const basic_string<charT,traits,Allocator>& lhs,
                      const basic_string<charT,traits,Allocator>& rhs);
    template<class charT, class traits, class Allocator>
      bool operator< (const basic_string<charT,traits,Allocator>& lhs,
                      const charT* rhs);
    template<class charT, class traits, class Allocator>
      bool operator< (const charT* lhs,
                      const basic_string<charT,traits,Allocator>& rhs);
    template<class charT, class traits, class Allocator>
      bool operator> (const basic_string<charT,traits,Allocator>& lhs,
                      const basic_string<charT,traits,Allocator>& rhs);
    template<class charT, class traits, class Allocator>
      bool operator> (const basic_string<charT,traits,Allocator>& lhs,
                      const charT* rhs);
    template<class charT, class traits, class Allocator>
      bool operator> (const charT* lhs,
                      const basic_string<charT,traits,Allocator>& rhs);

    template<class charT, class traits, class Allocator>
      bool operator<=(const basic_string<charT,traits,Allocator>& lhs,
                      const basic_string<charT,traits,Allocator>& rhs);
    template<class charT, class traits, class Allocator>
      bool operator<=(const basic_string<charT,traits,Allocator>& lhs,
                      const charT* rhs);
    template<class charT, class traits, class Allocator>
      bool operator<=(const charT* lhs,
                      const basic_string<charT,traits,Allocator>& rhs);
    template<class charT, class traits, class Allocator>
      bool operator>=(const basic_string<charT,traits,Allocator>& lhs,
                      const basic_string<charT,traits,Allocator>& rhs);
    template<class charT, class traits, class Allocator>
      bool operator>=(const basic_string<charT,traits,Allocator>& lhs,
                      const charT* rhs);
    template<class charT, class traits, class Allocator>
      bool operator>=(const charT* lhs,
                      const basic_string<charT,traits,Allocator>& rhs);
  // subclause _lib.string.special_:
    template<class charT, class traits, class Allocator>
       void swap(basic_string<charT,traits,Allocator>& lhs,
                 basic_string<charT,traits,Allocator>& rhs);
    template<class charT, class IS_traits,
             class STR_traits, class STR_Alloc>
     basic_istream<charT,IS_traits>&
      operator>>(basic_istream<charT,IS_traits>& is,
                         basic_string<charT,STR_traits,STR_Alloc>& str);
   template<class charT, class OS_traits,
                  class STR_traits, class STR_Alloc>
     basic_ostream<charT, OS_traits>&
       operator<<(basic_ostream<charT, OS_traits>& os,
                          const basic_string<charT,STR_traits,STR_Alloc>& str);
    template<class charT, class IS_traits, class STR_traits, class STR_Alloc>
      basic_istream<charT,IS_traits>&
        getline(basic_istream<charT,IS_traits>& is,
                basic_string<charT,STR_traits,STR_Alloc>& str,
                charT delim = IS_traits::newline() );
  // subclause _lib.string_, string:
    struct string_char_traits<char>;
    typedef basic_string<char> string;
  // subclause _lib.wstring_, wstring:
    struct string_char_traits<wchar_t>;
    typedef basic_string<wchar_t> wstring;
  }

1 In  this  subclause,  we  call  the  basic character types "char-like"
  types, and also  call  the  objects  of  char-like  types  "char-like"
  objects or simply "character"s.

2 The  header  <string>  defines  a  basic string class template and its
  traits that can handle all "char-like" template arguments with several
  function  signatures  for  manipulating  varying-length  sequences  of
  "char-like" objects.

3 The header <string> also defines two specific template classes  string
  and wstring and their special traits.

  21.1.1  Template class basic_string              [lib.template.string]

  21.1.1.1  Template class                      [lib.string.char.traits]
       string_char_traits
  namespace std {
    template<class charT> struct string_char_traits {
      typedef charT char_type; // for users to acquire the basic character type
      static void assign(char_type& c1, const char_type& c2);
      static bool eq(const char_type& c1, const char_type& c2);
      static bool ne(const char_type& c1, const char_type& c2);
      static bool lt(const char_type& c1, const char_type& c2);
      static char_type eos(); // the null character
      // speed-up functions
      static int compare(const char_type* s1, const char_type* s2, size_t n);
      static const char_type* find(const char_type* s, int n, const char_type& a);
      static size_t length(const char_type* s);
      static char_type* copy(char_type* s1, const char_type* s2, size_t n);
      static char_type* move(char_type* s1, const char_type* s2, size_t n);
      static char_type* assign(char_type* s, size_t n, const char_type& a);
    };
  }

  21.1.1.2  string_char_traits          [lib.string.char.traits.members]
       members

  static void assign(char_type& c1, const char_type& c2)

  Effects:
    Assigns c2 to c1.

  static bool eq(const char_type& c1, const char_type& c2)

  Returns
    c1 == c2

  static bool ne(const char_type& c1, const char_type& c2)

  Returns:
    !(c1 == c2)

  static bool lt(const char_type& c1, const char_type& c2)

  Returns:
    c1 < c2

  static char_type eos();

  Returns
    The null character for char_type

  static int compare(const char_type* s1, const char_type* s2, size_t n);

  Returns:
    0 iff for each n in the range [0, n) the expression eq(s1[i], s2[i])
    is true. Otherwise, returns a negative integer iff for some j in the
    range  [0,n)  the expression lt(s1[j], s2[j]) is true and for each i
    in the range [0, n) the expression eq(s1[i], s2[i]) is true.  Other­
    wise, returns a positive integer.

  static const char_type* find(const char_type* s, int n, const char_type& a);

  Effects:
    determines  the lowest pointer p , if possible, such that all of the
    following conditions hold true:

  --*p == a

  --sfP <= p <= sfP + nfP
  Returns:
    p if the function can determine such a value for p

  static size_t length(const char_type* s);

  Returns:
    the lowest non-negative value of i such that the expression eq(s[i],
    eos())  returns  true and for each j in the range [0, i) the expres­
    sion ne(s[j], eos()) returns true.

  static char_type* copy(char_type* s1, const char_type* s2, size_t n);

  Requires:
    s2 shall not be in the range [s1, s1+n)
  Effects:
    Copies elements.  For  each  i  in  the  range  [0,  i)  ,  performs
    assign(s1[i], s2[i]).

  static char_type* move(char_type* s1, const char_type* s2, size_t n);

  Effects:
    copies  elements.  For  each integer i in the range [0, n), performs
    assign(s1[i], s2[i]).  Even when s2 is in the range [s1, s1+n),  the
    implementation shall copy the characters correctly.
  Returns:
    s1.

  static char_type* assign(char_type* s, size_t n, const char_type& a);

  Effects:
    For each integer i in the range [0, n), performs assign(s1[i], a).
  Returns:
    s

  21.1.1.3  Template class basic_string               [lib.basic.string]
  namespace std {
    template<class charT, class traits = string_char_traits<charT>,
             class Allocator = allocator>
    class basic_string {
    public:
    // types:
      typedef          traits            traits_type;
      typedef typename traits::char_type value_type;
      typedef          Allocator         allocator_type;
      typedef typename Allocator::size_type       size_type;
      typedef typename Allocator::difference_type difference_type;
      typedef typename Allocator::types<charT>::reference       reference;
      typedef typename Allocator::types<charT>::const_reference const_reference;
      typedef typename Allocator::types<charT>::pointer         pointer;
      typedef typename Allocator::types<charT>::const_pointer   const_pointer;
      typedef implementation_defined                      iterator;
      typedef implementation_defined                      const_iterator;
      typedef reverse_iterator<iterator, value_type,
                      reference, difference_type>               reverse_iterator;
      typedef reverse_iterator<const_iterator, value_type,
                      const_reference, difference_type>         const_reverse_iterator;
      static const size_type npos = -1;
    // _lib.string.cons_ construct/copy/destroy:
      explicit basic_string(const Allocator& = Allocator());
      basic_string(const basic_string& str, size_type pos = 0,
                   size_type n = npos, const Allocator& = Allocator());
      basic_string(const charT* s, size_type n, const Allocator& = Allocator());
      basic_string(const charT* s, const Allocator& = Allocator());
      basic_string(size_type n, charT c, const Allocator& = Allocator());
      template<class InputIterator>
        basic_string(InputIterator begin, InputIterator end,
                     const Allocator& = Allocator());
     ~basic_string();
      basic_string& operator=(const basic_string& str);
      basic_string& operator=(const charT* s);
      basic_string& operator=(charT c);

    // _lib.string.iterators_ iterators:
      iterator       begin();
      const_iterator begin() const;
      iterator       end();
      const_iterator end() const;

      reverse_iterator       rbegin();
      const_reverse_iterator rbegin() const;
      reverse_iterator       rend();
      const_reverse_iterator rend() const;
    // _lib.string.capacity_ capacity:
      size_type size() const;
      size_type length() const;
      size_type max_size() const;
      void resize(size_type n, charT c);
      void resize(size_type n);
      size_type capacity() const;
      void reserve(size_type res_arg);
      bool empty() const;
    // _lib.string.access_ element access:
      charT     operator[](size_type pos) const;
      reference operator[](size_type pos);
      const_reference at(size_type n) const;
      reference       at(size_type n);
    // _lib.string.modifiers_ modifiers:
      basic_string& operator+=(const basic_string& rhs);
      basic_string& operator+=(const charT* s);
      basic_string& operator+=(charT c);
      basic_string& append(const basic_string& str);
      basic_string& append(const basic_string& str, size_type pos,
                           size_type n);
      basic_string& append(const charT* s, size_type n);
      basic_string& append(const charT* s);
      basic_string& append(size_type n, charT c);
      template<class InputIterator>
        basic_string& append(InputIterator first, InputIterator last);
      basic_string& assign(const basic_string&);
      basic_string& assign(const basic_string& str, size_type pos,
                           size_type n);
      basic_string& assign(const charT* s, size_type n);
      basic_string& assign(const charT* s);
      basic_string& assign(size_type n, charT c);
      template<class InputIterator>
        basic_string& assign(InputIterator first, InputIterator last);

      basic_string& insert(size_type pos1, const basic_string& str);
      basic_string& insert(size_type pos1, const basic_string& str,
                           size_type pos2, size_type n);
      basic_string& insert(size_type pos, const charT* s, size_type n);
      basic_string& insert(size_type pos, const charT* s);
      basic_string& insert(size_type pos, size_type n, charT c);
      iterator insert(iterator p, charT c = charT());
      void     insert(iterator p, size_type n, charT c);
      template<class InputIterator>
        void insert(iterator p, InputIterator first, InputIterator last);
      basic_string& erase(size_type pos = 0, size_type n = npos);
      iterator erase(iterator position);
      iterator erase(iterator first, iterator last);
      basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
      basic_string& replace(size_type pos1, size_type n1, const basic_string& str,
                            size_type pos2, size_type n2);
      basic_string& replace(size_type pos, size_type n1, const charT* s,
                            size_type n2);
      basic_string& replace(size_type pos, size_type n1, const charT* s);
      basic_string& replace(size_type pos, size_type n1, size_type n2, charT c);
      basic_string& replace(iterator i1, iterator i2, const basic_string& str);
      basic_string& replace(iterator i1, iterator i2, const charT* s, size_type n);
      basic_string& replace(iterator i1, iterator i2, const charT* s);
      basic_string& replace(iterator i1, iterator i2,
                            size_type n, charT c);
      template<class InputIterator>
        basic_string& replace(iterator i1, iterator i2,
                              InputIterator j1, InputIterator j2);
      size_type copy(charT* s, size_type n, size_type pos = 0) const;
      void swap(basic_string<charT,traits,Allocator>&);
    // _lib.string.ops_ string operations:
      const charT* c_str() const;  // explicit
      const charT* data() const;
      const allocator_type& get_allocator() const;
      size_type find (const basic_string& str, size_type pos = 0) const;
      size_type find (const charT* s, size_type pos, size_type n) const;
      size_type find (const charT* s, size_type pos = 0) const;
      size_type find (charT c, size_type pos = 0) const;
      size_type rfind(const basic_string& str, size_type pos = npos) const;
      size_type rfind(const charT* s, size_type pos, size_type n) const;
      size_type rfind(const charT* s, size_type pos = npos) const;
      size_type rfind(charT c, size_type pos = npos) const;
      size_type find_first_of(const basic_string& str, size_type pos = 0) const;
      size_type find_first_of(const charT* s, size_type pos, size_type n) const;
      size_type find_first_of(const charT* s, size_type pos = 0) const;
      size_type find_first_of(charT c, size_type pos = 0) const;
      size_type find_last_of (const basic_string& str,
                              size_type pos = npos) const;
      size_type find_last_of (const charT* s, size_type pos, size_type n) const;
      size_type find_last_of (const charT* s, size_type pos = npos) const;
      size_type find_last_of (charT c, size_type pos = npos) const;

      size_type find_first_not_of(const basic_string& str,
                                  size_type pos = 0) const;
      size_type find_first_not_of(const charT* s, size_type pos,
                                  size_type n) const;
      size_type find_first_not_of(const charT* s, size_type pos = 0) const;
      size_type find_first_not_of(charT c, size_type pos = 0) const;
      size_type find_last_not_of (const basic_string& str,
                                  size_type pos = npos) const;
      size_type find_last_not_of (const charT* s, size_type pos,
                                  size_type n) const;
      size_type find_last_not_of (const charT* s, size_type pos = npos) const;
      size_type find_last_not_of (charT c, size_type pos = npos) const;
      basic_string substr(size_type pos = 0, size_type n = npos) const;
      int compare(const basic_string& str) const;
      int compare(size_type pos1, size_type n1,
                  const basic_string& str) const;
      int compare(size_type pos1, size_type n1,
                  const basic_string& str,
                  size_type pos2, size_type n2) const;
      int compare(const charT* s) const;
      int compare(size_type pos1, size_type n1,
                  const charT* s, size_type n2 = npos const;
    };
  }

1 For  a char-like type charT, the template class basic_string describes
  objects that can store a sequence consisting of a  varying  number  of
  arbitrary  char-like objects.  The first element of the sequence is at
  position zero.  Such a sequence is also called a "string" if the given
  char-like  type  is  clear  from  context. In the rest of this clause,
  charT denotes a such given char-like type.  Storage for the string  is
  allocated  and  freed  as  necessary  by the member functions of class
  basic_string.

2 The template class basic_string conforms  to  the  requirements  of  a
  Sequence,  as  specified  in  (_lib.sequence.reqmts_).   Additionally,
  because the iterators supported  by  basic_string  are  random  access
  iterators  (_lib.random.access.iterators_),  basic_string  conforms to
  the the requirements  of  a  Reversible  Container,  as  specified  in
  (_lib.container.requirements_).

3 In all cases, size() <= capacity().

4 The functions described in this clause can report two kinds of errors,
  each associated with a distinct exception:

  --a length error is associated with exceptions  of  type  length_error
    (_lib.length.error_);

  --an   out-of-range  error  is  associated  with  exceptions  of  type
    out_of_range (_lib.out.of.range_).

  21.1.1.4  basic_string constructors                  [lib.string.cons]

1 In all basic_string constructors, a copy of the Allocator argument  is
  used  for any memory allocation performed by the constructor or member
  functions during the lifetime of the object.

  explicit basic_string(const Allocator& = Allocator());

  Effects:
    Constructs an object of class basic_string.  The  postconditions  of
    this function are indicated in Table 2:

                      Table 2--basic_string() effects

  +----------------------------------------------------------------------------+
  | Element                                 Value                              |
  +----------------------------------------------------------------------------+
  |data()       a non-null pointer that is copyable and can have 0 added to it |
  |size()       0                                                              |
  |capacity()   an unspecified value                                           |
  +----------------------------------------------------------------------------+

  basic_string(const basic_string<charT,traits,Allocator>& str,
               size_type pos = 0, size_type n = npos);

  Requires:
    pos <= size()
  Throws:
    out_of_range if pos > str.size().
  Effects:
    Constructs an object of class basic_string and determines the effec­
    tive length rlen of the initial string value as the smaller of n and
    str.size() - pos, as indicated in Table 3:

      Table 3--basic_string(basic_string,size_type,size_type) effects

          +------------------------------------------------------+
          |    Element                      Value                |
          +------------------------------------------------------+
          |data()            points  at  the first element of an |
          |                  allocated copy of rlen elements  of |
          |                  the string controlled by str begin­ |
          |                  ning at position pos                |
          |size()            rlen                                |
          |capacity()        a value at least as large as size() |
          |get_allocator()   str.get_allocator()                 |
          +------------------------------------------------------+

  basic_string(const charT* s, size_type n,
               const Allocator& = Allocator());

  Requires:
    s shall not be a null pointer and n < npos.
  Throws:
    out_of_range if n == npos.
  Effects:
    Constructs an object of class basic_string and determines  its  ini­
    tial  string  value  from the array of charT of length n whose first
    element is designated by s, as indicated in Table 4:

           Table 4--basic_string(const charT*,size_type) effects

             +-------------------------------------------------+
             | Element                    Value                |
             +-------------------------------------------------+
             |data()       points at the first element  of  an |
             |             allocated  copy  of the array whose |
             |             first element is pointed at by s    |
             |size()       n                                   |
             |capacity()   a value at least as large as size() |
             +-------------------------------------------------+

  basic_string(const charT* s, const Allocator& = Allocator());

  Requires:
    s shall not be a null pointer.
  Effects:
    Constructs an object of class basic_string and determines  its  ini­
    tial   string   value   from   the   array   of   charT   of  length
    traits::length(s) whose first element is designated by  s, as  indi­
    cated in Table 5:

                Table 5--basic_string(const charT*) effects

             +-------------------------------------------------+
             | Element                    Value                |
             +-------------------------------------------------+
             |data()       points  at  the first element of an |
             |             allocated copy of the  array  whose |
             |             first element is pointed at by s    |
             |size()       traits::length(s)                   |
             |capacity()   a value at least as large as size() |
             +-------------------------------------------------+
  Notes:
    Uses traits::length().

  basic_string(size_type n, charT c, const Allocator& = Allocator());

  Requires:
    n < npos
  Throws:
    length_error if n == npos.
  Effects:
    Constructs  an  object of class basic_string and determines its ini­
    tial string value by repeating the char-like object c for all n ele­
    ments, as indicated in Table 6:

               Table 6--basic_string(size_type,charT) effects

             +-------------------------------------------------+
             | Element                    Value                |
             +-------------------------------------------------+
             |data()       points  at  the first element of an |
             |             allocated array of n elements, each |
             |             storing the initial value c         |
             |size()       n                                   |
             |capacity()   a value at least as large as size() |
             +-------------------------------------------------+

  template<class InputIterator>
    basic_string(InputIterator begin, InputIterator end,
                 const Allocator& = Allocator());

  Effects:
    Constructs  a  string  from the values in the range [begin, end), as
    indicated in Table 7:

                  Table 7--basic_string(begin,end) effects

             +-------------------------------------------------+
             | Element                    Value                |
             +-------------------------------------------------+
             |data()       points at the first element  of  an |
             |             allocated  copy  of the elements in |
             |             the range [first,last)              |
             |size()       distance between first and last     |
             |capacity()   a value at least as large as size() |
             +-------------------------------------------------+
  Notes:
    see clause _lib.sequence.reqmts_.

  basic_string<charT,traits,Allocator>&
    operator=(const basic_string<charT,traits,Allocator>& str);

  Effects:
    If *this and str are not the same object, modifies *this such that:

                      Table 7--operator=(str) effects

             +-------------------------------------------------+
             | Element                    Value                |
             +-------------------------------------------------+
             |data()       points at the first element  of  an |
             |             allocated  copy  of  the  the array |
             |             whose first element is  pointed  at |
             |             by str.size()                       |
             |size()       str.size()                          |
             |capacity()   a value at least as large as size() |
             +-------------------------------------------------+
    If *this and str are the same object, the member has no effect.
  Returns:
    *this

  basic_string<charT,traits,Allocator>&
    operator=(const charT* s);

  Returns:
    *this = basic_string<charT,traits,Allocator>(s).
  Notes:
    Uses traits::length().

  basic_string<charT,traits,Allocator>& operator=(charT c);

  Returns:
    *this = basic_string<charT,traits,Allocator>(1,c).

  21.1.1.5  basic_string iterator support         [lib.string.iterators]

  iterator       begin();
  const_iterator begin() const;

  Returns:
    an iterator referring to the first character in the string.

  iterator       end();
  const_iterator end() const;

  Returns:
    an iterator which is the past-the-end value.

  reverse_iterator       rbegin();
  const_reverse_iterator rbegin() const;

  Returns:
    an     iterator     which     is    semantically    equivalent    to
    reverse_iterator(end()).

  reverse_iterator       rend();
  const_reverse_iterator rend() const;

  Returns:
    an    iterator    which    is     semantically     equivalent     to
    reverse_iterator(begin()).

  21.1.1.6  basic_string capacity                  [lib.string.capacity]

  size_type size() const;

  Returns:
    a  count of the number of char-like objects currently in the string.

  size_type length() const;

  Returns:
    size().

  size_type max_size() const;

  Returns:
    The maximum size of the string.

  void resize(size_type n, charT c);

  Requires:
    n <= max_size()
  Throws:
    length_error if n > max_size().
  Effects:
    Alters the length of the string designated by *this as follows:

  --If n <= size(), the function replaces the string designated by *this
    with  a  string of length n whose elements are a copy of the initial
    elements of the original string designated by *this.

  --If n > size(), the function replaces the string designated by  *this
    with  a string of length n whose first size() elements are a copy of
    the original string designated by *this, and  whose  remaining  ele­
    ments are all initialized to c.

  void resize(size_type n);

  Effects:
    resize(n,charT()).

  size_type capacity() const;

  Returns:
    the size of the allocated storage in the string.

  void reserve(size_type res_arg);

1 The   member   function  reserve()  is  a  directive  that  informs  a
  basic_string of a planned change in size, so that it  can  manage  the
  storage allocation accordingly.
  Effects:
    After  reserve(),  capacity() is greater or equal to the argument of
    reserve if reallocation happens; and equal to the previous value  of
    capacity() otherwise.
    Reallocation happens at this point if and only if the current capac­
    ity is less than the argument of reserve().
    Reallocation invalidates all the references, pointers, and iterators
    referring to the elements in the sequence.  It is guaranteed that no
    reallocation takes place during the  insertions  that  happen  after
    reserve()  takes  place  until  the time when the size of the string
    reaches the size specified by reserve().

  bool empty() const;

  Returns:
    size() == 0.

  21.1.1.7  basic_string element access              [lib.string.access]

  charT     operator[](size_type pos) const;
  reference operator[](size_type pos);

  Effects:
    The reference returned by the non-const version is invalid after any
    subsequent call to c_str(), data(), or any non-const member function
    for the object.

  Returns:
    If pos < size(), returns data()[pos].  Otherwise, if pos ==  size(),
    the const version returns traits::eos().  Otherwise, the behavior is
    undefined.

  const_reference at(size_type pos) const;
  reference       at(size_type pos);

  Requires:
    pos < size()
  Throws:
    out_of_range if pos >= size().
  Returns:
    operator[](pos).

  21.1.1.8  basic_string modifiers                [lib.string.modifiers]

  21.1.1.8.1  basic_string::operator+=                [lib.string::op+=]

  basic_string<charT,traits,Allocator>&
    operator+=(const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    append(rhs).

  basic_string<charT,traits,Allocator>& operator+=(const charT* s);

  Returns:
    *this += basic_string<charT,traits,Allocator>(s).
  Notes:
    Uses traits::length().

  basic_string<charT,traits,Allocator>& operator+=(charT c);

  Returns:
    *this += basic_string<charT,traits,Allocator>(1,c).

  21.1.1.8.2  basic_string::append                  [lib.string::append]

  basic_string<charT,traits,Allocator>&
    append(const basic_string<charT,traits>& str);

  Returns:
    append(str, 0, npos).

  basic_string<charT,traits,Allocator>&
    append(const basic_string<charT,traits>& str, size_type pos, size_type n);

  Requires:
    pos <= str.size()
  Throws:
    out_of_range if pos > str.size().
  Effects:
    Determines the effective length rlen of the string to append as  the
    smaller  of  n  and  str.size()  -  pos.   The  function then throws
    length_error if size() >= npos - rlen.
    Otherwise, the function replaces the string controlled by *this with
    a  string  of length size() + rlen whose first size() elements are a
    copy of the original string controlled by *this and whose  remaining
    elements are a copy of the initial elements of the string controlled
    by str beginning at position pos.
  Returns:
    *this.

  basic_string<charT,traits,Allocator>&
    append(const charT* s, size_type n);

  Returns:
    append(basic_string<charT,traits,Allocator>(s,n)).

  basic_string<charT,traits,Allocator>& append(const charT* s);

  Returns:
    append(basic_string<charT,traits,Allocator>(s)).
  Notes:
    Uses traits::length().

  basic_string<charT,traits,Allocator>&
    append(size_type n, charT c);

  Returns:
    append(basic_string<charT,traits,Allocator>(n,c)).

  template<class InputIterator>
    basic_string& append(InputIterator first, InputIterator last);

  Returns:
    append(basic_string<charT,traits,Allocator>(first,last)).

  21.1.1.8.3  basic_string::assign                  [lib.string::assign]

  basic_string<charT,traits,Allocator>&
    assign(const basic_string<charT,traits>& str);

    Returns assign(str, 0, npos) .

  basic_string<charT,traits,Allocator>&
    assign(const basic_string<charT,traits>& str, size_type pos,
           size_type n);

  Requires:
    pos <= str.size()
  Throws:
    out_of_range if pos > str.size().
  Effects:
    Determines the effective length rlen of the string to assign as  the
    smaller of n and str.size() - pos.
    The  function  then  replaces  the string controlled by *this with a
    string of length rlen whose elements are a copy of the  string  con­
    trolled by str beginning at position pos.
  Returns:
    *this.

  basic_string<charT,traits,Allocator>&
    assign(const charT* s, size_type n);

  Returns:
    assign(basic_string<charT,traits,Allocator>(s,n)).

  basic_string<charT,traits,Allocator>& assign(const charT* s);

  Returns:
    assign(basic_string(s)).
  Notes:
    Uses traits::length().

  basic_string<charT,traits,Allocator>&
    assign(size_type n, charT c);

  Returns:
    assign(basic_string<charT,traits,Allocator>(n,c)).

  template<class InputIterator>
    basic_string& assign(InputIterator first, InputIterator last);

  Returns:
    assign(basic_string<charT,traits,Allocator>(first,last)).

  21.1.1.8.4  basic_string::insert                  [lib.string::insert]

  basic_string<charT,traits,Allocator>&
    insert(size_type pos1,
           const basic_string<charT,traits,Allocator>& str);

  Returns:
    insert(pos1,str).

  basic_string<charT,traits,Allocator>&
    insert(size_type pos1,
           const basic_string<charT,traits,Allocator>& str,
           size_type pos2 = 0, size_type n = npos);

  Requires
    pos1 <= size() and pos2 <= str.size()
  Throws:
    out_of_range if pos1 > size() or pos2 > str.size().
  Effects:
    Determines  the effective length rlen of the string to insert as the
    smaller of n and str.size() - pos2.   Then  throws  length_error  if
    size() >= npos - rlen.
    Otherwise, the function replaces the string controlled by *this with
    a string of length size() + rlen whose first  pos1  elements  are  a
    copy  of  the  initial elements of the original string controlled by
    *this, whose next rlen elements are a copy of the  elements  of  the
    string  controlled  by  str  beginning  at  position pos2, and whose
    remaining elements are a copy of the remaining elements of the orig­
    inal string controlled by *this.
  Returns:
    *this.

  basic_string<charT,traits,Allocator>&
    insert(size_type pos, const charT* s, size_type n);

  Returns:
    insert(pos,basic_string<charT,traits,Allocator>(s,n)).

  basic_string<charT,traits,Allocator>&
    insert(size_type pos, const charT* s);

  Returns:
    insert(pos,basic_string<charT,traits,Allocator>(s)).
  Notes:
    Uses traits::length().

  basic_string<charT,traits,Allocator>&
    insert(size_type pos, size_type n, charT c);

  Returns:
    insert(pos,basic_string<charT,traits,Allocator>(n,c)).

  iterator insert(iterator p, charT c);

  Requires:
    p is a valid iterator on *this.
  Effects:
    inserts a copy of c before the character referred to by p.
  Returns:
    an iterator which refers to the copy of the inserted character.

  void insert(iterator p, size_type n, charT c);

  Requires:
    p is a valid iterator on *this.
  Effects:
    inserts n copies of c before the character referrred to by p.

  template<class InputIterator>
    void insert(iterator p, InputIterator first, InputIterator last);

  Requires:
    p is a valid iterator on *this.  [first,last) is a valid range.
  Effects:
    inserts  copies  of  the characters in the range [first,last) before
    the character referrred to by p.

  21.1.1.8.5  basic_string::erase                    [lib.string::erase]

  basic_string<charT,traits,Allocator>&
    erase(size_type pos = 0, size_type n = npos);

  Requires:
    pos  <= size()
  Throws:
    out_of_range if pos  > size().
  Effects:
    Determines the effective length xlen of the string to be removed  as
    the smaller of n and size() - pos.
    The  function  then  replaces  the string controlled by *this with a
    string of length size() - xlen whose first pos elements are  a  copy
    of  the initial elements of the original string controlled by *this,
    and whose remaining elements are a copy of the elements of the orig­
    inal string controlled by *this beginning at position pos + xlen.
  Returns:
    *this.

  iterator erase(iterator p);

  Requires:
    p is a valid iterator on *this.
  Effects:
    removes the character referred to by p.

  Returns:
    an  iterator  which  points  to  the element immediately following p
    prior to the element being erased.  If no such element exists, end()
    is returned.

  iterator erase(iterator first, iterator last);

  Requires:
    first  and  last  are  valid  iterators  on  *this, defining a range
    [first,last).
  Effects:
    removes the characters in the range [first,last).
  Returns:
    an iterator which points to the element immediately  following  last
    prior to the element being erased.  If no such element exists, end()

  21.1.1.8.6  basic_string::replace                [lib.string::replace]

  basic_string<charT,traits,Allocator>&
    replace(size_type pos1, size_type n1,
            const basic_string<charT,traits,Allocator>& str);

  Returns:
    replace(pos1,n1,

  basic_string<charT,traits,Allocator>&
    replace(size_type pos1, size_type n1,
            const basic_string<charT,traits,Allocator>& str,
            size_type pos2 = 0, size_type n2 = npos);

  Requires:
    pos1 <= size() && pos2 <= str.size().
  Throws:
    out_of_range if pos1 > size() or pos2 > str.size().
  Effects:
    Determines the effective length xlen of the string to be removed  as
    the  smaller of n1 and size() - pos1.  It also determines the effec­
    tive length rlen of the string to be inserted as the smaller  of  n2
    and str.size() - pos2 .
    Throws length_error if size() - xlen >= npos - rlen.
    Otherwise, the function replaces the string controlled by *this with
    a string of length size() - xlen + rlen whose  first  pos1  elements
    are a copy of the initial elements of the original string controlled
    by *this, whose next rlen elements are a copy of  the  initial  ele­
    ments  of  the  string controlled by str beginning at position pos2,
    and whose remaining elements are a copy of the elements of the orig­
    inal string controlled by *this beginning at position pos1 + xlen.
  Returns:
    *this.

  basic_string<charT,traits,Allocator>&
    replace(size_type pos, size_type n1, const charT* s, size_type n2);

  Returns:
    replace(pos,n1,basic_string<charT,traits,Allocator>(s,n2)).

  basic_string<charT,traits,Allocator>&
    replace(size_type pos, size_type n1, const charT* s);

  Returns:
    replace(pos,n1,basic_string<charT,traits,Allocator>(s)).
  Notes:
    Uses traits::length().

  basic_string<charT,traits,Allocator>&
    replace(size_type pos, size_type n1,
            size_type n2, charT c);

  Returns:
    replace(pos,n1,basic_string<charT,traits,Allocator>(n2,c)).

  basic_string& replace(iterator i1, iterator i2, const basic_string& str);

  Requires:
    The  iterators  i1  and  i2 are valid iterators on *this, defining a
    range [i1,i2).
  Effects:
    Replaces the string controlled by *this  with  a  string  of  length
    size()  -  (i2  - i1) + str.size() whose first begin() - i1 elements
    are a copy of the initial elements of the original string controlled
    by  *this,  whose  next str.size() elements are a copy of the string
    controlled by str, and whose remaining elements are a  copy  of  the
    elements  of  the  original  string controlled by *this beginning at
    position i2.
  Returns:
    *this.
  Notes:
    After the call, the  length  of  the  string  will  be  changed  by:
    str.size() - (i2 - i1).

  basic_string&
    replace(iterator i1, iterator i2, const charT* s, size_type n);

  Returns:
    replace(i1,i2,basic_string(s,n)).
  Notes:
    Length change: n - (i2 - i1).

  basic_string& replace(iterator i1, iterator i2, const charT* s);

  Returns:
    replace(i1,i2,basic_string(s)).
  Notes:
    Length change: traits::length(s) - (i2 - i1).
    Uses traits::length().

  basic_string& replace(iterator i1, iterator i2, size_type n,
                        charT c);

  Returns:
    replace(i1,i2,basic_string(n,c)).
  Notes:
    Length change: n - (i2 - i1).

  template<class InputIterator>
    basic_string& replace(iterator i1, iterator i2,
                          InputIterator j1, InputIterator j2);

  Returns:
    replace(i1,i2,basic_string(j1,j2)).
  Notes:
    Length change: j2 - j1 - (i2 - i1).

  21.1.1.8.7  basic_string::copy                      [lib.string::copy]

  size_type copy(charT* s, size_type n, size_type pos = 0) const;

  Requires:
    pos <= size()
  Throws:
    out_of_range if pos > size().
  Effects:
    Determines  the  effective  length rlen of the string to copy as the
    smaller of n and size() - pos.  s shall designate  an  array  of  at
    least rlen elements.
    The  function then replaces the string designated by s with a string
    of length rlen whose elements are a copy of the string controlled by
    *this beginning at position pos.
    The  function does not append a null object to the string designated
    by s.
  Returns:
    rlen.

  21.1.1.8.8  basic_string::swap                      [lib.string::swap]

  void swap(basic_string<charT,traits,Allocator>& s);

  Effects:
    Swaps the contents of the two strings.
  Postcondition:
    *this contains the characters that were in s, s contains the charac­
    ters that were in *this.
  Complexity:
    linear    in    general,    constant    if    a.get_allocator()   ==
    b.get_allocator().

  21.1.1.9  basic_string string operations              [lib.string.ops]

  const charT* c_str() const;

  Returns:
    A pointer to the initial element of an array of length  size()  +  1
    whose  first size() elements equal the corresponding elements of the
    string controlled by *this and whose last element is a null  charac­
    ter specified by traits::eos().
  Requires:
    The  program  shall not alter any of the values stored in the array.
    Nor shall the program treat the returned value as  a  valid  pointer
    value  after  any  subsequent call to a non-const member function of
    the class basic_string that designates the same object as this.
  Notes:
    Uses traits::eos().

  const charT* data() const;

  Returns:
    If size() is nonzero, the member returns a pointer  to  the  initial
    element  of  an  array  whose first size() elements equal the corre­
    sponding elements of the string controlled by *this.  If  size()  is
    zero, the member returns a non-null pointer that is copyable and can
    have zero added to it.
  Requires:
    The program shall not alter any of the values stored in the  charac­
    ter  array.   Nor  shall  the  program treat the returned value as a
    valid pointer value after any subsequent call to a non- const member
    function of basic_string that designates the same object as this.

  const allocator_type& get_allocator() const;

  Returns:
    a reference to the string's allocator object.

  21.1.1.9.1  basic_string::find                      [lib.string::find]

  size_type find(const basic_string<charT,traits,Allocator>& str,
                 size_type pos = 0) const;

  Effects:
    Determines  the lowest position xpos, if possible, such that both of
    the following conditions obtain:

  --pos <= xpos and xpos + str.size() <= size();

  --at(xpos+I) == str.at(I) for all elements I of the string  controlled
    by str.
  Returns:
    xpos  if  the  function can determine such a value for xpos.  Other­
    wise, returns npos.
  Notes:
    Uses traits::eq().

  size_type find(const charT* s, size_type pos, size_type n) const;

  Returns:
    find(basic_string<charT,traits,Allocator>(s,n)pos).

  size_type find(const charT* s, size_type pos = 0) const;

  Returns:
    find(basic_string<charT,traits,Allocator>(s),pos).
  Notes:
    Uses traits::length().

  size_type find(charT c, size_type pos = 0) const;

  Returns:
    find(basic_string<charT,traits,Allocator>(1,c),pos).

  21.1.1.9.2  basic_string::rfind                    [lib.string::rfind]

  size_type rfind(const basic_string<charT,traits,Allocator>& str,
                  size_type pos = npos) const;

  Effects:
    Determines the highest position xpos, if possible, such that both of
    the following conditions obtain:

  --xpos <= pos and xpos + str.size() <= size();

  --at(xpos+I)  == str.at(I) for all elements I of the string controlled

    by str.
  Returns:
    xpos if the function can determine such a value  for  xpos.   Other­
    wise, returns npos.
  Notes:
    Uses traits::eq().

  size_type rfind(const charT* s, size_type pos, size_type n) const;

  Returns:
    rfind(basic_string<charT,traits,Allocator>(s,n),pos).

  size_type rfind(const charT* s, size_type pos = npos) const;

  Returns:
    rfind(basic_string<charT,traits,Allocator>(s),pos).
  Notes:
    Uses traits::length().

  size_type rfind(charT c, size_type pos = npos) const;

  Returns:
    rfind(basic_string<charT,traits,Allocator>(1,c),pos).

  21.1.1.9.3                                 [lib.string::find.first.of]
       basic_string::find_first_of

  size_type
    find_first_of(const basic_string<charT,traits,Allocator>& str,
                  size_type pos = 0) const;

  Effects:
    Determines the lowest position xpos, if possible, such that both  of
    the following conditions obtain:

  --pos <= xpos and xpos < size();

  --at(xpos) == str.at(I) for some element I of the string controlled by
    str.
  Returns:
    xpos if the function can determine such a value  for  xpos.   Other­
    wise, returns npos.
  Notes:
    Uses traits::eq().

  size_type
    find_first_of(const charT* s, size_type pos, size_type n) const;

  Returns:
    find_first_of(basic_string<charT,traits,Allocator>(s,n),pos).

  size_type find_first_of(const charT* s, size_type pos = 0) const;

  Returns:
    find_first_of(basic_string<charT,traits,Allocator>(s),pos).
  Notes:
    Uses traits::length().

  size_type find_first_of(charT c, size_type pos = 0) const;

  Returns:
    find_first_of(basic_string<charT,traits,Allocator>(1,c),pos).

  21.1.1.9.4  basic_string::find_last_of      [lib.string::find.last.of]

  size_type
    find_last_of(const basic_string<charT,traits,Allocator>& str,
                 size_type pos = npos) const;

  Effects:
    Determines the highest position xpos, if possible, such that both of
    the following conditions obtain:

  --xpos <= pos and pos < size();

  --at(xpos) == str.at(I) for some element I of the string controlled by
    str.
  Returns:
    xpos if the function can determine such a value  for  xpos.   Other­
    wise, returns npos.
  Notes:
    Uses traits::eq().

  size_type find_last_of(const charT* s, size_type pos, size_type n) const;

  Returns:
    find_last_of(basic_string<charT,traits,Allocator>(s,n),pos).

  size_type find_last_of(const charT* s, size_type pos = npos) const;

  Returns:
    find_last_of(basic_string<charT,traits,Allocator>(s),pos).
  Notes:
    Uses traits::length().

  size_type find_last_of(charT c, size_type pos = npos) const;

  Returns:
    find_last_of(basic_string<charT,traits,Allocator>(1,c),pos).

  21.1.1.9.5                             [lib.string::find.first.not.of]
       basic_string::find_first_not_of

  size_type
    find_first_not_of(const basic_string<charT,traits,Allocator>& str,
                      size_type pos = 0) const;

  Effects:
    Determines  the lowest position xpos, if possible, such that both of
    the following conditions obtain:

  --pos <= xpos and xpos < size();

  --at(xpos) == str.at(I) for no element I of the string  controlled  by
    str.
  Returns:
    xpos  if  the  function can determine such a value for xpos.  Other­
    wise, returns npos.
  Notes:
    Uses traits::eq().

  size_type
    find_first_not_of(const charT* s, size_type pos, size_type n) const;

  Returns:
    find_first_not_of(basic_string<charT,traits,Allocator>(s,n),pos).

  size_type find_first_not_of(const charT* s, size_type pos = 0) const;

  Returns:
    find_first_not_of(basic_string<charT,traits,Allocator>(s),pos).
  Notes:
    Uses traits::length().

  size_type find_first_not_of(charT c, size_type pos = 0) const;

  Returns:
    find_first_not_of(basic_string<charT,traits,Allocator>(1,c),pos).

  21.1.1.9.6                              [lib.string::find.last.not.of]
       basic_string::find_last_not_of

  size_type
    find_last_not_of(const basic_string<charT,traits,Allocator>& str,
                     size_type pos = npos) const;

  Effects:
    Determines the highest position xpos, if possible, such that both of
    the following conditions obtain:

  --xpos <= pos and pos < size();

  --at(xpos)  == str.at(I)) for no element I of the string controlled by
    str.
  Returns:
    xpos if the function can determine such a value  for  xpos.   Other­
    wise, returns npos.
  Notes:
    Uses traits::eq().

  size_type find_last_not_of(const charT* s, size_type pos,
                             size_type n) const;

  Returns:
    find_last_not_of(basic_string<charT,traits,Allocator>(s,n),pos).

  size_type find_last_not_of(const charT* s, size_type pos = npos) const;

  Returns:
    find_last_not_of(basic_string<charT,traits,Allocator>(s),pos).
  Notes:
    Uses traits::length().

  size_type find_last_not_of(charT c, size_type pos = npos) const;

  Returns:
    find_last_not_of(basic_string<charT,traits,Allocator>(1,c),pos).

  21.1.1.9.7  basic_string::substr                  [lib.string::substr]

  basic_string<charT,traits,Allocator>
    substr(size_type pos = 0, size_type n = npos) const;

  Requires:
    pos <= size()
  Throws:
    out_of_range if pos > size().
  Effects:
    Determines  the  effective  length rlen of the string to copy as the
    smaller of n and size() - pos.

  Returns:
    basic_string<charT,traits,Allocator>(data()+pos,rlen).

  21.1.1.9.8  basic_string::compare                [lib.string::compare]

  int compare(const basic_string<charT,traits,Allocator>& str)

  Effects:
    Determines the effective length rlen of the strings  to  compare  as
    the  smallest  of size() and str.size().  The function then compares
    the  two  strings  by  calling  traits::compare(data(),  str.data(),
    rlen).
  Returns:
    the nonzero result if the result of the comparison is nonzero.  Oth­
    erwise, returns a value as indicated in Table 8:

                         Table 8--compare() results

                   +------------------------------------+
                   |     Condition         Return Value |
                   +------------------------------------+
                   |size() <  str.size()   < 0          |
                   |size() == str.size()     0          |
                   |size() >  str.size()   > 0          |
                   +------------------------------------+

  int compare(size_type pos1, size_type n1,
              const basic_string<charT,traits,Allocator>& str) const;

  Returns:

  basic_string<charT,traits,Allocator>(*this,pos1,n1).compare(
               str)" .

  int compare(size_type pos1, size_type n1,
              const basic_string<charT,traits,Allocator>& str,
              size_type pos2, size_type n2) const;

  Returns:

  basic_string<charT,traits,Allocator>(*this,pos1,n1).compare(
               basic_string<charT,traits,Allocator>(str,pos2,n2)) .

  int compare(charT *s) const;

  Returns:
    *this.compare(basic_string<charT,traits,Allocator>(s)).

  int compare(size_type pos, size_type n1,
              chrT *s, size_type n2 = npos) const;

  Returns:

  basic_string<charT,traits,Allocator>(*this,pos,n1).compare(
               basic_string<charT,traits,Allocator>(s,n2))

  21.1.1.10  basic_string non-member             [lib.string.nonmembers]
       functions

  21.1.1.10.1  operator+                               [lib.string::op+]

  template<class charT, class traits, class Allocator>
    basic_string<charT,traits,Allocator>
      operator+(const basic_string<charT,traits,Allocator>& lhs,
                const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    basic_string<charT,traits,Allocator>(lhs).append(rhs)

  template<class charT, class traits, class Allocator>
    basic_string<charT,traits,Allocator>
      operator+(const charT* lhs,
                const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    basic_string<charT,traits,Allocator>(lhs) + rhs.
  Notes:
    Uses traits::length().

  template<class charT, class traits, class Allocator>
    basic_string<charT,traits,Allocator>
      operator+(charT lhs,
                const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    basic_string<charT,traits,Allocator>(1,lhs) + rhs.

  template<class charT, class traits, class Allocator>
    basic_string<charT,traits,Allocator>
      operator+(const basic_string<charT,traits,Allocator>& lhs,
                const charT* rhs);

  Returns:
    lhs + basic_string<charT,traits,Allocator>(rhs).
  Notes:
    Uses traits::length().

  template<class charT, class traits, class Allocator>
    basic_string<charT,traits,Allocator>
      operator+(const basic_string<charT,traits,Allocator>& lhs,
                charT rhs);

  Returns:
    lhs + basic_string<charT,traits,Allocator>(1,rhs).

  21.1.1.10.2  operator==                       [lib.string::operator==]

  template<class charT, class traits, class Allocator>
    bool operator==(const basic_string<charT,traits,Allocator>& lhs,
                    const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    lhs.compare(rhs) == 0.

  template<class charT, class traits, class Allocator>
    bool operator==(const charT* lhs,
                    const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    basic_string<charT,traits,Allocator>(lhs) == rhs.

  template<class charT, class traits, class Allocator>
    bool operator==(const basic_string<charT,traits,Allocator>& lhs,
                    const charT* rhs);

  Returns:
    lhs == basic_string<charT,traits,Allocator>(rhs).
  Notes:
    Uses traits::length().

  21.1.1.10.3  operator!=                             [lib.string::op!=]

  template<class charT, class traits, class Allocator>
    bool operator!=(const basic_string<charT,traits,Allocator>& lhs,
                    const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    !(lhs == rhs).

  template<class charT, class traits, class Allocator>
    bool operator!=(const charT* lhs,
                    const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    basic_string<charT,traits,Allocator>(lhs) != rhs.

  template<class charT, class traits, class Allocator>
    bool operator!=(const basic_string<charT,traits,Allocator>& lhs,
                    const charT* rhs);

  Returns:
    lhs != basic_string<charT,traits,Allocator>(rhs).
  Notes:
    Uses traits::length().

  21.1.1.10.4  operator<                               [lib.string::op<]

  template<class charT, class traits, class Allocator>
    bool operator< (const basic_string<charT,traits,Allocator>& lhs,
                    const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    lhs.compare(rhs) < 0.

  template<class charT, class traits, class Allocator>
    bool operator< (const charT* lhs,
                    const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    basic_string<charT,traits,Allocator>(lhs) < rhs.

  template<class charT, class traits, class Allocator>
    bool operator< (const basic_string<charT,traits,Allocator>& lhs,
                    const charT* rhs);

  Returns:
    lhs < basic_string<charT,traits,Allocator>(rhs).

  21.1.1.10.5  operator>                               [lib.string::op>]

  template<class charT, class traits, class Allocator>
    bool operator> (const basic_string<charT,traits,Allocator>& lhs,
                    const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    lhs.compare(rhs) > 0.

  template<class charT, class traits, class Allocator>
    bool operator> (const charT* lhs,
                    const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    basic_string<charT,traits,Allocator>(lhs) > rhs.

  template<class charT, class traits, class Allocator>
    bool operator> (const basic_string<charT,traits,Allocator>& lhs,
                    const charT* rhs);

  Returns:
    lhs > basic_string<charT,traits,Allocator>(rhs).

  21.1.1.10.6  operator<=                             [lib.string::op<=]

  template<class charT, class traits, class Allocator>
    bool operator<=(const basic_string<charT,traits,Allocator>& lhs,
                    const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    lhs.compare(rhs) <= 0.

  template<class charT, class traits, class Allocator>
    bool operator<=(const charT* lhs,
                    const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    basic_string<charT,traits,Allocator>(lhs) <= rhs.

  template<class charT, class traits, class Allocator>
    bool operator<=(const basic_string<charT,traits,Allocator>& lhs,
                    const charT* rhs);

  Returns:
    lhs <= basic_string<charT,traits,Allocator>(rhs).

  21.1.1.10.7  operator>=                             [lib.string::op>=]

  template<class charT, class traits, class Allocator>
    bool operator>=(const basic_string<charT,traits,Allocator>& lhs,
                    const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    lhs.compare(rhs) >= 0.

  template<class charT, class traits, class Allocator>
    bool operator>=(const charT* lhs,
                    const basic_string<charT,traits,Allocator>& rhs);

  Returns:
    basic_string<charT,traits,Allocator>(lhs) >= rhs.

  template<class charT, class traits, class Allocator>
    bool operator>=(const basic_string<charT,traits,Allocator>& lhs,
                    const charT* rhs);

  Returns:
    lhs >= basic_string<charT,traits,Allocator>(rhs).

  21.1.1.10.8  swap                                 [lib.string.special]
    template<class charT, class traits, class Allocator>
       void swap(basic_string<charT,traits,Allocator>& lhs,
                 basic_string<charT,traits,Allocator>& rhs);
  Effects:
    lhs.swap(rhs);

  +-------                 BEGIN BOX 1                -------+
  Change: Issue 23-031 in N0781R2=95-0181R2, approved in Tokyo, approved
  the  addition  of  swap  specializations  for  all  containers  except
  basic_string.   It  mentioned  the problem only in this class.  In the
  interest of stability and correctness, it has been added and an  issue
  opened to formalize the change.
  Rick Wilhelm
  +-------                  END BOX 1                 -------+

  21.1.1.10.9  Inserters and extractors                  [lib.string.io]

  template<class charT, class IS_traits,
           class STR_traits, class STR_Alloc>
    basic_istream<charT,IS_traits>&
      operator>>(basic_istream<charT,IS_traits>& is,
                 basic_string<charT,STR_traits,STR_Alloc>& str);

  Effects:
    The  function  begins  execuion  by  calling is.ipfx(true).  If that
    function  returns  true,  the  function  endeavours  to  obtain  the
    requested  input.  The function extracts characters and appends then
    to str as if by calling str.append(1,c).  If is.width()  is  greater
    than  zero,  the  maximum number of characters stored is is.width();
    otherwise it is str.max_size().  Characters are extracted and stored

    until any of the following occurs:

  --n characters are stored;

  --end-of-file occurs on the input sequence;

  --IS_traits::is_whitespace(c,ctype)  is  true  for  the next available
    input  character   c,   where   ctype   is   acquired   by   calling
    use_facet<ctype<charT>  >(is.getloc()).   In  any case, the function
    ends by calling is.isfx().
  Returns:
    is

  template<class charT, class OS_traits,
                 class STR_traits, class STR_Alloc>
    basic_ostream<charT, OS_traits>&
      operator<<(basic_ostream<charT, OS_traits>& os,
                         const basic_string<charT,STR_traits,STR_Alloc>& str);

  Effects:
    Behaves as if the function calls:

  os.write(str.data(), str.size())

  Returns:
    os

  template<class charT, class IS_traits, class STR_traits,
           class STR_Alloc>
    basic_istream<charT,IS_traits>&
      getline(basic_istream<charT,IS_traits>& is,
              basic_string<charT,STR_traits,STR_Alloc>& str,
              charT delim = IS_traits::newline() );

  Effects:
    The function begins by callling  is.ipfx(true).   If  that  function
    returns  true,  the  function  endeavours  to  extract the requested
    input.  It also counts  the  number  of  character  extracted.   The
    string  is  initially made empty by calling str.erase().  Characters
    are extracted from the stream and appended to the string  as  if  by
    calling  str.append(1,c).   Characters  are  extracted  and appended
    until one of the following occurs:

  --end-of-file occurs on the input sequence (in which case,  the  func­
    tion calls is.setstate(ios_base::eofbit)

  --c  == delim for the next available input character c (in which case,
    c is extracted but not appended) (_lib.iostate.flags_)

  --str.max_size() characters are stored (in which  case,  the  function

    calls is.setstate(ios_base::failbit) (_lib.iostate.flags_)

1 The conditions are tested in the order shown.

2 In  any case, the function ends by storing the count in is and calling
  is.isfx(), then returning the value specified.

3 If    the    function    extracts    no    characters,    it     calls
  is.setstate(ios_base::failbit)   which   may  throw  ios_base::failure
  (_lib.iostate.flags_).
  Returns:
    is.

  21.1.2  Class string                                      [lib.string]
  namespace std {
    struct string_char_traits<char> {
      typedef char char_type;
      static void assign(char& c1, const char& c2);
      static bool eq(const char& c1, const char& c2);
      static bool ne(const char& c1, const char& c2);
      static bool lt(const char& c1, const char& c2);
      static char eos();
      static int compare(const char* s1, const char* s2, size_t n);
      static const char_type* find(const char* s, int n, const char& a);
      static size_t length(const char* s);
      static char* copy(char* s1, const char* s2, size_t n);
      static char* move(char* s1, const char* s2, size_t n);
      static char* assign(char* s, size_t n, const char& a);
    };
    typedef basic_string<char> string;
  }

  21.1.3  string_char_traits<char>           [lib.string.traits.members]
       members

  static void assign(char& c1, const char& c2);

  Effects:
    c1 = c2.

  static bool eq(const char& c1, const char& c2);

  Returns:
    c1 == c2.

  static bool ne(const char& c1, const char& c2);

  Returns:
    c1 != c2.

  static bool lt(const char& c1, const char& c2);

  Returns:
    c1 < c2.

  static char eos();

  Returns:
    0.

  static int compare(const char* s1, const char* s2, size_t n);

  Returns:
    ::memcmp(s1,s2,n).

  static const char* find(const char* s, int n, const char& a);

  Returns:
    ::memchr(s,a,n).

  static size_type length(const char* s);

  Returns:
    ::strlen(s).

  static char* copy(char* s1, const char* s2, size_t n);

  Returns:
    ::memcpy(s1,s2,n).

  static char* move(char* s1, const char* s2, size_t n);

  Returns:
    ::memmove(s1,s2,n).

  static char* assign(char* s, size_t n, const char& a);

  Returns:
    ::memset(s,a,n).

  21.1.4  Class wstring                                    [lib.wstring]

  namespace std {
    struct string_char_traits<wchar_t> {
      typedef wchar_t char_type;
      static void assign(wchar_t& c1, const wchar_t& c2);
      static bool eq(const wchar_t& c1, const wchar_t& c2);
      static bool ne(const wchar_t& c1, const wchar_t& c2);
      static bool lt(const wchar_t& c1, const wchar_t& c2);
      static wchar_t eos();
      static int compare(const wchar_t* s1, const wchar_t* s2, size_t n);
      static const char_type* find(const wchar_t* s, int n, const wchar_t& a);
      static size_t length(const wchar_t* s);
      static wchar_t* copy(wchar_t* s1, const wchar_t* s2, size_t n);
      static wchar_t* move(wchar_t* s1, const wchar_t* s2, size_t n);
      static wchar_t* assign(wchar_t* s, size_t n, const wchar_t& a);
    };
    typedef basic_string<wchar_t> wstring;
  }

  21.1.5  string_char_traits<wchar_t> members      [lib.wstring.members]

  static void assign(wchar_t& c1, const wchar_t& c2);

  Effects:
    c1 = c2.

  static bool eq(const wchar_t& c1, const wchar_t& c2);

  Returns:
    c1 == c2.

  static bool ne(const wchar_t& c1, const wchar_t& c2);

  Returns:
    c1 != c2.

  static bool lt(const wchar_t& c1, const wchar_t& c2);

  Returns:
    c1 < c2.

  static wchar_t eos();

  Returns:
    0.

  static int compare(const wchar_t* s1, const wchar_t* s2, size_t n);

  Returns:
    ::wmemcmp(s1,s2,n).

  static const wchar_t* find(const wchar_t* s, int n, const w_chart& a);

  Returns:
    ::wmemchr(s,a,n).

  static size_type length(const wchar_t* s);

  Returns:
    ::wcslen(s).

  static wchar_t* copy(wchar_t* s1, const wchar_t* s2, size_t n);

  Returns:
    ::wmemcpy(s1,s2,n).

  static wchar_t* move(wchar_t* s1, const wchar_t* s2, size_t n);

  Returns:
    ::wmemmove(s1,s2,n).

  static wchar_t* assign(wchar_t* s, size_t n, const wchar_t& a);

  Returns:
    ::wmemset(s,a,n).

  21.2  Null-terminated sequence utilities               [lib.c.strings]

1 Headers <cctype>, <cwctype>, <cstring>, <cwchar>, <cstdlib> (multibyte
  conversions), and <ciso646>.

                    Table 8--Header <cctype> synopsis

            +-------------------------------------------------+
            | Type                    Name(s)                 |
            +-------------------------------------------------+
            |Functions:                                       |
            |isalnum   isdigit   isprint   isupper    tolower |
            |isalpha   isgraph   ispunct   isxdigit   toupper |
            |iscntrl   islower   isspace                      |
            +-------------------------------------------------+

                    Table 8--Header <cwctype> synopsis

   +------------------------------------------------------------------+
   |  Type                            Name(s)                         |
   +------------------------------------------------------------------+
   |Macro:     WEOF <cwctype>                                         |
   +------------------------------------------------------------------+
   |Types:     wctrans_t   wctype_t   wint_t <cwctype>                |
   +------------------------------------------------------------------+
   |Functions:                                                        |
   |iswalnum   iswctype    iswlower   iswspace    towctrans   wctrans |
   |iswalpha   iswdigit    iswprint   iswupper    towlower    wctype  |
   |iswcntrl   iswgraph    iswpunct   iswxdigit   towupper            |
   +------------------------------------------------------------------+

                    Table 8--Header <cstring> synopsis

            +-------------------------------------------------+
            | Type                    Name(s)                 |
            +-------------------------------------------------+
            |Macro:    NULL <cstring>                         |
            +-------------------------------------------------+
            |Type:     size_t <cstring>                       |
            +-------------------------------------------------+
            |Functions:                                       |
            |strcoll              strlen    strpbrk   strtok  |
            |strcat    strcpy     strncat   strrchr   strxfrm |
            |strchr    strcspn    strncmp   strspn            |
            |strcmp    strerror   strncpy   strstr            |
            +-------------------------------------------------+

                    Table 8--Header <cwchar> synopsis

  +------------------------------------------------------------------------------+
  |  Type                                  Name(s)                               |
  +------------------------------------------------------------------------------+
  |Macros:    NULL <cwchar>   WCHAR_MAX         WCHAR_MIN   WEOF <cwchar>        |
  +------------------------------------------------------------------------------+
  |Types:     mbstate_t       wint_t <cwchar>   size_t                           |
  +------------------------------------------------------------------------------+
  |Functions:                                                                    |
  |btowc      getwchar        ungetwc           wcscpy      wcsrtombs   wmemchr  |
  |fgetwc     mbrlen          vfwprintf         wcscspn     wcsspn      wmemcmp  |
  |fgetws     mbrtowc         vswprintf         wcsftime    wcsstr      wmemcpy  |
  |fputwc     mbsinit         vwprintf          wcslen      wcstod      wmemmove |
  |fputws     mbsrtowcs       wcrtomb           wcsncat     wcstok      wmemset  |
  |fwide      putwc           wcscat            wcsncmp     wcstol      wprintf  |
  |fwprintf   putwchar        wcschr            wcsncpy     wcstoul     wscanf   |
  |fwscanf    swprintf        wcscmp            wcspbrk     wcsxfrm              |
  |getwc      swscanf         wcscoll           wcsrchr     wctob                |
  +------------------------------------------------------------------------------+

                    Table 8--Header <cstdlib> synopsis

               +------------------------------------------+
               | Type                 Name(s)             |
               +------------------------------------------+
               |Macros:   MB_CUR_MAX                      |
               +------------------------------------------+
               |Functions:                                |
               |atol      mblen        strtod    wctomb   |
               |atof      mbstowcs     strtol    wcstombs |
               |atoi      mbtowc       strtoul            |
               +------------------------------------------+

  +-------                 BEGIN BOX 2                -------+
  Change: added wchar_t to above table because wcsmemchr uses it. -ark
  +-------                  END BOX 2                 -------+

2 The  contents are the same as the Standard C library, with the follow­
  ing modifications:

3 None of the headers shall define the type wchar_t (_lex.key_).

4 The function signature strchr(const char*, int) is replaced by the two
  declarations:

  const char* strchr(const char* s, int c);
        char* strchr(      char* s, int c);

5 both of which have the same behavior as the original declaration.

6 The  function  signature strpbrk(const char*, const char*) is replaced
  by the two declarations:

  const char* strpbrk(const char* s1, const char* s2);
        char* strpbrk(      char* s1, const char* s2);

7 both of which have the same behavior as the original declaration.

8 The function signature strrchr(const char*, int) is  replaced  by  the
  two declarations:

  const char* strrchr(const char* s, int c);
        char* strrchr(      char* s, int c);

9 both of which have the same behavior as the original declaration.

10The function signature strstr(const char*, const char*) is replaced by
  the two declarations:

  const char* strstr(const char* s1, const char* s2);
        char* strstr(      char* s1, const char* s2);

11both of which have the same behavior as the original declaration.

12The function signature memchr(const void*, int, size_t) is replaced by
  the two declarations:

  const void* memchr(const void* s, int c, size_t n);
        void* memchr(      void* s, int c, size_t n);

13both of which have the same behavior as the original declaration.

14The  function signature wcschr(const wchar_t*, wchar_t) is replaced by
  the two declarations:

  const wchar_t* wcschr(const wchar_t* s, wchar_t c);
        wchar_t* wcschr(      wchar_t* s, wchar_t c);

15both of which have the same behavior as the original declaration.

16The  function  signature  wcspbrk(const wchar_t*,  const wchar_t*)  is
  replaced by the two declarations:

  const wchar_t* wcspbrk(const wchar_t* s1, const wchar_t* s2);
        wchar_t* wcspbrk(      wchar_t* s1, const wchar_t* s2);

17both of which have the same behavior as the original declaration.

18The function signature wcsrchr(const wchar_t*, wchar_t) is replaced by
  the two declarations:

  const wchar_t* wcsrchr(const wchar_t* s, wchar_t c);
        wchar_t* wcsrchr(      wchar_t* s, wchar_t c);

19both of which have the same behavior as the original declaration.

20The  function  signature  wcsstr(const wchar_t*,  const wchar_t*)   is
  replaced by the two declarations:

  const wchar_t* wcsstr(const wchar_t* s1, const wchar_t* s2);
        wchar_t* wcsstr(      wchar_t* s1, const wchar_t* s2);

21both of which have the same behavior as the original declaration.

22The   function  signature  wmemchr(const wwchar_t*,  int,  size_t)  is
  replaced by the two declarations:

  const wchar_t* wmemchr(const wchar_t* s, wchar_t c, size_t n);
        wchar_t* wmemchr(      wchar_t* s, wchar_t c, size_t n);

23both of which have the same behavior as the original declaration.

  SEE ALSO: ISO C subclauses 7.3, 7.10.7, 7.10.8, and  7.11.   Amendment
  1 subclauses 4.4, 4.5, and 4.6.