basic_string/vector iterators

Philip Martin pm@corris.dircon.co.uk
Thu Dec 30 07:30:00 GMT 1999


Hello

Here is a second implementation of a class for basic_string and vector
iterators.  The first significant difference between this and the
previous post is that the template parameter is now an iterator
instead of a value type.  This makes the class a more general iterator
adapter, although I only see it being used to change pointers into
classes. The iterator_category of the class is that of the template
parameter and thus the class is not necessarily a random access
iterator.

This change made it necessary to alter the way that an iterator is
converted to a const_iterator.  Previously there was an ordinary
member constructor, now there is a template member constructor.  This
has the effect that the assignment of a const_iterator to an iterator
now generates the same warning/error that would be generated for the
template parameter: in the case of basic_string and vector a warning
about discarding const.  The previous implementation generated an
error for this case.

A second change is that I have made the comparison operators
non-member functions, much as for reverse_iterator<>.  I have also
added operator+(difference_type,iterator) which was missing from the
previous post.

I have finally manged to compile and run with -fnew-abi and the size
problem caused by inheriting from std::iterator is indeed removed.


Philip


-------------------------------------------------------------------------------


1999-02-14  Philip Martin  <pm@corris.dircon.co.uk>

	* bits/basic_string.h: use __normal_iterator<> for iterators
	* bits/std_sstream.h: support __normal_iterator<> iterators
	* bits/string.tcc: ditto
	* src/misc-inst.cc: ditto
	* stl/bits/stl_iterator.h: add __normal_iterator<>
	* stl/bits/stl_vector.h: use __normal_iterator<> for iterators
	* testsuite/24/24iterator.cc: Add test cases for basic_string and 
	vector iterators


diff -cprN libstdc++/bits/basic_string.h libstdc++-modified/bits/basic_string.h
*** libstdc++/bits/basic_string.h	Fri Feb 12 19:40:15 1999
--- libstdc++-modified/bits/basic_string.h	Mon Feb 15 20:33:29 1999
*************** namespace std {
*** 40,45 ****
--- 40,47 ----
    template<class _CharT, class _Traits, class _Alloc>
    class basic_string
    {
+   private:
+     typedef basic_string<_CharT, _Traits, _Alloc> string_type;
    public:
      // Types:
      typedef _Traits traits_type;
*************** namespace std {
*** 51,58 ****
      typedef typename _Alloc::const_reference const_reference;
      typedef typename _Alloc::pointer pointer;
      typedef typename _Alloc::const_pointer const_pointer;
!     typedef pointer iterator;
!     typedef const_pointer const_iterator;
      typedef reverse_iterator<const_iterator> const_reverse_iterator;
      typedef reverse_iterator<iterator> reverse_iterator;
      static const size_type npos = ~(size_type)0;
--- 53,60 ----
      typedef typename _Alloc::const_reference const_reference;
      typedef typename _Alloc::pointer pointer;
      typedef typename _Alloc::const_pointer const_pointer;
!     typedef __normal_iterator<pointer, string_type> iterator;
!     typedef __normal_iterator<const_pointer, string_type> const_iterator;
      typedef reverse_iterator<const_iterator> const_reverse_iterator;
      typedef reverse_iterator<iterator> reverse_iterator;
      static const size_type npos = ~(size_type)0;
*************** namespace std {
*** 141,148 ****
  
      // For the internal use we have functions similar to `begin'/`end'
      // but they do not call _M_leak.
!     iterator _M_ibegin () const { return _M_data (); }
!     iterator _M_iend () const { return _M_data () + this->size (); }
  
      void _M_leak ()    // for use in begin() & non-const op[]
        { if (_M_rep ()->_M_state >= 0) _M_leak_hard(); }
--- 143,150 ----
  
      // For the internal use we have functions similar to `begin'/`end'
      // but they do not call _M_leak.
!     iterator _M_ibegin () const { return iterator (_M_data ()); }
!     iterator _M_iend () const { return iterator (_M_data () + this->size ()); }
  
      void _M_leak ()    // for use in begin() & non-const op[]
        { if (_M_rep ()->_M_state >= 0) _M_leak_hard(); }
*************** namespace std {
*** 213,222 ****
        { return assign (1, __c); }
  
      // Iterators:
!     iterator begin () { _M_leak (); return &this->operator[](0); }
!     const_iterator begin () const { return &(*_M_rep ())[0]; }
!     iterator end () { _M_leak (); return &(this->operator[](length ())); }
!     const_iterator end () const { return &(*_M_rep ())[length ()]; }
  
      reverse_iterator rbegin ()
        { return reverse_iterator (end ()); }
--- 215,229 ----
        { return assign (1, __c); }
  
      // Iterators:
!     iterator begin () { _M_leak (); return iterator (&this->operator[](0)); }
!     const_iterator begin () const { return const_iterator (&(*_M_rep ())[0]); }
!     iterator end ()
!       {
!          _M_leak ();
!          return iterator (&(this->operator[](length ())));
!       }
!     const_iterator end () const
!       { return const_iterator (&(*_M_rep ())[length ()]); }
  
      reverse_iterator rbegin ()
        { return reverse_iterator (end ()); }
diff -cprN libstdc++/bits/std_sstream.h libstdc++-modified/bits/std_sstream.h
*** libstdc++/bits/std_sstream.h	Fri Feb 12 19:41:10 1999
--- libstdc++-modified/bits/std_sstream.h	Sun Feb 14 17:01:15 1999
*************** namespace std {
*** 240,251 ****
  
      virtual int sync()
        {
! 	// Will eventually need to cast these to _Alloc::pointer or
! 	// string_type::iterator types.
  	if (_M_mode & ios_base::in)
! 	  setg(_M_str.begin(), _M_str.begin(), _M_str.end());
  	if (_M_mode & ios_base::out)
! 	    setp(_M_str.begin(), _M_str.end());
  	return 0;
        }
  
--- 240,252 ----
  
      virtual int sync()
        {
!         // using details of iterator implementation to convert
!         // iterator to pointer
  	if (_M_mode & ios_base::in)
! 	  setg(_M_str.begin().base(), _M_str.begin().base(),
!                _M_str.end().base());
  	if (_M_mode & ios_base::out)
! 	    setp(_M_str.begin().base(), _M_str.end().base());
  	return 0;
        }
  
diff -cprN libstdc++/bits/string.tcc libstdc++-modified/bits/string.tcc
*** libstdc++/bits/string.tcc	Thu Dec 31 23:15:39 1998
--- libstdc++-modified/bits/string.tcc	Sun Feb 14 18:04:33 1999
*************** template<class _CharT, class _Traits, cl
*** 450,456 ****
    _M_mutate (__newlen, __off1, _M_iend () - __i2);
    // invalidated __i1, __i2
    if (__n2)
!     _S_copy_chars(_M_ibegin () + __off1, __j1, __j2);
    return *this;
  }
  
--- 450,456 ----
    _M_mutate (__newlen, __off1, _M_iend () - __i2);
    // invalidated __i1, __i2
    if (__n2)
!     _S_copy_chars(_M_data () + __off1, __j1, __j2);
    return *this;
  }
  
*************** basic_string<_CharT,_Traits,_Alloc>::rep
*** 477,483 ****
    _M_mutate (__newlen, __off1, _M_iend () - __i2);
    // invalidated __i1, __i2
    if (__n2)
!     _Traits::assign(_M_ibegin () + __off1, __n2, __c);
    return *this;
  }
  
--- 477,483 ----
    _M_mutate (__newlen, __off1, _M_iend () - __i2);
    // invalidated __i1, __i2
    if (__n2)
!     _Traits::assign(_M_data () + __off1, __n2, __c);
    return *this;
  }
  
*************** basic_string<_CharT,_Traits,_Alloc>::fin
*** 533,540 ****
  {
    if (__pos < this->size())
      {
!       const _CharT* __p = _S_find(data () + __pos, _M_iend (), __c);
!       if (__p != _M_iend ())
          return __p - data ();
      }
    return npos;
--- 533,540 ----
  {
    if (__pos < this->size())
      {
!       const _CharT* __p = _S_find(data () + __pos, _M_data (), __c);
!       if (__p != _M_data () + this->size())
          return __p - data ();
      }
    return npos;
diff -cprN libstdc++/src/misc-inst.cc libstdc++-modified/src/misc-inst.cc
*** libstdc++/src/misc-inst.cc	Fri Feb 12 19:41:20 1999
--- libstdc++-modified/src/misc-inst.cc	Sun Feb 14 17:02:37 1999
***************
*** 47,55 ****
  //
  // string
  //
! template string::basic_string(char*, char*, allocator<char> const&);
  
! template wstring::basic_string(wchar_t*, wchar_t*, allocator<wchar_t> const&);
  
  template char* string::_S_construct<char *>(char *, char *, allocator<char> const &, forward_iterator_tag);
  
--- 47,55 ----
  //
  // string
  //
! template string::basic_string(string::iterator, string::iterator, allocator<char> const&);
  
! template wstring::basic_string(wstring::iterator, wstring::iterator, allocator<wchar_t> const&);
  
  template char* string::_S_construct<char *>(char *, char *, allocator<char> const &, forward_iterator_tag);
  
*************** template wchar_t* wstring::_S_construct<
*** 59,71 ****
  
  template wchar_t* wstring::_S_construct<const wchar_t *>(const wchar_t *, const wchar_t *, allocator<wchar_t> const &, forward_iterator_tag);
  
! template string& string::_M_replace<char *>(char *, char *, char *, char *, forward_iterator_tag);
  
! template string& string::_M_replace<const char *>(char *, char *, const char *, const char *, forward_iterator_tag);
  
! template wstring& wstring::_M_replace<wchar_t *>(wchar_t *, wchar_t *, wchar_t *, wchar_t *, forward_iterator_tag);
  
! template wstring& wstring::_M_replace<const wchar_t *>(wchar_t *, wchar_t *, const wchar_t *, const wchar_t *, forward_iterator_tag);
  
  
  //
--- 59,79 ----
  
  template wchar_t* wstring::_S_construct<const wchar_t *>(const wchar_t *, const wchar_t *, allocator<wchar_t> const &, forward_iterator_tag);
  
! template string& string::_M_replace<char *>(string::iterator, string::iterator, char *, char *, forward_iterator_tag);
  
! template string& string::_M_replace<const char *>(string::iterator, string::iterator, const char *, const char *, forward_iterator_tag);
  
! template string& string::_M_replace<string::iterator>(string::iterator, string::iterator, string::iterator, string::iterator, forward_iterator_tag);
  
! template string& string::_M_replace<string::const_iterator>(string::iterator, string::iterator, string::const_iterator, string::const_iterator, forward_iterator_tag);
! 
! template wstring& wstring::_M_replace<wchar_t *>(wstring::iterator, wstring::iterator, wchar_t *, wchar_t *, forward_iterator_tag);
! 
! template wstring& wstring::_M_replace<const wchar_t *>(wstring::iterator, wstring::iterator, const wchar_t *, const wchar_t *, forward_iterator_tag);
! 
! template wstring& wstring::_M_replace<wstring::iterator>(wstring::iterator, wstring::iterator, wstring::iterator, wstring::iterator, forward_iterator_tag);
! 
! template wstring& wstring::_M_replace<wstring::const_iterator>(wstring::iterator, wstring::iterator, wstring::const_iterator, wstring::const_iterator, forward_iterator_tag);
  
  
  //
*************** template wistreambuf_iter __match_parall
*** 83,89 ****
   wistreambuf_iter, wistreambuf_iter, int, const string *, int *, int &, bool &);
  
  template void vector<locale::facet *, allocator<locale::facet *> >::insert(
!   locale::facet **, unsigned int, locale::facet *const &);
  
  //template bool istreambuf_iter::_M_equal_helper(const istreambuf_iter &) const;
  
--- 91,97 ----
   wistreambuf_iter, wistreambuf_iter, int, const string *, int *, int &, bool &);
  
  template void vector<locale::facet *, allocator<locale::facet *> >::insert(
!   vector<locale::facet *, allocator<locale::facet *> >::iterator, unsigned int, locale::facet *const &);
  
  //template bool istreambuf_iter::_M_equal_helper(const istreambuf_iter &) const;
  
*************** template const char*  find_if<const char
*** 216,226 ****
  template string* __uninitialized_fill_n_aux<string*, unsigned int, string>
  (string*, unsigned int, string const &, _Bool<false>);
  
! template string* __uninitialized_copy_aux<string const *, string *>
! (string const *, string const *, string*, _Bool<false>);
  
  template locale::facet ** fill_n<locale::facet **, unsigned int, locale::facet *>(locale::facet **, unsigned int, locale::facet * const &);
  
  template void fill<locale::facet **, locale::facet *>(locale::facet **, locale::facet *, locale::facet * const &);
  
  
--- 224,238 ----
  template string* __uninitialized_fill_n_aux<string*, unsigned int, string>
  (string*, unsigned int, string const &, _Bool<false>);
  
! template string* __uninitialized_copy_aux<vector<string>::const_iterator, string*> (vector<string>::const_iterator, vector<string>::const_iterator, string*, _Bool<false>);
  
  template locale::facet ** fill_n<locale::facet **, unsigned int, locale::facet *>(locale::facet **, unsigned int, locale::facet * const &);
  
  template void fill<locale::facet **, locale::facet *>(locale::facet **, locale::facet *, locale::facet * const &);
  
  
+ template const ctype<char>& use_facet<ctype<char> >(const locale &);
+ 
+ template const ctype<wchar_t>& use_facet<ctype<wchar_t> >(const locale &);
+ 
+ template const codecvt<char, char, mbstate_t>& use_facet<codecvt<char, char, mbstate_t> >(const locale &);
diff -cprN libstdc++/stl/bits/stl_iterator.h libstdc++-modified/stl/bits/stl_iterator.h
*** libstdc++/stl/bits/stl_iterator.h	Fri Feb 12 19:45:40 1999
--- libstdc++-modified/stl/bits/stl_iterator.h	Mon Feb 15 22:30:50 1999
*************** iterator_category(const ostream_iterator
*** 944,949 ****
--- 944,1079 ----
  
  #endif /* __STL_USE_NEW_IOSTREAMS */
  
+ // This iterator adapter is 'normal' in the sense that it does not
+ // change the semantics of any of the operators of its itererator
+ // parameter.  Its primary purpose is to convert an iterator that is
+ // not a class, e.g. a pointer, into an iterator that is a class.
+ // The _Container parameter exists solely so that different containers
+ // using this template can instantiate different types, even if the
+ // _Iterator parameter is the same.
+ template<typename _Iterator, typename _Container>
+ class __normal_iterator
+   : public iterator<iterator_traits<_Iterator>::iterator_category,
+                     iterator_traits<_Iterator>::value_type,
+                     iterator_traits<_Iterator>::difference_type,
+                     iterator_traits<_Iterator>::pointer,
+                     iterator_traits<_Iterator>::reference>
+ {
+ public:
+ 
+   typedef __normal_iterator<_Iterator, _Container> normal_iterator_type;
+ 
+   inline __normal_iterator() : _M_current() { }
+ 
+   inline explicit __normal_iterator(const _Iterator& __i)
+     : _M_current(__i) { }
+ 
+   // Allow iterator to const_iterator conversion
+   template<typename _Iter>
+   inline __normal_iterator(const __normal_iterator<_Iter, _Container>& __i)
+     : _M_current(__i.base()) { }
+ 
+   // forward iterator requirements
+ 
+   inline reference
+   operator*() const
+     { return *_M_current; }
+ 
+   inline pointer
+   operator->() const
+     { return _M_current; }
+ 
+   inline normal_iterator_type&
+   operator++()
+     { ++_M_current; return *this; }
+ 
+   inline normal_iterator_type
+   operator++(int)
+     { return __normal_iterator(_M_current++); }
+ 
+   // bidirectional iterator requirements
+ 
+   inline normal_iterator_type&
+   operator--()
+     { --_M_current; return *this; }
+ 
+   inline normal_iterator_type
+   operator--(int)
+     { return __normal_iterator(_M_current--); }
+ 
+   // random access iterator requirements
+ 
+   inline reference
+   operator[](const difference_type& __n) const
+     { return _M_current[__n]; }
+ 
+   inline normal_iterator_type&
+   operator+=(const difference_type& __n)
+     { _M_current += __n; return *this; }
+ 
+   inline normal_iterator_type
+   operator+(const difference_type& __n) const
+     { return __normal_iterator(_M_current + __n); }
+ 
+   inline normal_iterator_type&
+   operator-=(const difference_type& __n)
+     { _M_current -= __n; return *this; }
+ 
+   inline normal_iterator_type
+   operator-(const difference_type& __n) const
+     { return __normal_iterator(_M_current - __n); }
+ 
+   inline difference_type
+   operator-(const normal_iterator_type& __i) const
+     { return _M_current - __i._M_current; }
+ 
+   const _Iterator& base() const
+     { return _M_current; }
+ 
+ protected:
+   _Iterator _M_current;
+ };
+ 
+ // forward iterator requirements
+ 
+ template<typename _IteratorL, typename _IteratorR, typename _Container>
+ bool operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
+                 const __normal_iterator<_IteratorR, _Container>& __rhs)
+ { return __lhs.base() == __rhs.base(); }
+ 
+ template<typename _IteratorL, typename _IteratorR, typename _Container>
+ bool operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
+                 const __normal_iterator<_IteratorR, _Container>& __rhs)
+ { return !(__lhs == __rhs); }
+ 
+ // random access iterator requirements
+ 
+ template<typename _IteratorL, typename _IteratorR, typename _Container>
+ bool operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
+                const __normal_iterator<_IteratorR, _Container>& __rhs)
+ { return __lhs.base() < __rhs.base(); }
+ 
+ template<typename _IteratorL, typename _IteratorR, typename _Container>
+ bool operator>(const __normal_iterator<_IteratorL, _Container>& __lhs,
+                const __normal_iterator<_IteratorR, _Container>& __rhs)
+ { return __rhs < __lhs; }
+ 
+ template<typename _IteratorL, typename _IteratorR, typename _Container>
+ bool operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs,
+                 const __normal_iterator<_IteratorR, _Container>& __rhs)
+ { return !(__rhs < __lhs); }
+ 
+ template<typename _IteratorL, typename _IteratorR, typename _Container>
+ bool operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs,
+                 const __normal_iterator<_IteratorR, _Container>& __rhs)
+ { return !(__lhs < __rhs); }
+ 
+ template<typename _Iterator, typename _Container>
+ inline __normal_iterator<_Iterator, _Container>
+ operator+(__normal_iterator<_Iterator, _Container>::difference_type __n,
+           const __normal_iterator<_Iterator, _Container>& __i)
+ { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
+ 
  __STL_END_NAMESPACE
  
  #endif /* __SGI_STL_INTERNAL_ITERATOR_H */
diff -cprN libstdc++/stl/bits/stl_vector.h libstdc++-modified/stl/bits/stl_vector.h
*** libstdc++/stl/bits/stl_vector.h	Fri Feb 12 19:46:25 1999
--- libstdc++-modified/stl/bits/stl_vector.h	Mon Feb 15 20:33:39 1999
*************** class vector : protected _Vector_base<_T
*** 154,165 ****
  {
  private:
    typedef _Vector_base<_Tp, _Alloc> _Base;
  public:
    typedef _Tp value_type;
    typedef value_type* pointer;
    typedef const value_type* const_pointer;
!   typedef value_type* iterator;
!   typedef const value_type* const_iterator;
    typedef value_type& reference;
    typedef const value_type& const_reference;
    typedef size_t size_type;
--- 154,166 ----
  {
  private:
    typedef _Vector_base<_Tp, _Alloc> _Base;
+   typedef vector<_Tp, _Alloc> vector_type;
  public:
    typedef _Tp value_type;
    typedef value_type* pointer;
    typedef const value_type* const_pointer;
!   typedef __normal_iterator<pointer, vector_type> iterator;
!   typedef __normal_iterator<const_pointer, vector_type> const_iterator;
    typedef value_type& reference;
    typedef const value_type& const_reference;
    typedef size_t size_type;
*************** protected:
*** 192,201 ****
    void _M_insert_aux(iterator __position);
  
  public:
!   iterator begin() { return _M_start; }
!   const_iterator begin() const { return _M_start; }
!   iterator end() { return _M_finish; }
!   const_iterator end() const { return _M_finish; }
  
    reverse_iterator rbegin()
      { return reverse_iterator(end()); }
--- 193,203 ----
    void _M_insert_aux(iterator __position);
  
  public:
!   iterator begin() { return iterator (_M_start); }
!   const_iterator begin() const
!     { return const_iterator (_M_start); }
!   iterator end() { return iterator (_M_finish); }
!   const_iterator end() const { return const_iterator (_M_finish); }
  
    reverse_iterator rbegin()
      { return reverse_iterator(end()); }
*************** public:
*** 269,275 ****
    void reserve(size_type __n) {
      if (capacity() < __n) {
        const size_type __old_size = size();
!       iterator __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish);
        destroy(_M_start, _M_finish);
        _M_deallocate(_M_start, _M_end_of_storage - _M_start);
        _M_start = __tmp;
--- 271,277 ----
    void reserve(size_type __n) {
      if (capacity() < __n) {
        const size_type __old_size = size();
!       iterator __tmp(_M_allocate_and_copy(__n, _M_start, _M_finish));
        destroy(_M_start, _M_finish);
        _M_deallocate(_M_start, _M_end_of_storage - _M_start);
        _M_start = __tmp;
*************** public:
*** 391,404 ****
    }
    iterator erase(iterator __position) {
      if (__position + 1 != end())
!       copy(__position + 1, _M_finish, __position);
      --_M_finish;
      destroy(_M_finish);
      return __position;
    }
    iterator erase(iterator __first, iterator __last) {
!     iterator __i = copy(__last, _M_finish, __first);
!     destroy(__i, _M_finish);
      _M_finish = _M_finish - (__last - __first);
      return __first;
    }
--- 393,406 ----
    }
    iterator erase(iterator __position) {
      if (__position + 1 != end())
!       copy(__position + 1, end(), __position);
      --_M_finish;
      destroy(_M_finish);
      return __position;
    }
    iterator erase(iterator __first, iterator __last) {
!     iterator __i(copy(__last, end(), __first));
!     destroy(__i, end());
      _M_finish = _M_finish - (__last - __first);
      return __first;
    }
*************** protected:
*** 419,425 ****
    iterator _M_allocate_and_copy(size_type __n, _ForwardIterator __first, 
                                                 _ForwardIterator __last)
  {
!     iterator __result = _M_allocate(__n);
      __STL_TRY {
        uninitialized_copy(__first, __last, __result);
        return __result;
--- 421,427 ----
    iterator _M_allocate_and_copy(size_type __n, _ForwardIterator __first, 
                                                 _ForwardIterator __last)
  {
!     iterator __result(_M_allocate(__n));
      __STL_TRY {
        uninitialized_copy(__first, __last, __result);
        return __result;
*************** protected:
*** 430,436 ****
    iterator _M_allocate_and_copy(size_type __n, const_iterator __first, 
                                                 const_iterator __last)
    {
!     iterator __result = _M_allocate(__n);
      __STL_TRY {
        uninitialized_copy(__first, __last, __result);
        return __result;
--- 432,438 ----
    iterator _M_allocate_and_copy(size_type __n, const_iterator __first, 
                                                 const_iterator __last)
    {
!     iterator __result(_M_allocate(__n));
      __STL_TRY {
        uninitialized_copy(__first, __last, __result);
        return __result;
*************** vector<_Tp,_Alloc>::operator=(const vect
*** 531,544 ****
    if (&__x != this) {
      const size_type __xlen = __x.size();
      if (__xlen > capacity()) {
!       iterator __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end());
        destroy(_M_start, _M_finish);
        _M_deallocate(_M_start, _M_end_of_storage - _M_start);
        _M_start = __tmp;
        _M_end_of_storage = _M_start + __xlen;
      }
      else if (size() >= __xlen) {
!       iterator __i = copy(__x.begin(), __x.end(), begin());
        destroy(__i, _M_finish);
      }
      else {
--- 533,546 ----
    if (&__x != this) {
      const size_type __xlen = __x.size();
      if (__xlen > capacity()) {
!       iterator __tmp(_M_allocate_and_copy(__xlen, __x.begin(), __x.end()));
        destroy(_M_start, _M_finish);
        _M_deallocate(_M_start, _M_end_of_storage - _M_start);
        _M_start = __tmp;
        _M_end_of_storage = _M_start + __xlen;
      }
      else if (size() >= __xlen) {
!       iterator __i(copy(__x.begin(), __x.end(), begin()));
        destroy(__i, _M_finish);
      }
      else {
*************** void vector<_Tp, _Alloc>::assign(size_t 
*** 569,575 ****
  template <class _Tp, class _Alloc> template <class _InputIter>
  void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last,
                                          input_iterator_tag) {
!   iterator __cur = begin();
    for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
      *__cur = *__first;
    if (__first == __last)
--- 571,577 ----
  template <class _Tp, class _Alloc> template <class _InputIter>
  void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last,
                                          input_iterator_tag) {
!   iterator __cur(begin());
    for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
      *__cur = *__first;
    if (__first == __last)
*************** vector<_Tp, _Alloc>::_M_assign_aux(_Forw
*** 586,599 ****
    distance(__first, __last, __len);
  
    if (__len > capacity()) {
!     iterator __tmp = _M_allocate_and_copy(__len, __first, __last);
      destroy(_M_start, _M_finish);
      _M_deallocate(_M_start, _M_end_of_storage - _M_start);
      _M_start = __tmp;
      _M_end_of_storage = _M_finish = _M_start + __len;
    }
    else if (size() >= __len) {
!     iterator __new_finish = copy(__first, __last, _M_start);
      destroy(__new_finish, _M_finish);
      _M_finish = __new_finish;
    }
--- 588,601 ----
    distance(__first, __last, __len);
  
    if (__len > capacity()) {
!     iterator __tmp(_M_allocate_and_copy(__len, __first, __last));
      destroy(_M_start, _M_finish);
      _M_deallocate(_M_start, _M_end_of_storage - _M_start);
      _M_start = __tmp;
      _M_end_of_storage = _M_finish = _M_start + __len;
    }
    else if (size() >= __len) {
!     iterator __new_finish(copy(__first, __last, _M_start));
      destroy(__new_finish, _M_finish);
      _M_finish = __new_finish;
    }
*************** vector<_Tp, _Alloc>::_M_insert_aux(itera
*** 615,641 ****
      construct(_M_finish, *(_M_finish - 1));
      ++_M_finish;
      _Tp __x_copy = __x;
!     copy_backward(__position, _M_finish - 2, _M_finish - 1);
      *__position = __x_copy;
    }
    else {
      const size_type __old_size = size();
      const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
!     iterator __new_start = _M_allocate(__len);
!     iterator __new_finish = __new_start;
      __STL_TRY {
!       __new_finish = uninitialized_copy(_M_start, __position, __new_start);
!       construct(__new_finish, __x);
        ++__new_finish;
!       __new_finish = uninitialized_copy(__position, _M_finish, __new_finish);
      }
      __STL_UNWIND((destroy(__new_start,__new_finish), 
!                   _M_deallocate(__new_start,__len)));
      destroy(begin(), end());
      _M_deallocate(_M_start, _M_end_of_storage - _M_start);
!     _M_start = __new_start;
!     _M_finish = __new_finish;
!     _M_end_of_storage = __new_start + __len;
    }
  }
  
--- 617,645 ----
      construct(_M_finish, *(_M_finish - 1));
      ++_M_finish;
      _Tp __x_copy = __x;
!     copy_backward(__position, iterator(_M_finish - 2), iterator(_M_finish- 1));
      *__position = __x_copy;
    }
    else {
      const size_type __old_size = size();
      const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
!     iterator __new_start(_M_allocate(__len));
!     iterator __new_finish(__new_start);
      __STL_TRY {
!       __new_finish = uninitialized_copy(iterator(_M_start), __position,
!                                         __new_start);
!       construct(__new_finish.base(), __x);
        ++__new_finish;
!       __new_finish = uninitialized_copy(__position, iterator(_M_finish),
!                                         __new_finish);
      }
      __STL_UNWIND((destroy(__new_start,__new_finish), 
!                   _M_deallocate(__new_start.base(),__len)));
      destroy(begin(), end());
      _M_deallocate(_M_start, _M_end_of_storage - _M_start);
!     _M_start = __new_start.base();
!     _M_finish = __new_finish.base();
!     _M_end_of_storage = __new_start.base() + __len;
    }
  }
  
*************** vector<_Tp, _Alloc>::_M_insert_aux(itera
*** 652,659 ****
    else {
      const size_type __old_size = size();
      const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
!     iterator __new_start = _M_allocate(__len);
!     iterator __new_finish = __new_start;
      __STL_TRY {
        __new_finish = uninitialized_copy(_M_start, __position, __new_start);
        construct(__new_finish);
--- 656,663 ----
    else {
      const size_type __old_size = size();
      const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
!     iterator __new_start(_M_allocate(__len));
!     iterator __new_finish(__new_start);
      __STL_TRY {
        __new_finish = uninitialized_copy(_M_start, __position, __new_start);
        construct(__new_finish);
*************** void vector<_Tp, _Alloc>::insert(iterato
*** 677,684 ****
    if (__n != 0) {
      if (size_type(_M_end_of_storage - _M_finish) >= __n) {
        _Tp __x_copy = __x;
!       const size_type __elems_after = _M_finish - __position;
!       iterator __old_finish = _M_finish;
        if (__elems_after > __n) {
          uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
          _M_finish += __n;
--- 681,688 ----
    if (__n != 0) {
      if (size_type(_M_end_of_storage - _M_finish) >= __n) {
        _Tp __x_copy = __x;
!       const size_type __elems_after = end() - __position;
!       iterator __old_finish(_M_finish);
        if (__elems_after > __n) {
          uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
          _M_finish += __n;
*************** void vector<_Tp, _Alloc>::insert(iterato
*** 696,716 ****
      else {
        const size_type __old_size = size();        
        const size_type __len = __old_size + max(__old_size, __n);
!       iterator __new_start = _M_allocate(__len);
!       iterator __new_finish = __new_start;
        __STL_TRY {
!         __new_finish = uninitialized_copy(_M_start, __position, __new_start);
          __new_finish = uninitialized_fill_n(__new_finish, __n, __x);
          __new_finish
!           = uninitialized_copy(__position, _M_finish, __new_finish);
        }
        __STL_UNWIND((destroy(__new_start,__new_finish), 
!                     _M_deallocate(__new_start,__len)));
        destroy(_M_start, _M_finish);
        _M_deallocate(_M_start, _M_end_of_storage - _M_start);
!       _M_start = __new_start;
!       _M_finish = __new_finish;
!       _M_end_of_storage = __new_start + __len;
      }
    }
  }
--- 700,720 ----
      else {
        const size_type __old_size = size();        
        const size_type __len = __old_size + max(__old_size, __n);
!       iterator __new_start(_M_allocate(__len));
!       iterator __new_finish(__new_start);
        __STL_TRY {
!         __new_finish = uninitialized_copy(_M_start, __position.base(), __new_start);
          __new_finish = uninitialized_fill_n(__new_finish, __n, __x);
          __new_finish
!           = uninitialized_copy(__position.base(), _M_finish, __new_finish);
        }
        __STL_UNWIND((destroy(__new_start,__new_finish), 
!                     _M_deallocate(__new_start.base(),__len)));
        destroy(_M_start, _M_finish);
        _M_deallocate(_M_start, _M_end_of_storage - _M_start);
!       _M_start = __new_start.base();
!       _M_finish = __new_finish.base();
!       _M_end_of_storage = __new_start.base() + __len;
      }
    }
  }
*************** vector<_Tp, _Alloc>::_M_range_insert(ite
*** 742,748 ****
      distance(__first, __last, __n);
      if (size_type(_M_end_of_storage - _M_finish) >= __n) {
        const size_type __elems_after = _M_finish - __position;
!       iterator __old_finish = _M_finish;
        if (__elems_after > __n) {
          uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
          _M_finish += __n;
--- 746,752 ----
      distance(__first, __last, __n);
      if (size_type(_M_end_of_storage - _M_finish) >= __n) {
        const size_type __elems_after = _M_finish - __position;
!       iterator __old_finish(_M_finish);
        if (__elems_after > __n) {
          uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
          _M_finish += __n;
*************** vector<_Tp, _Alloc>::_M_range_insert(ite
*** 762,769 ****
      else {
        const size_type __old_size = size();
        const size_type __len = __old_size + max(__old_size, __n);
!       iterator __new_start = _M_allocate(__len);
!       iterator __new_finish = __new_start;
        __STL_TRY {
          __new_finish = uninitialized_copy(_M_start, __position, __new_start);
          __new_finish = uninitialized_copy(__first, __last, __new_finish);
--- 766,773 ----
      else {
        const size_type __old_size = size();
        const size_type __len = __old_size + max(__old_size, __n);
!       iterator __new_start(_M_allocate(__len));
!       iterator __new_finish(__new_start);
        __STL_TRY {
          __new_finish = uninitialized_copy(_M_start, __position, __new_start);
          __new_finish = uninitialized_copy(__first, __last, __new_finish);
*************** vector<_Tp, _Alloc>::insert(iterator __p
*** 794,800 ****
      distance(__first, __last, __n);
      if (size_type(_M_end_of_storage - _M_finish) >= __n) {
        const size_type __elems_after = _M_finish - __position;
!       iterator __old_finish = _M_finish;
        if (__elems_after > __n) {
          uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
          _M_finish += __n;
--- 798,804 ----
      distance(__first, __last, __n);
      if (size_type(_M_end_of_storage - _M_finish) >= __n) {
        const size_type __elems_after = _M_finish - __position;
!       iterator __old_finish(_M_finish);
        if (__elems_after > __n) {
          uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
          _M_finish += __n;
*************** vector<_Tp, _Alloc>::insert(iterator __p
*** 812,819 ****
      else {
        const size_type __old_size = size();
        const size_type __len = __old_size + max(__old_size, __n);
!       iterator __new_start = _M_allocate(__len);
!       iterator __new_finish = __new_start;
        __STL_TRY {
          __new_finish = uninitialized_copy(_M_start, __position, __new_start);
          __new_finish = uninitialized_copy(__first, __last, __new_finish);
--- 816,823 ----
      else {
        const size_type __old_size = size();
        const size_type __len = __old_size + max(__old_size, __n);
!       iterator __new_start(_M_allocate(__len));
!       iterator __new_finish(__new_start);
        __STL_TRY {
          __new_finish = uninitialized_copy(_M_start, __position, __new_start);
          __new_finish = uninitialized_copy(__first, __last, __new_finish);
diff -cprN libstdc++/testsuite/24/24iterator.cc libstdc++-modified/testsuite/24/24iterator.cc
*** libstdc++/testsuite/24/24iterator.cc	Thu Jan  1 01:00:00 1970
--- libstdc++-modified/testsuite/24/24iterator.cc	Mon Feb 15 20:53:11 1999
***************
*** 0 ****
--- 1,581 ----
+ // 24.1.5 Random accesss iterators
+ // 24.3.1 Iterator traits
+ // (basic_string and vector implementations)
+ //
+ // Copyright (C) 1999  Philip Martin
+ // This program is free software; you can redistribute it and/or modify
+ // it under the terms of the GNU General Public License as published by
+ // the Free Software Foundation; either version 2 of the License, or 
+ // (at your option) any later version.                             
+ //                                                         
+ // This program is distributed in the hope that it will be useful,   
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of    
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    
+ // GNU General Public License for more details.
+ //
+ // You should have received a copy of the GNU General Public License
+ // along with this program; if not, write to the Free Software       
+ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+ // USA
+ 
+ 
+ #include <string>
+ #include <vector>
+ 
+ int string_stuff()
+ {
+    int failures(0);
+ 
+    std::string s("abcde");
+ 
+    std::string::iterator i1(s.begin());
+    if (*i1 != 'a')
+       ++failures;
+ 
+    ++i1;
+    if (*i1 != 'b')
+       ++failures;
+ 
+    i1++;
+    if (*i1 != 'c')
+       ++failures;
+ 
+    ++ ++i1;
+    if (*i1 != 'e')
+       ++failures;
+ 
+    --i1;
+    if (*i1 != 'd')
+       ++failures;
+ 
+    i1--;
+    if (*i1 != 'c')
+       ++failures;
+ 
+    -- --i1;
+    if (*i1 != 'a')
+       ++failures;
+ 
+    std::string::iterator i2;
+    i2 = s.end();
+    std::iterator_traits<std::string::iterator>::difference_type d1;
+    d1 = i2 - i1;
+    if (d1 != 5)
+       ++failures;
+ 
+    std::iterator_traits<std::string::iterator>::value_type v1;
+    v1 = i1[0];
+    if (v1 != 'a')
+       ++failures;
+ 
+    std::iterator_traits<std::string::iterator>::reference r1(i1[0]);
+    if (r1 != 'a')
+       ++failures;
+    r1 = 'x';
+    if (r1 != 'x')
+       ++failures;
+    r1 = 'a';
+ 
+    if ((i1 != i2) != true)
+       ++failures;
+    if ((i1 == i2) != false)
+       ++failures;
+    if ((i1 <  i2) != true)
+       ++failures;
+    if ((i1 >  i2) != false)
+       ++failures;
+    if ((i1 <= i2) != true)
+       ++failures;
+    if ((i1 >= i2) != false)
+       ++failures;
+ 
+    std::string::iterator i3;
+    i3 = i1;
+    if ((i3 == i1) != true)
+       ++failures;
+ 
+    i3 += 5;
+    if ((i3 == i2) != true)
+       ++failures;
+ 
+    i3 -= 5;
+    if ((i3 == i1) != true)
+       ++failures;
+ 
+    if (i3 + 5 != i2)
+       ++failures;
+ 
+    if (5 + i3 != i2)
+       ++failures;
+ 
+    if (i2 - 5 != i3)
+       ++failures;
+ 
+    if (i1[0] != 'a')
+       ++failures;
+ 
+    i1[4] = 'x';
+    if (i2[-1] != 'x')
+       ++failures;
+    i1[4] = 'e';
+ 
+    i1[2] = 'x';
+    if (i2[-3] != 'x')
+       ++failures;
+    i1[2] = 'c';
+ 
+    std::string::const_iterator ci1(s.begin());
+    if (*ci1 != 'a')
+       ++failures;
+ 
+    ++ci1;
+    if (*ci1 != 'b')
+       ++failures;
+ 
+    ci1++;
+    if (*ci1 != 'c')
+       ++failures;
+ 
+    ++ ++ci1;
+    if (*ci1 != 'e')
+       ++failures;
+ 
+    --ci1;
+    if (*ci1 != 'd')
+       ++failures;
+ 
+    ci1--;
+    if (*ci1 != 'c')
+       ++failures;
+ 
+    -- --ci1;
+    if (*ci1 != 'a')
+       ++failures;
+ 
+    std::string::const_iterator ci2;
+    ci2 = s.end();
+    std::iterator_traits<std::string::const_iterator>::difference_type d2;
+    d2 = ci2 - ci1;
+    if (d2 != 5)
+       ++failures;
+ 
+    std::iterator_traits<std::string::const_iterator>::value_type v2;
+    v2 = ci1[0];
+    if (v2 != 'a')
+       ++failures;
+ 
+    std::iterator_traits<std::string::const_iterator>::reference r2(ci1[0]);
+    if (r2 != 'a')
+       ++failures;
+ 
+    if ((ci1 != ci2) != true)
+       ++failures;
+    if ((ci1 == ci2) != false)
+       ++failures;
+    if ((ci1 <  ci2) != true)
+       ++failures;
+    if ((ci1 >  ci2) != false)
+       ++failures;
+    if ((ci1 <= ci2) != true)
+       ++failures;
+    if ((ci1 >= ci2) != false)
+       ++failures;
+ 
+    std::string::const_iterator ci3;
+    ci3 = ci1;
+    if ((ci3 == ci1) != true)
+       ++failures;
+ 
+    ci3 += 5;
+    if ((ci3 == ci2) != true)
+       ++failures;
+ 
+    ci3 -= 5;
+    if ((ci3 == ci1) != true)
+       ++failures;
+ 
+    if (ci3 + 5 != ci2)
+       ++failures;
+ 
+    if (5 + ci3 != ci2)
+       ++failures;
+ 
+    if (ci2 - 5 != ci3)
+       ++failures;
+ 
+    if (ci1[2] != 'c')
+       ++failures;
+ 
+    if (ci2[-1] != 'e')
+       ++failures;
+ 
+    // iterator and const_iterator
+    std::string::const_iterator ci4(i1);
+    if ((ci4 == i1) != true)
+       ++failures;
+    if ((ci4 != i1) != false)
+       ++failures;
+    if ((ci4 < i1)  != false)
+      ++failures;
+    if ((ci4 > i1)  != false)
+      ++failures;
+    if ((ci4 <= i1) != true)
+      ++failures;
+    if ((ci4 >= i1) != true)
+      ++failures;
+    ci4 = i2;
+    if ((i2 == ci4) != true)
+      ++failures;
+    if ((i2 < ci4)  != false)
+      ++failures;
+    if ((i2 > ci4)  != false)
+      ++failures;
+    if ((i2 <= ci4) != true)
+      ++failures;
+    if ((i2 >= ci4) != true)
+      ++failures;
+ 
+    const std::string cs("ABCDE");
+    std::string::const_iterator ci5(cs.begin());
+    if (ci5[0] != 'A')
+       ++failures;
+ 
+    return failures;
+ }
+ 
+ int vector_stuff()
+ {
+    int failures(0);
+ 
+    std::vector<int> v;
+    v.push_back(int(1));
+    v.push_back(int(2));
+    v.push_back(int(3));
+    v.push_back(int(4));
+    v.push_back(int(5));
+ 
+    std::vector<int>::iterator i1(v.begin());
+    if (*i1 != 1)
+       ++failures;
+ 
+    ++i1;
+    if (*i1 != 2)
+       ++failures;
+ 
+    i1++;
+    if (*i1 != 3)
+       ++failures;
+ 
+    ++ ++i1;
+    if (*i1 != 5)
+       ++failures;
+ 
+    --i1;
+    if (*i1 != 4)
+       ++failures;
+ 
+    i1--;
+    if (*i1 != 3)
+       ++failures;
+ 
+    -- --i1;
+    if (*i1 != 1)
+       ++failures;
+ 
+    std::vector<int>::iterator i2;
+    i2 = v.end();
+    std::iterator_traits<std::vector<int>::iterator>::difference_type d1;
+    d1 = i2 - i1;
+    if (d1 != 5)
+       ++failures;
+ 
+    std::iterator_traits<std::vector<int>::iterator>::value_type v1;
+    v1 = i1[0];
+    if (v1 != 1)
+       ++failures;
+ 
+    std::iterator_traits<std::vector<int>::iterator>::reference r1(i1[0]);
+    if (r1 != 1)
+       ++failures;
+    r1 = 9;
+    if (r1 != 9)
+       ++failures;
+    r1 = 1;
+ 
+    if ((i1 != i2) != true)
+       ++failures;
+    if ((i1 == i2) != false)
+       ++failures;
+    if ((i1 <  i2) != true)
+       ++failures;
+    if ((i1 >  i2) != false)
+       ++failures;
+    if ((i1 <= i2) != true)
+       ++failures;
+    if ((i1 >= i2) != false)
+       ++failures;
+ 
+    std::vector<int>::iterator i3;
+    i3 = i1;
+    if ((i3 == i1) != true)
+       ++failures;
+ 
+    i3 += 5;
+    if ((i3 == i2) != true)
+       ++failures;
+ 
+    i3 -= 5;
+    if ((i3 == i1) != true)
+       ++failures;
+ 
+    if (i3 + 5 != i2)
+       ++failures;
+ 
+    if (5 + i3 != i2)
+       ++failures;
+ 
+    if (i2 - 5 != i3)
+       ++failures;
+ 
+    if (i1[0] != 1)
+       ++failures;
+ 
+    i1[4] = 9;
+    if (i2[-1] != 9)
+       ++failures;
+    i1[4] = 5;
+ 
+    i1[2] = 9;
+    if (i2[-3] != 9)
+       ++failures;
+    i1[2] = 3;
+ 
+    std::vector<int>::const_iterator ci1(v.begin());
+    if (*ci1 != 1)
+       ++failures;
+ 
+    ++ci1;
+    if (*ci1 != 2)
+       ++failures;
+ 
+    ci1++;
+    if (*ci1 != 3)
+       ++failures;
+ 
+    ++ ++ci1;
+    if (*ci1 != 5)
+       ++failures;
+ 
+    --ci1;
+    if (*ci1 != 4)
+       ++failures;
+ 
+    ci1--;
+    if (*ci1 != 3)
+       ++failures;
+ 
+    -- --ci1;
+    if (*ci1 != 1)
+       ++failures;
+ 
+    std::vector<int>::const_iterator ci2;
+    ci2 = v.end();
+    std::iterator_traits<std::vector<int>::const_iterator>::difference_type d2;
+    d2 = ci2 - ci1;
+    if (d2 != 5)
+       ++failures;
+ 
+    std::iterator_traits<std::vector<int>::const_iterator>::value_type v2;
+    v2 = ci1[0];
+    if (v2 != 1)
+       ++failures;
+ 
+    std::iterator_traits<std::vector<int>::const_iterator>::reference
+       r2(ci1[0]);
+    if (r2 != 1)
+       ++failures;
+ 
+    if ((ci1 != ci2) != true)
+       ++failures;
+    if ((ci1 == ci2) != false)
+       ++failures;
+    if ((ci1 <  ci2) != true)
+       ++failures;
+    if ((ci1 >  ci2) != false)
+       ++failures;
+    if ((ci1 <= ci2) != true)
+       ++failures;
+    if ((ci1 >= ci2) != false)
+       ++failures;
+ 
+    std::vector<int>::const_iterator ci3;
+    ci3 = ci1;
+    if ((ci3 == ci1) != true)
+       ++failures;
+ 
+    ci3 += 5;
+    if ((ci3 == ci2) != true)
+       ++failures;
+ 
+    ci3 -= 5;
+    if ((ci3 == ci1) != true)
+       ++failures;
+ 
+    if (ci3 + 5 != ci2)
+       ++failures;
+ 
+    if (5 + ci3 != ci2)
+       ++failures;
+ 
+    if (ci2 - 5 != ci3)
+       ++failures;
+ 
+    if (ci1[2] != 3)
+       ++failures;
+ 
+    if (ci2[-1] != 5)
+       ++failures;
+ 
+    // iterator to const_iterator
+    std::vector<int>::const_iterator ci4(i1);
+    if ((ci4 == i1) != true)
+       ++failures;
+    if ((ci4 != i1) != false)
+       ++failures;
+    if ((ci4 < i1)  != false)
+      ++failures;
+    if ((ci4 > i1)  != false)
+      ++failures;
+    if ((ci4 <= i1) != true)
+      ++failures;
+    if ((ci4 >= i1) != true)
+      ++failures;
+    ci4 = i2;
+    if ((i2 == ci4) != true)
+      ++failures;
+    if ((i2 < ci4)  != false)
+      ++failures;
+    if ((i2 > ci4)  != false)
+      ++failures;
+    if ((i2 <= ci4) != true)
+      ++failures;
+    if ((i2 >= ci4) != true)
+      ++failures;
+ 
+    const std::vector<int> cv(v);
+    std::vector<int>::const_iterator ci5(cv.begin());
+    if (ci5[0] != 1)
+       ++failures;
+ 
+    std::vector<std::string> vs;
+    vs.push_back(string("abc"));
+    std::vector<std::string>::iterator ivs(vs.begin());
+    if (ivs->c_str()[1] != 'b')
+       ++failures;
+ 
+    return failures;
+ }
+ 
+ int reverse_stuff()
+ {
+    int failures(0);
+ 
+    std::string s("abcde");
+ 
+    std::string::reverse_iterator ri(s.rbegin());
+    if (*ri != 'e')
+       ++failures;
+ 
+    std::iterator_traits<std::string::reverse_iterator>::difference_type d;
+    d = s.rend() - ri;
+    if (d != 5)
+       ++failures;
+ 
+    const std::string cs("abcde");
+    std::string::const_reverse_iterator cri(cs.rend());
+    if (cri - 5 != cs.rbegin())
+       ++failures;
+ 
+    return failures;
+ }
+ 
+ // the following should be compiler errors
+ // flag runtime errors in case they slip through the compiler
+ int wrong_stuff()
+ {
+    int failures(0);
+ 
+ #ifdef ITER24_F1
+    extern void f(std::vector<string*>::iterator);
+    vector<string*> vs[2];
+    f(vs);                       // address of array is not an iterator
+    failures++;
+ #endif
+ 
+ #ifdef ITER24_F2
+    string s;
+    char *i = s.begin();         // begin() doesn't return a pointer
+    failures++;
+ #endif
+ 
+ #ifdef ITER24_F3
+    std::string::const_iterator ci;
+    std::string::iterator i;
+    if (i - ci)                  // remove const_ is a warning
+       i++;
+    // failures++;  only a warning
+ #endif
+ 
+ #ifdef ITER24_F4
+    std::vector<char>::iterator iv;
+    std::string::iterator is(iv);// vector<char> is not string
+    failures++;
+ #endif
+ 
+ #ifdef ITER24_F5
+    std::vector<char>::iterator iv;
+    std::string::iterator is;
+    if (iv == is)                // vector<char> is not string
+       ++iv;
+    failures++;
+ #endif
+ 
+ #ifdef ITER24_F6
+    std::vector<char>::const_iterator ci;
+    std::vector<char>::iterator i = ci;  // remove const_ is a warning
+    ++i;
+    // failures++; only a warning
+ #endif
+ 
+ #ifdef ITER24_F7
+    std::vector<int> v(1);
+    std::vector<int>::const_iterator ci(v.begin());
+    *ci = 1;                     // cannot assign through const_iterator
+    failures++;
+ #endif
+ 
+ #ifdef ITER24_F8
+    std::vector<const int> v(1);
+    std::vector<const int>::reference r(v.begin()[0]);
+    r = 1;                       // cannot assign through reference to const
+    failures++;
+ #endif
+ 
+    return failures;
+ }
+ 
+ int main(int argc,
+          char **argv)
+ {
+    int failures(0);
+ 
+    failures += string_stuff();
+ 
+    failures += vector_stuff();
+ 
+    failures += reverse_stuff();
+ 
+    failures += wrong_stuff();
+ 
+    return failures ? 1 : 0;
+ }



More information about the Libstdc++ mailing list