OSDN Git Service

2002-08-09 Phil Edwards <pme@gcc.gnu.org>
authorpme <pme@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Aug 2002 16:51:15 +0000 (16:51 +0000)
committerpme <pme@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Aug 2002 16:51:15 +0000 (16:51 +0000)
* include/bits/deque.tcc, include/bits/list.tcc,
include/bits/stl_deque.h, include/bits/stl_iterator_base_funcs.h,
include/bits/stl_list.h, include/bits/stl_map.h,
include/bits/stl_multimap.h, include/bits/stl_queue.h,
include/bits/stl_stack.h, include/bits/stl_vector.h,
include/bits/vector.tcc:  Re-indent contents of namespace std,
re-wrap comment lines as necessary.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@56165 138bc75d-0d04-0410-961f-82ee72b054a4

12 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/deque.tcc
libstdc++-v3/include/bits/list.tcc
libstdc++-v3/include/bits/stl_deque.h
libstdc++-v3/include/bits/stl_iterator_base_funcs.h
libstdc++-v3/include/bits/stl_list.h
libstdc++-v3/include/bits/stl_map.h
libstdc++-v3/include/bits/stl_multimap.h
libstdc++-v3/include/bits/stl_queue.h
libstdc++-v3/include/bits/stl_stack.h
libstdc++-v3/include/bits/stl_vector.h
libstdc++-v3/include/bits/vector.tcc

index 5d19ef5..e6e0278 100644 (file)
@@ -1,3 +1,13 @@
+2002-08-09  Phil Edwards  <pme@gcc.gnu.org>
+
+       * include/bits/deque.tcc, include/bits/list.tcc,
+       include/bits/stl_deque.h, include/bits/stl_iterator_base_funcs.h,
+       include/bits/stl_list.h, include/bits/stl_map.h,
+       include/bits/stl_multimap.h, include/bits/stl_queue.h,
+       include/bits/stl_stack.h, include/bits/stl_vector.h,
+       include/bits/vector.tcc:  Re-indent contents of namespace std,
+       re-wrap comment lines as necessary.
+
 2002-08-08  Danny Smith  <dannysmith@users.sourceforge.net>
             Benjamin Kosnik  <bkoz@redhat.com>
        
index 31711ba..a8d43d0 100644 (file)
 #ifndef __GLIBCPP_INTERNAL_DEQUE_TCC
 #define __GLIBCPP_INTERNAL_DEQUE_TCC
 
-// Since this entire file is within namespace std, there's no reason to
-// waste two spaces along the left column.  Thus the leading indentation is
-// slightly violated from here on.
 namespace std
 { 
-
-template <typename _Tp, typename _Alloc>
-  deque<_Tp,_Alloc>&
-  deque<_Tp,_Alloc>::
-  operator=(const deque& __x)
-  {
-    const size_type __len = size();
-    if (&__x != this)
+  template <typename _Tp, typename _Alloc>
+    deque<_Tp,_Alloc>&
+    deque<_Tp,_Alloc>::
+    operator=(const deque& __x)
     {
-      if (__len >= __x.size())
-        erase(copy(__x.begin(), __x.end(), _M_start), _M_finish);
-      else
+      const size_type __len = size();
+      if (&__x != this)
       {
-        const_iterator __mid = __x.begin() + difference_type(__len);
-        copy(__x.begin(), __mid, _M_start);
-        insert(_M_finish, __mid, __x.end());
+        if (__len >= __x.size())
+          erase(copy(__x.begin(), __x.end(), _M_start), _M_finish);
+        else
+        {
+          const_iterator __mid = __x.begin() + difference_type(__len);
+          copy(__x.begin(), __mid, _M_start);
+          insert(_M_finish, __mid, __x.end());
+        }
       }
-    }
-    return *this;
-  }        
-
-template <typename _Tp, typename _Alloc>
-  typename deque<_Tp,_Alloc>::iterator 
-  deque<_Tp,_Alloc>::
-  insert(iterator position, const value_type& __x)
-  {
-    if (position._M_cur == _M_start._M_cur)
-    {
-      push_front(__x);
-      return _M_start;
-    }
-    else if (position._M_cur == _M_finish._M_cur)
-    {
-      push_back(__x);
-      iterator __tmp = _M_finish;
-      --__tmp;
-      return __tmp;
-    }
-    else
-      return _M_insert_aux(position, __x);
-  }
-
-template <typename _Tp, typename _Alloc>
-  typename deque<_Tp,_Alloc>::iterator 
-  deque<_Tp,_Alloc>::
-  erase(iterator __position)
-  {
-    iterator __next = __position;
-    ++__next;
-    size_type __index = __position - _M_start;
-    if (__index < (size() >> 1))
-    {
-      copy_backward(_M_start, __position, __next);
-      pop_front();
-    }
-    else
-    {
-      copy(__next, _M_finish, __position);
-      pop_back();
-    }
-    return _M_start + __index;
-  }
-
-template <typename _Tp, typename _Alloc>
-  typename deque<_Tp,_Alloc>::iterator 
-  deque<_Tp,_Alloc>::
-  erase(iterator __first, iterator __last)
-  {
-    if (__first == _M_start && __last == _M_finish)
-    {
-      clear();
-      return _M_finish;
-    }
-    else
+      return *this;
+    }        
+  
+  template <typename _Tp, typename _Alloc>
+    typename deque<_Tp,_Alloc>::iterator 
+    deque<_Tp,_Alloc>::
+    insert(iterator position, const value_type& __x)
     {
-      difference_type __n = __last - __first;
-      difference_type __elems_before = __first - _M_start;
-      if (static_cast<size_type>(__elems_before) < (size() - __n) / 2)
+      if (position._M_cur == _M_start._M_cur)
       {
-        copy_backward(_M_start, __first, __last);
-        iterator __new_start = _M_start + __n;
-        _Destroy(_M_start, __new_start);
-        _M_destroy_nodes(_M_start._M_node, __new_start._M_node);
-        _M_start = __new_start;
+        push_front(__x);
+        return _M_start;
       }
-      else
+      else if (position._M_cur == _M_finish._M_cur)
       {
-        copy(__last, _M_finish, __first);
-        iterator __new_finish = _M_finish - __n;
-        _Destroy(__new_finish, _M_finish);
-        _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1);
-        _M_finish = __new_finish;
+        push_back(__x);
+        iterator __tmp = _M_finish;
+        --__tmp;
+        return __tmp;
       }
-      return _M_start + __elems_before;
-    }
-  }
-  
-template <typename _Tp, typename _Alloc> 
-  void
-  deque<_Tp,_Alloc>::
-  clear()
-  {
-    for (_Map_pointer __node = _M_start._M_node + 1;
-         __node < _M_finish._M_node;
-         ++__node)
-    {
-      _Destroy(*__node, *__node + _S_buffer_size());
-      _M_deallocate_node(*__node);
-    }
-  
-    if (_M_start._M_node != _M_finish._M_node)
-    {
-      _Destroy(_M_start._M_cur, _M_start._M_last);
-      _Destroy(_M_finish._M_first, _M_finish._M_cur);
-      _M_deallocate_node(_M_finish._M_first);
-    }
-    else
-      _Destroy(_M_start._M_cur, _M_finish._M_cur);
-  
-    _M_finish = _M_start;
-  }
-  
-template <typename _Tp, class _Alloc>
-  template <typename _InputIter>
-    void
-    deque<_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)
-        erase(__cur, end());
       else
-        insert(end(), __first, __last);
+        return _M_insert_aux(position, __x);
     }
   
-template <typename _Tp, typename _Alloc>
-  void
-  deque<_Tp,_Alloc>::
-  _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
-  {
-    if (__pos._M_cur == _M_start._M_cur)
-    {
-      iterator __new_start = _M_reserve_elements_at_front(__n);
-      try
-        {
-          uninitialized_fill(__new_start, _M_start, __x);
-          _M_start = __new_start;
-        }
-      catch(...)
-        {
-          _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
-          __throw_exception_again;
-        }
-    }
-    else if (__pos._M_cur == _M_finish._M_cur)
+  template <typename _Tp, typename _Alloc>
+    typename deque<_Tp,_Alloc>::iterator 
+    deque<_Tp,_Alloc>::
+    erase(iterator __position)
     {
-      iterator __new_finish = _M_reserve_elements_at_back(__n);
-      try
-        {
-          uninitialized_fill(_M_finish, __new_finish, __x);
-          _M_finish = __new_finish;
-        }
-      catch(...)
-        {
-          _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);    
-          __throw_exception_again;
-        }
-    }
-    else 
-      _M_insert_aux(__pos, __n, __x);
-  }
-  
-template <typename _Tp, typename _Alloc>
-  void
-  deque<_Tp,_Alloc>::
-  _M_fill_initialize(const value_type& __value)
-  {
-    _Map_pointer __cur;
-    try
+      iterator __next = __position;
+      ++__next;
+      size_type __index = __position - _M_start;
+      if (__index < (size() >> 1))
       {
-        for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur)
-          uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value);
-        uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value);
+        copy_backward(_M_start, __position, __next);
+        pop_front();
       }
-    catch(...)
+      else
       {
-        _Destroy(_M_start, iterator(*__cur, __cur));
-        __throw_exception_again;
+        copy(__next, _M_finish, __position);
+        pop_back();
       }
-  }
+      return _M_start + __index;
+    }
   
-template <typename _Tp, typename _Alloc>
-  template <typename _InputIterator>
-    void
+  template <typename _Tp, typename _Alloc>
+    typename deque<_Tp,_Alloc>::iterator 
     deque<_Tp,_Alloc>::
-    _M_range_initialize(_InputIterator __first, _InputIterator __last,
-                        input_iterator_tag)
+    erase(iterator __first, iterator __last)
     {
-      _M_initialize_map(0);
-      try
+      if (__first == _M_start && __last == _M_finish)
+      {
+        clear();
+        return _M_finish;
+      }
+      else
+      {
+        difference_type __n = __last - __first;
+        difference_type __elems_before = __first - _M_start;
+        if (static_cast<size_type>(__elems_before) < (size() - __n) / 2)
         {
-          for ( ; __first != __last; ++__first)
-            push_back(*__first);
+          copy_backward(_M_start, __first, __last);
+          iterator __new_start = _M_start + __n;
+          _Destroy(_M_start, __new_start);
+          _M_destroy_nodes(_M_start._M_node, __new_start._M_node);
+          _M_start = __new_start;
         }
-      catch(...)
+        else
         {
-          clear();
-          __throw_exception_again;
+          copy(__last, _M_finish, __first);
+          iterator __new_finish = _M_finish - __n;
+          _Destroy(__new_finish, _M_finish);
+          _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1);
+          _M_finish = __new_finish;
         }
+        return _M_start + __elems_before;
+      }
     }
-  
-template <typename _Tp, typename _Alloc>
-  template <typename _ForwardIterator>
+    
+  template <typename _Tp, typename _Alloc> 
     void
     deque<_Tp,_Alloc>::
-    _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
-                        forward_iterator_tag)
+    clear()
     {
-      size_type __n = distance(__first, __last);
-      _M_initialize_map(__n);
-    
-      _Map_pointer __cur_node;
-      try
-        {
-          for (__cur_node = _M_start._M_node; 
-               __cur_node < _M_finish._M_node; 
-               ++__cur_node)
-          {
-            _ForwardIterator __mid = __first;
-            advance(__mid, _S_buffer_size());
-            uninitialized_copy(__first, __mid, *__cur_node);
-            __first = __mid;
-          }
-          uninitialized_copy(__first, __last, _M_finish._M_first);
-        }
-      catch(...)
-        {
-          _Destroy(_M_start, iterator(*__cur_node, __cur_node));
-          __throw_exception_again;
-        }
-    }
-  
-// Called only if _M_finish._M_cur == _M_finish._M_last - 1.
-template <typename _Tp, typename _Alloc>
-  void
-  deque<_Tp,_Alloc>::
-  _M_push_back_aux(const value_type& __t)
-  {
-    value_type __t_copy = __t;
-    _M_reserve_map_at_back();
-    *(_M_finish._M_node + 1) = _M_allocate_node();
-    try
-      {
-        _Construct(_M_finish._M_cur, __t_copy);
-        _M_finish._M_set_node(_M_finish._M_node + 1);
-        _M_finish._M_cur = _M_finish._M_first;
-      }
-    catch(...)
+      for (_Map_pointer __node = _M_start._M_node + 1;
+           __node < _M_finish._M_node;
+           ++__node)
       {
-        _M_deallocate_node(*(_M_finish._M_node + 1));
-        __throw_exception_again;
+        _Destroy(*__node, *__node + _S_buffer_size());
+        _M_deallocate_node(*__node);
       }
-  }
-  
-#ifdef _GLIBCPP_DEPRECATED
-// Called only if _M_finish._M_cur == _M_finish._M_last - 1.
-template <typename _Tp, typename _Alloc>
-  void
-  deque<_Tp,_Alloc>::
-  _M_push_back_aux()
-  {
-    _M_reserve_map_at_back();
-    *(_M_finish._M_node + 1) = _M_allocate_node();
-    try
-      {
-        _Construct(_M_finish._M_cur);
-        _M_finish._M_set_node(_M_finish._M_node + 1);
-        _M_finish._M_cur = _M_finish._M_first;
-      }
-    catch(...)
-      {
-        _M_deallocate_node(*(_M_finish._M_node + 1));
-        __throw_exception_again;
-      }
-  }
-#endif
-  
-// Called only if _M_start._M_cur == _M_start._M_first.
-template <typename _Tp, typename _Alloc>
-  void
-  deque<_Tp,_Alloc>::
-  _M_push_front_aux(const value_type& __t)
-  {
-    value_type __t_copy = __t;
-    _M_reserve_map_at_front();
-    *(_M_start._M_node - 1) = _M_allocate_node();
-    try
-      {
-        _M_start._M_set_node(_M_start._M_node - 1);
-        _M_start._M_cur = _M_start._M_last - 1;
-        _Construct(_M_start._M_cur, __t_copy);
-      }
-    catch(...)
-      {
-        ++_M_start;
-        _M_deallocate_node(*(_M_start._M_node - 1));
-        __throw_exception_again;
-      }
-  } 
-  
-#ifdef _GLIBCPP_DEPRECATED
-// Called only if _M_start._M_cur == _M_start._M_first.
-template <typename _Tp, typename _Alloc>
-  void
-  deque<_Tp,_Alloc>::
-  _M_push_front_aux()
-  {
-    _M_reserve_map_at_front();
-    *(_M_start._M_node - 1) = _M_allocate_node();
-    try
+    
+      if (_M_start._M_node != _M_finish._M_node)
       {
-        _M_start._M_set_node(_M_start._M_node - 1);
-        _M_start._M_cur = _M_start._M_last - 1;
-        _Construct(_M_start._M_cur);
+        _Destroy(_M_start._M_cur, _M_start._M_last);
+        _Destroy(_M_finish._M_first, _M_finish._M_cur);
+        _M_deallocate_node(_M_finish._M_first);
       }
-    catch(...)
+      else
+        _Destroy(_M_start._M_cur, _M_finish._M_cur);
+    
+      _M_finish = _M_start;
+    }
+    
+  template <typename _Tp, class _Alloc>
+    template <typename _InputIter>
+      void
+      deque<_Tp,_Alloc>
+      ::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag)
       {
-        ++_M_start;
-        _M_deallocate_node(*(_M_start._M_node - 1));
-        __throw_exception_again;
+        iterator __cur = begin();
+        for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
+          *__cur = *__first;
+        if (__first == __last)
+          erase(__cur, end());
+        else
+          insert(end(), __first, __last);
       }
-  } 
-#endif
-  
-// Called only if _M_finish._M_cur == _M_finish._M_first.
-template <typename _Tp, typename _Alloc>
-  void deque<_Tp,_Alloc>::
-  _M_pop_back_aux()
-  {
-    _M_deallocate_node(_M_finish._M_first);
-    _M_finish._M_set_node(_M_finish._M_node - 1);
-    _M_finish._M_cur = _M_finish._M_last - 1;
-    _Destroy(_M_finish._M_cur);
-  }
-  
-// Called only if _M_start._M_cur == _M_start._M_last - 1.  Note that 
-// if the deque has at least one element (a precondition for this member 
-// function), and if _M_start._M_cur == _M_start._M_last, then the deque 
-// must have at least two nodes.
-template <typename _Tp, typename _Alloc>
-  void deque<_Tp,_Alloc>::
-  _M_pop_front_aux()
-  {
-    _Destroy(_M_start._M_cur);
-    _M_deallocate_node(_M_start._M_first);
-    _M_start._M_set_node(_M_start._M_node + 1);
-    _M_start._M_cur = _M_start._M_first;
-  }      
-  
-template <typename _Tp, typename _Alloc>
-  template <typename _InputIterator>
-    void
-    deque<_Tp,_Alloc>::
-    _M_range_insert_aux(iterator __pos,
-                        _InputIterator __first, _InputIterator __last,
-                        input_iterator_tag)
-    {
-      copy(__first, __last, inserter(*this, __pos));
-    }
-  
-template <typename _Tp, typename _Alloc>
-  template <typename _ForwardIterator>
+    
+  template <typename _Tp, typename _Alloc>
     void
     deque<_Tp,_Alloc>::
-    _M_range_insert_aux(iterator __pos,
-                        _ForwardIterator __first, _ForwardIterator __last,
-                        forward_iterator_tag)
+    _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
     {
-      size_type __n = distance(__first, __last);
       if (__pos._M_cur == _M_start._M_cur)
       {
         iterator __new_start = _M_reserve_elements_at_front(__n);
         try
           {
-            uninitialized_copy(__first, __last, __new_start);
+            uninitialized_fill(__new_start, _M_start, __x);
             _M_start = __new_start;
           }
         catch(...)
@@ -466,197 +223,362 @@ template <typename _Tp, typename _Alloc>
         iterator __new_finish = _M_reserve_elements_at_back(__n);
         try
           {
-            uninitialized_copy(__first, __last, _M_finish);
+            uninitialized_fill(_M_finish, __new_finish, __x);
             _M_finish = __new_finish;
           }
         catch(...)
           {
-            _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);
+            _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);    
             __throw_exception_again;
           }
       }
-      else
-        _M_insert_aux(__pos, __first, __last, __n);
-    }
-  
-template <typename _Tp, typename _Alloc>
-  typename deque<_Tp, _Alloc>::iterator
-  deque<_Tp,_Alloc>::
-  _M_insert_aux(iterator __pos, const value_type& __x)
-  {
-    difference_type __index = __pos - _M_start;
-    value_type __x_copy = __x; // XXX copy
-    if (static_cast<size_type>(__index) < size() / 2)
-    {
-      push_front(front());
-      iterator __front1 = _M_start;
-      ++__front1;
-      iterator __front2 = __front1;
-      ++__front2;
-      __pos = _M_start + __index;
-      iterator __pos1 = __pos;
-      ++__pos1;
-      copy(__front2, __pos1, __front1);
+      else 
+        _M_insert_aux(__pos, __n, __x);
     }
-    else
+    
+  template <typename _Tp, typename _Alloc>
+    void
+    deque<_Tp,_Alloc>::
+    _M_fill_initialize(const value_type& __value)
     {
-      push_back(back());
-      iterator __back1 = _M_finish;
-      --__back1;
-      iterator __back2 = __back1;
-      --__back2;
-      __pos = _M_start + __index;
-      copy_backward(__pos, __back2, __back1);
+      _Map_pointer __cur;
+      try
+        {
+          for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur)
+            uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value);
+          uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value);
+        }
+      catch(...)
+        {
+          _Destroy(_M_start, iterator(*__cur, __cur));
+          __throw_exception_again;
+        }
     }
-    *__pos = __x_copy;
-    return __pos;
-  }
-  
-#ifdef _GLIBCPP_DEPRECATED
-// Nothing seems to actually use this.  According to the pattern followed by
-// the rest of the SGI code, it would be called by the deprecated insert(pos)
-// function, but that has been replaced.  We'll take our time removing this
-// anyhow; mark for 3.4.  -pme
-template <typename _Tp, typename _Alloc>
-  typename deque<_Tp,_Alloc>::iterator 
-  deque<_Tp,_Alloc>::
-  _M_insert_aux(iterator __pos)
-  {
-    difference_type __index = __pos - _M_start;
-    if (static_cast<size_type>(__index) < size() / 2)
+    
+  template <typename _Tp, typename _Alloc>
+    template <typename _InputIterator>
+      void
+      deque<_Tp,_Alloc>::
+      _M_range_initialize(_InputIterator __first, _InputIterator __last,
+                          input_iterator_tag)
+      {
+        _M_initialize_map(0);
+        try
+          {
+            for ( ; __first != __last; ++__first)
+              push_back(*__first);
+          }
+        catch(...)
+          {
+            clear();
+            __throw_exception_again;
+          }
+      }
+    
+  template <typename _Tp, typename _Alloc>
+    template <typename _ForwardIterator>
+      void
+      deque<_Tp,_Alloc>::
+      _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
+                          forward_iterator_tag)
+      {
+        size_type __n = distance(__first, __last);
+        _M_initialize_map(__n);
+      
+        _Map_pointer __cur_node;
+        try
+          {
+            for (__cur_node = _M_start._M_node; 
+                 __cur_node < _M_finish._M_node; 
+                 ++__cur_node)
+            {
+              _ForwardIterator __mid = __first;
+              advance(__mid, _S_buffer_size());
+              uninitialized_copy(__first, __mid, *__cur_node);
+              __first = __mid;
+            }
+            uninitialized_copy(__first, __last, _M_finish._M_first);
+          }
+        catch(...)
+          {
+            _Destroy(_M_start, iterator(*__cur_node, __cur_node));
+            __throw_exception_again;
+          }
+      }
+    
+  // Called only if _M_finish._M_cur == _M_finish._M_last - 1.
+  template <typename _Tp, typename _Alloc>
+    void
+    deque<_Tp,_Alloc>::
+    _M_push_back_aux(const value_type& __t)
     {
-      push_front(front());
-      iterator __front1 = _M_start;
-      ++__front1;
-      iterator __front2 = __front1;
-      ++__front2;
-      __pos = _M_start + __index;
-      iterator __pos1 = __pos;
-      ++__pos1;
-      copy(__front2, __pos1, __front1);
+      value_type __t_copy = __t;
+      _M_reserve_map_at_back();
+      *(_M_finish._M_node + 1) = _M_allocate_node();
+      try
+        {
+          _Construct(_M_finish._M_cur, __t_copy);
+          _M_finish._M_set_node(_M_finish._M_node + 1);
+          _M_finish._M_cur = _M_finish._M_first;
+        }
+      catch(...)
+        {
+          _M_deallocate_node(*(_M_finish._M_node + 1));
+          __throw_exception_again;
+        }
     }
-    else
+    
+  #ifdef _GLIBCPP_DEPRECATED
+  // Called only if _M_finish._M_cur == _M_finish._M_last - 1.
+  template <typename _Tp, typename _Alloc>
+    void
+    deque<_Tp,_Alloc>::
+    _M_push_back_aux()
     {
-      push_back(back());
-      iterator __back1 = _M_finish;
-      --__back1;
-      iterator __back2 = __back1;
-      --__back2;
-      __pos = _M_start + __index;
-      copy_backward(__pos, __back2, __back1);
+      _M_reserve_map_at_back();
+      *(_M_finish._M_node + 1) = _M_allocate_node();
+      try
+        {
+          _Construct(_M_finish._M_cur);
+          _M_finish._M_set_node(_M_finish._M_node + 1);
+          _M_finish._M_cur = _M_finish._M_first;
+        }
+      catch(...)
+        {
+          _M_deallocate_node(*(_M_finish._M_node + 1));
+          __throw_exception_again;
+        }
     }
-    *__pos = value_type();
-    return __pos;
-  }
-#endif
-  
-template <typename _Tp, typename _Alloc>
-  void
-  deque<_Tp,_Alloc>::
-  _M_insert_aux(iterator __pos, size_type __n, const value_type& __x)
-  {
-    const difference_type __elems_before = __pos - _M_start;
-    size_type __length = this->size();
-    value_type __x_copy = __x;
-    if (__elems_before < difference_type(__length / 2))
+  #endif
+    
+  // Called only if _M_start._M_cur == _M_start._M_first.
+  template <typename _Tp, typename _Alloc>
+    void
+    deque<_Tp,_Alloc>::
+    _M_push_front_aux(const value_type& __t)
     {
-      iterator __new_start = _M_reserve_elements_at_front(__n);
-      iterator __old_start = _M_start;
-      __pos = _M_start + __elems_before;
+      value_type __t_copy = __t;
+      _M_reserve_map_at_front();
+      *(_M_start._M_node - 1) = _M_allocate_node();
       try
         {
-          if (__elems_before >= difference_type(__n))
-          {
-            iterator __start_n = _M_start + difference_type(__n);
-            uninitialized_copy(_M_start, __start_n, __new_start);
-            _M_start = __new_start;
-            copy(__start_n, __pos, __old_start);
-            fill(__pos - difference_type(__n), __pos, __x_copy);
-          }
-          else
-          {
-            __uninitialized_copy_fill(_M_start, __pos, __new_start, 
-                                      _M_start, __x_copy);
-            _M_start = __new_start;
-            fill(__old_start, __pos, __x_copy);
-          }
+          _M_start._M_set_node(_M_start._M_node - 1);
+          _M_start._M_cur = _M_start._M_last - 1;
+          _Construct(_M_start._M_cur, __t_copy);
         }
       catch(...)
-        { 
-          _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
+        {
+          ++_M_start;
+          _M_deallocate_node(*(_M_start._M_node - 1));
           __throw_exception_again;
         }
-    }
-    else
+    } 
+    
+  #ifdef _GLIBCPP_DEPRECATED
+  // Called only if _M_start._M_cur == _M_start._M_first.
+  template <typename _Tp, typename _Alloc>
+    void
+    deque<_Tp,_Alloc>::
+    _M_push_front_aux()
     {
-      iterator __new_finish = _M_reserve_elements_at_back(__n);
-      iterator __old_finish = _M_finish;
-      const difference_type __elems_after = 
-        difference_type(__length) - __elems_before;
-      __pos = _M_finish - __elems_after;
+      _M_reserve_map_at_front();
+      *(_M_start._M_node - 1) = _M_allocate_node();
       try
         {
-          if (__elems_after > difference_type(__n))
-          {
-            iterator __finish_n = _M_finish - difference_type(__n);
-            uninitialized_copy(__finish_n, _M_finish, _M_finish);
-            _M_finish = __new_finish;
-            copy_backward(__pos, __finish_n, __old_finish);
-            fill(__pos, __pos + difference_type(__n), __x_copy);
-          }
-          else
-          {
-            __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n),
-                                      __x_copy, __pos, _M_finish);
-            _M_finish = __new_finish;
-            fill(__pos, __old_finish, __x_copy);
-          }
+          _M_start._M_set_node(_M_start._M_node - 1);
+          _M_start._M_cur = _M_start._M_last - 1;
+          _Construct(_M_start._M_cur);
         }
       catch(...)
-        { 
-          _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);
+        {
+          ++_M_start;
+          _M_deallocate_node(*(_M_start._M_node - 1));
           __throw_exception_again;
         }
+    } 
+  #endif
+    
+  // Called only if _M_finish._M_cur == _M_finish._M_first.
+  template <typename _Tp, typename _Alloc>
+    void deque<_Tp,_Alloc>::
+    _M_pop_back_aux()
+    {
+      _M_deallocate_node(_M_finish._M_first);
+      _M_finish._M_set_node(_M_finish._M_node - 1);
+      _M_finish._M_cur = _M_finish._M_last - 1;
+      _Destroy(_M_finish._M_cur);
     }
-  }
-  
-template <typename _Tp, typename _Alloc>
-  template <typename _ForwardIterator>
+    
+  // Called only if _M_start._M_cur == _M_start._M_last - 1.  Note that 
+  // if the deque has at least one element (a precondition for this member 
+  // function), and if _M_start._M_cur == _M_start._M_last, then the deque 
+  // must have at least two nodes.
+  template <typename _Tp, typename _Alloc>
+    void deque<_Tp,_Alloc>::
+    _M_pop_front_aux()
+    {
+      _Destroy(_M_start._M_cur);
+      _M_deallocate_node(_M_start._M_first);
+      _M_start._M_set_node(_M_start._M_node + 1);
+      _M_start._M_cur = _M_start._M_first;
+    }      
+    
+  template <typename _Tp, typename _Alloc>
+    template <typename _InputIterator>
+      void
+      deque<_Tp,_Alloc>::
+      _M_range_insert_aux(iterator __pos,
+                          _InputIterator __first, _InputIterator __last,
+                          input_iterator_tag)
+      {
+        copy(__first, __last, inserter(*this, __pos));
+      }
+    
+  template <typename _Tp, typename _Alloc>
+    template <typename _ForwardIterator>
+      void
+      deque<_Tp,_Alloc>::
+      _M_range_insert_aux(iterator __pos,
+                          _ForwardIterator __first, _ForwardIterator __last,
+                          forward_iterator_tag)
+      {
+        size_type __n = distance(__first, __last);
+        if (__pos._M_cur == _M_start._M_cur)
+        {
+          iterator __new_start = _M_reserve_elements_at_front(__n);
+          try
+            {
+              uninitialized_copy(__first, __last, __new_start);
+              _M_start = __new_start;
+            }
+          catch(...)
+            {
+              _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
+              __throw_exception_again;
+            }
+        }
+        else if (__pos._M_cur == _M_finish._M_cur)
+        {
+          iterator __new_finish = _M_reserve_elements_at_back(__n);
+          try
+            {
+              uninitialized_copy(__first, __last, _M_finish);
+              _M_finish = __new_finish;
+            }
+          catch(...)
+            {
+              _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);
+              __throw_exception_again;
+            }
+        }
+        else
+          _M_insert_aux(__pos, __first, __last, __n);
+      }
+    
+  template <typename _Tp, typename _Alloc>
+    typename deque<_Tp, _Alloc>::iterator
+    deque<_Tp,_Alloc>::
+    _M_insert_aux(iterator __pos, const value_type& __x)
+    {
+      difference_type __index = __pos - _M_start;
+      value_type __x_copy = __x; // XXX copy
+      if (static_cast<size_type>(__index) < size() / 2)
+      {
+        push_front(front());
+        iterator __front1 = _M_start;
+        ++__front1;
+        iterator __front2 = __front1;
+        ++__front2;
+        __pos = _M_start + __index;
+        iterator __pos1 = __pos;
+        ++__pos1;
+        copy(__front2, __pos1, __front1);
+      }
+      else
+      {
+        push_back(back());
+        iterator __back1 = _M_finish;
+        --__back1;
+        iterator __back2 = __back1;
+        --__back2;
+        __pos = _M_start + __index;
+        copy_backward(__pos, __back2, __back1);
+      }
+      *__pos = __x_copy;
+      return __pos;
+    }
+    
+  #ifdef _GLIBCPP_DEPRECATED
+  // Nothing seems to actually use this.  According to the pattern followed by
+  // the rest of the SGI code, it would be called by the deprecated insert(pos)
+  // function, but that has been replaced.  We'll take our time removing this
+  // anyhow; mark for 3.4.  -pme
+  template <typename _Tp, typename _Alloc>
+    typename deque<_Tp,_Alloc>::iterator 
+    deque<_Tp,_Alloc>::
+    _M_insert_aux(iterator __pos)
+    {
+      difference_type __index = __pos - _M_start;
+      if (static_cast<size_type>(__index) < size() / 2)
+      {
+        push_front(front());
+        iterator __front1 = _M_start;
+        ++__front1;
+        iterator __front2 = __front1;
+        ++__front2;
+        __pos = _M_start + __index;
+        iterator __pos1 = __pos;
+        ++__pos1;
+        copy(__front2, __pos1, __front1);
+      }
+      else
+      {
+        push_back(back());
+        iterator __back1 = _M_finish;
+        --__back1;
+        iterator __back2 = __back1;
+        --__back2;
+        __pos = _M_start + __index;
+        copy_backward(__pos, __back2, __back1);
+      }
+      *__pos = value_type();
+      return __pos;
+    }
+  #endif
+    
+  template <typename _Tp, typename _Alloc>
     void
     deque<_Tp,_Alloc>::
-    _M_insert_aux(iterator __pos,
-                  _ForwardIterator __first, _ForwardIterator __last,
-                  size_type __n)
+    _M_insert_aux(iterator __pos, size_type __n, const value_type& __x)
     {
-      const difference_type __elemsbefore = __pos - _M_start;
-      size_type __length = size();
-      if (static_cast<size_type>(__elemsbefore) < __length / 2)
+      const difference_type __elems_before = __pos - _M_start;
+      size_type __length = this->size();
+      value_type __x_copy = __x;
+      if (__elems_before < difference_type(__length / 2))
       {
         iterator __new_start = _M_reserve_elements_at_front(__n);
         iterator __old_start = _M_start;
-        __pos = _M_start + __elemsbefore;
+        __pos = _M_start + __elems_before;
         try
           {
-            if (__elemsbefore >= difference_type(__n))
+            if (__elems_before >= difference_type(__n))
             {
-              iterator __start_n = _M_start + difference_type(__n); 
+              iterator __start_n = _M_start + difference_type(__n);
               uninitialized_copy(_M_start, __start_n, __new_start);
               _M_start = __new_start;
               copy(__start_n, __pos, __old_start);
-              copy(__first, __last, __pos - difference_type(__n));
+              fill(__pos - difference_type(__n), __pos, __x_copy);
             }
             else
             {
-              _ForwardIterator __mid = __first;
-              advance(__mid, difference_type(__n) - __elemsbefore);
-              __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
-                                        __new_start);
+              __uninitialized_copy_fill(_M_start, __pos, __new_start, 
+                                        _M_start, __x_copy);
               _M_start = __new_start;
-              copy(__mid, __last, __old_start);
+              fill(__old_start, __pos, __x_copy);
             }
           }
         catch(...)
-          {
+          { 
             _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
             __throw_exception_again;
           }
@@ -665,119 +587,192 @@ template <typename _Tp, typename _Alloc>
       {
         iterator __new_finish = _M_reserve_elements_at_back(__n);
         iterator __old_finish = _M_finish;
-        const difference_type __elemsafter = 
-          difference_type(__length) - __elemsbefore;
-        __pos = _M_finish - __elemsafter;
+        const difference_type __elems_after = 
+          difference_type(__length) - __elems_before;
+        __pos = _M_finish - __elems_after;
         try
           {
-            if (__elemsafter > difference_type(__n))
+            if (__elems_after > difference_type(__n))
             {
               iterator __finish_n = _M_finish - difference_type(__n);
               uninitialized_copy(__finish_n, _M_finish, _M_finish);
               _M_finish = __new_finish;
               copy_backward(__pos, __finish_n, __old_finish);
-              copy(__first, __last, __pos);
+              fill(__pos, __pos + difference_type(__n), __x_copy);
             }
             else
             {
-              _ForwardIterator __mid = __first;
-              advance(__mid, __elemsafter);
-              __uninitialized_copy_copy(__mid, __last, __pos,
-                                        _M_finish, _M_finish);
+              __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n),
+                                        __x_copy, __pos, _M_finish);
               _M_finish = __new_finish;
-              copy(__first, __mid, __pos);
+              fill(__pos, __old_finish, __x_copy);
             }
           }
         catch(...)
-          {
+          { 
             _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);
             __throw_exception_again;
           }
       }
     }
-  
-template <typename _Tp, typename _Alloc>
-  void
-  deque<_Tp,_Alloc>::
-  _M_new_elements_at_front(size_type __new_elems)
-  {
-    size_type __new_nodes
-        = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
-    _M_reserve_map_at_front(__new_nodes);
-    size_type __i;
-    try
-      {
-        for (__i = 1; __i <= __new_nodes; ++__i)
-          *(_M_start._M_node - __i) = _M_allocate_node();
-      }
-    catch(...)
+    
+  template <typename _Tp, typename _Alloc>
+    template <typename _ForwardIterator>
+      void
+      deque<_Tp,_Alloc>::
+      _M_insert_aux(iterator __pos,
+                    _ForwardIterator __first, _ForwardIterator __last,
+                    size_type __n)
       {
-        for (size_type __j = 1; __j < __i; ++__j)
-          _M_deallocate_node(*(_M_start._M_node - __j));      
-        __throw_exception_again;
+        const difference_type __elemsbefore = __pos - _M_start;
+        size_type __length = size();
+        if (static_cast<size_type>(__elemsbefore) < __length / 2)
+        {
+          iterator __new_start = _M_reserve_elements_at_front(__n);
+          iterator __old_start = _M_start;
+          __pos = _M_start + __elemsbefore;
+          try
+            {
+              if (__elemsbefore >= difference_type(__n))
+              {
+                iterator __start_n = _M_start + difference_type(__n); 
+                uninitialized_copy(_M_start, __start_n, __new_start);
+                _M_start = __new_start;
+                copy(__start_n, __pos, __old_start);
+                copy(__first, __last, __pos - difference_type(__n));
+              }
+              else
+              {
+                _ForwardIterator __mid = __first;
+                advance(__mid, difference_type(__n) - __elemsbefore);
+                __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
+                                          __new_start);
+                _M_start = __new_start;
+                copy(__mid, __last, __old_start);
+              }
+            }
+          catch(...)
+            {
+              _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
+              __throw_exception_again;
+            }
+        }
+        else
+        {
+          iterator __new_finish = _M_reserve_elements_at_back(__n);
+          iterator __old_finish = _M_finish;
+          const difference_type __elemsafter = 
+            difference_type(__length) - __elemsbefore;
+          __pos = _M_finish - __elemsafter;
+          try
+            {
+              if (__elemsafter > difference_type(__n))
+              {
+                iterator __finish_n = _M_finish - difference_type(__n);
+                uninitialized_copy(__finish_n, _M_finish, _M_finish);
+                _M_finish = __new_finish;
+                copy_backward(__pos, __finish_n, __old_finish);
+                copy(__first, __last, __pos);
+              }
+              else
+              {
+                _ForwardIterator __mid = __first;
+                advance(__mid, __elemsafter);
+                __uninitialized_copy_copy(__mid, __last, __pos,
+                                          _M_finish, _M_finish);
+                _M_finish = __new_finish;
+                copy(__first, __mid, __pos);
+              }
+            }
+          catch(...)
+            {
+              _M_destroy_nodes(_M_finish._M_node + 1, __new_finish._M_node + 1);
+              __throw_exception_again;
+            }
+        }
       }
-  }
-  
-template <typename _Tp, typename _Alloc>
-  void
-  deque<_Tp,_Alloc>::
-  _M_new_elements_at_back(size_type __new_elems)
-  {
-    size_type __new_nodes
-        = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
-    _M_reserve_map_at_back(__new_nodes);
-    size_type __i;
-    try
+    
+  template <typename _Tp, typename _Alloc>
+    void
+    deque<_Tp,_Alloc>::
+    _M_new_elements_at_front(size_type __new_elems)
+    {
+      size_type __new_nodes
+          = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
+      _M_reserve_map_at_front(__new_nodes);
+      size_type __i;
+      try
+        {
+          for (__i = 1; __i <= __new_nodes; ++__i)
+            *(_M_start._M_node - __i) = _M_allocate_node();
+        }
+      catch(...)
+        {
+          for (size_type __j = 1; __j < __i; ++__j)
+            _M_deallocate_node(*(_M_start._M_node - __j));      
+          __throw_exception_again;
+        }
+    }
+    
+  template <typename _Tp, typename _Alloc>
+    void
+    deque<_Tp,_Alloc>::
+    _M_new_elements_at_back(size_type __new_elems)
+    {
+      size_type __new_nodes
+          = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
+      _M_reserve_map_at_back(__new_nodes);
+      size_type __i;
+      try
+        {
+          for (__i = 1; __i <= __new_nodes; ++__i)
+            *(_M_finish._M_node + __i) = _M_allocate_node();
+        }
+      catch(...)
+        {
+          for (size_type __j = 1; __j < __i; ++__j)
+            _M_deallocate_node(*(_M_finish._M_node + __j));      
+          __throw_exception_again;
+        }
+    }
+    
+  template <typename _Tp, typename _Alloc>
+    void
+    deque<_Tp,_Alloc>::
+    _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front)
+    {
+      size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1;
+      size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
+    
+      _Map_pointer __new_nstart;
+      if (_M_map_size > 2 * __new_num_nodes)
       {
-        for (__i = 1; __i <= __new_nodes; ++__i)
-          *(_M_finish._M_node + __i) = _M_allocate_node();
+        __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2 
+                         + (__add_at_front ? __nodes_to_add : 0);
+        if (__new_nstart < _M_start._M_node)
+          copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
+        else
+          copy_backward(_M_start._M_node, _M_finish._M_node + 1, 
+                        __new_nstart + __old_num_nodes);
       }
-    catch(...)
+      else
       {
-        for (size_type __j = 1; __j < __i; ++__j)
-          _M_deallocate_node(*(_M_finish._M_node + __j));      
-        __throw_exception_again;
-      }
-  }
-  
-template <typename _Tp, typename _Alloc>
-  void
-  deque<_Tp,_Alloc>::
-  _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front)
-  {
-    size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1;
-    size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
-  
-    _Map_pointer __new_nstart;
-    if (_M_map_size > 2 * __new_num_nodes)
-    {
-      __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2 
-                       + (__add_at_front ? __nodes_to_add : 0);
-      if (__new_nstart < _M_start._M_node)
+        size_type __new_map_size = 
+          _M_map_size + max(_M_map_size, __nodes_to_add) + 2;
+    
+        _Map_pointer __new_map = _M_allocate_map(__new_map_size);
+        __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
+                             + (__add_at_front ? __nodes_to_add : 0);
         copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
-      else
-        copy_backward(_M_start._M_node, _M_finish._M_node + 1, 
-                      __new_nstart + __old_num_nodes);
-    }
-    else
-    {
-      size_type __new_map_size = 
-        _M_map_size + max(_M_map_size, __nodes_to_add) + 2;
-  
-      _Map_pointer __new_map = _M_allocate_map(__new_map_size);
-      __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
-                           + (__add_at_front ? __nodes_to_add : 0);
-      copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
-      _M_deallocate_map(_M_map, _M_map_size);
-  
-      _M_map = __new_map;
-      _M_map_size = __new_map_size;
+        _M_deallocate_map(_M_map, _M_map_size);
+    
+        _M_map = __new_map;
+        _M_map_size = __new_map_size;
+      }
+    
+      _M_start._M_set_node(__new_nstart);
+      _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
     }
-  
-    _M_start._M_set_node(__new_nstart);
-    _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
-  }
-
 } // namespace std 
   
 #endif /* __GLIBCPP_INTERNAL_DEQUE_TCC */
index 7fbfa9d..898a502 100644 (file)
 #ifndef __GLIBCPP_INTERNAL_LIST_TCC
 #define __GLIBCPP_INTERNAL_LIST_TCC
 
-// Since this entire file is within namespace std, there's no reason to
-// waste two spaces along the left column.  Thus the leading indentation is
-// slightly violated from here on.
 namespace std
 {
-
-template<typename _Tp, typename _Alloc>
-  void
-  _List_base<_Tp,_Alloc>::
-  __clear()
-  {
-    typedef _List_node<_Tp>  _Node;
-    _Node* __cur = static_cast<_Node*>(_M_node->_M_next);
-    while (__cur != _M_node)
+  template<typename _Tp, typename _Alloc>
+    void
+    _List_base<_Tp,_Alloc>::
+    __clear()
     {
-      _Node* __tmp = __cur;
-      __cur = static_cast<_Node*>(__cur->_M_next);
-      _Destroy(&__tmp->_M_data);
-      _M_put_node(__tmp);
+      typedef _List_node<_Tp>  _Node;
+      _Node* __cur = static_cast<_Node*>(_M_node->_M_next);
+      while (__cur != _M_node)
+      {
+        _Node* __tmp = __cur;
+        __cur = static_cast<_Node*>(__cur->_M_next);
+        _Destroy(&__tmp->_M_data);
+        _M_put_node(__tmp);
+      }
+      _M_node->_M_next = _M_node;
+      _M_node->_M_prev = _M_node;
     }
-    _M_node->_M_next = _M_node;
-    _M_node->_M_prev = _M_node;
-  }
-
-template<typename _Tp, typename _Alloc>
-  typename list<_Tp,_Alloc>::iterator
-  list<_Tp,_Alloc>::
-  insert(iterator __position, const value_type& __x)
-  {
-    _Node* __tmp = _M_create_node(__x);
-    __tmp->_M_next = __position._M_node;
-    __tmp->_M_prev = __position._M_node->_M_prev;
-    __position._M_node->_M_prev->_M_next = __tmp;
-    __position._M_node->_M_prev = __tmp;
-    return __tmp;
-  }
-
-template<typename _Tp, typename _Alloc>
-  typename list<_Tp,_Alloc>::iterator
-  list<_Tp,_Alloc>::
-  erase(iterator __position)
-  {
-    _List_node_base* __next_node = __position._M_node->_M_next;
-    _List_node_base* __prev_node = __position._M_node->_M_prev;
-    _Node* __n = static_cast<_Node*>(__position._M_node);
-    __prev_node->_M_next = __next_node;
-    __next_node->_M_prev = __prev_node;
-    _Destroy(&__n->_M_data);
-    _M_put_node(__n);
-    return iterator(static_cast<_Node*>(__next_node));
-  }
-
-template<typename _Tp, typename _Alloc>
-  void
-  list<_Tp,_Alloc>::
-  resize(size_type __new_size, const value_type& __x)
-  {
-    iterator __i = begin();
-    size_type __len = 0;
-    for ( ; __i != end() && __len < __new_size; ++__i, ++__len)
-      ;
-    if (__len == __new_size)
-      erase(__i, end());
-    else                          // __i == end()
-      insert(end(), __new_size - __len, __x);
-  }
-
-template<typename _Tp, typename _Alloc>
-  list<_Tp,_Alloc>&
-  list<_Tp,_Alloc>::
-  operator=(const list& __x)
-  {
-    if (this != &__x)
+  
+  template<typename _Tp, typename _Alloc>
+    typename list<_Tp,_Alloc>::iterator
+    list<_Tp,_Alloc>::
+    insert(iterator __position, const value_type& __x)
     {
-      iterator __first1 = begin();
-      iterator __last1 = end();
-      const_iterator __first2 = __x.begin();
-      const_iterator __last2 = __x.end();
-      while (__first1 != __last1 && __first2 != __last2)
-        *__first1++ = *__first2++;
-      if (__first2 == __last2)
-        erase(__first1, __last1);
-      else
-        insert(__last1, __first2, __last2);
+      _Node* __tmp = _M_create_node(__x);
+      __tmp->_M_next = __position._M_node;
+      __tmp->_M_prev = __position._M_node->_M_prev;
+      __position._M_node->_M_prev->_M_next = __tmp;
+      __position._M_node->_M_prev = __tmp;
+      return __tmp;
     }
-    return *this;
-  }
-
-template<typename _Tp, typename _Alloc>
-  void
-  list<_Tp,_Alloc>::
-  _M_fill_assign(size_type __n, const value_type& __val)
-  {
-    iterator __i = begin();
-    for ( ; __i != end() && __n > 0; ++__i, --__n)
-      *__i = __val;
-    if (__n > 0)
-      insert(end(), __n, __val);
-    else
-      erase(__i, end());
-  }
-
-template<typename _Tp, typename _Alloc>
-  template <typename _InputIter>
-    void
+  
+  template<typename _Tp, typename _Alloc>
+    typename list<_Tp,_Alloc>::iterator
     list<_Tp,_Alloc>::
-    _M_assign_dispatch(_InputIter __first2, _InputIter __last2, __false_type)
+    erase(iterator __position)
     {
-      iterator __first1 = begin();
-      iterator __last1 = end();
-      for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
-        *__first1 = *__first2;
-      if (__first2 == __last2)
-        erase(__first1, __last1);
-      else
-        insert(__last1, __first2, __last2);
+      _List_node_base* __next_node = __position._M_node->_M_next;
+      _List_node_base* __prev_node = __position._M_node->_M_prev;
+      _Node* __n = static_cast<_Node*>(__position._M_node);
+      __prev_node->_M_next = __next_node;
+      __next_node->_M_prev = __prev_node;
+      _Destroy(&__n->_M_data);
+      _M_put_node(__n);
+      return iterator(static_cast<_Node*>(__next_node));
     }
-
-template<typename _Tp, typename _Alloc>
-  void
-  list<_Tp,_Alloc>::
-  remove(const value_type& __value)
-  {
-    iterator __first = begin();
-    iterator __last = end();
-    while (__first != __last)
+  
+  template<typename _Tp, typename _Alloc>
+    void
+    list<_Tp,_Alloc>::
+    resize(size_type __new_size, const value_type& __x)
     {
-      iterator __next = __first;
-      ++__next;
-      if (*__first == __value)
-        erase(__first);
-      __first = __next;
+      iterator __i = begin();
+      size_type __len = 0;
+      for ( ; __i != end() && __len < __new_size; ++__i, ++__len)
+        ;
+      if (__len == __new_size)
+        erase(__i, end());
+      else                          // __i == end()
+        insert(end(), __new_size - __len, __x);
     }
-  }
-
-template<typename _Tp, typename _Alloc>
-  void
-  list<_Tp,_Alloc>::
-  unique()
-  {
-    iterator __first = begin();
-    iterator __last = end();
-    if (__first == __last) return;
-    iterator __next = __first;
-    while (++__next != __last)
+  
+  template<typename _Tp, typename _Alloc>
+    list<_Tp,_Alloc>&
+    list<_Tp,_Alloc>::
+    operator=(const list& __x)
     {
-      if (*__first == *__next)
-        erase(__next);
-      else
-        __first = __next;
-      __next = __first;
-    }
-  }
-
-template<typename _Tp, typename _Alloc>
-  void
-  list<_Tp,_Alloc>::
-  merge(list& __x)
-  {
-    iterator __first1 = begin();
-    iterator __last1 = end();
-    iterator __first2 = __x.begin();
-    iterator __last2 = __x.end();
-    while (__first1 != __last1 && __first2 != __last2)
-      if (*__first2 < *__first1)
+      if (this != &__x)
       {
-        iterator __next = __first2;
-        _M_transfer(__first1, __first2, ++__next);
-        __first2 = __next;
+        iterator __first1 = begin();
+        iterator __last1 = end();
+        const_iterator __first2 = __x.begin();
+        const_iterator __last2 = __x.end();
+        while (__first1 != __last1 && __first2 != __last2)
+          *__first1++ = *__first2++;
+        if (__first2 == __last2)
+          erase(__first1, __last1);
+        else
+          insert(__last1, __first2, __last2);
       }
-      else
-        ++__first1;
-    if (__first2 != __last2)
-      _M_transfer(__last1, __first2, __last2);
-  }
-
-// FIXME put this somewhere else
-inline void
-__List_base_reverse(_List_node_base* __p)
-{
-  _List_node_base* __tmp = __p;
-  do {
-    std::swap(__tmp->_M_next, __tmp->_M_prev);
-    __tmp = __tmp->_M_prev;     // Old next node is now prev.
-  } while (__tmp != __p);
-}
-
-template<typename _Tp, typename _Alloc>
-  void
-  list<_Tp,_Alloc>::
-  sort()
-  {
-    // Do nothing if the list has length 0 or 1.
-    if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node)
+      return *this;
+    }
+  
+  template<typename _Tp, typename _Alloc>
+    void
+    list<_Tp,_Alloc>::
+    _M_fill_assign(size_type __n, const value_type& __val)
     {
-      list __carry;
-      list __counter[64];
-      int __fill = 0;
-      while (!empty())
+      iterator __i = begin();
+      for ( ; __i != end() && __n > 0; ++__i, --__n)
+        *__i = __val;
+      if (__n > 0)
+        insert(end(), __n, __val);
+      else
+        erase(__i, end());
+    }
+  
+  template<typename _Tp, typename _Alloc>
+    template <typename _InputIter>
+      void
+      list<_Tp,_Alloc>::
+      _M_assign_dispatch(_InputIter __first2, _InputIter __last2, __false_type)
       {
-        __carry.splice(__carry.begin(), *this, begin());
-        int __i = 0;
-        while(__i < __fill && !__counter[__i].empty())
-        {
-          __counter[__i].merge(__carry);
-          __carry.swap(__counter[__i++]);
-        }
-        __carry.swap(__counter[__i]);
-        if (__i == __fill) ++__fill;
+        iterator __first1 = begin();
+        iterator __last1 = end();
+        for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
+          *__first1 = *__first2;
+        if (__first2 == __last2)
+          erase(__first1, __last1);
+        else
+          insert(__last1, __first2, __last2);
       }
-
-      for (int __i = 1; __i < __fill; ++__i)
-        __counter[__i].merge(__counter[__i-1]);
-      swap(__counter[__fill-1]);
-    }
-  }
-
-template<typename _Tp, typename _Alloc>
-  template <typename _Predicate>
+  
+  template<typename _Tp, typename _Alloc>
     void
     list<_Tp,_Alloc>::
-    remove_if(_Predicate __pred)
+    remove(const value_type& __value)
     {
       iterator __first = begin();
       iterator __last = end();
@@ -290,16 +186,16 @@ template<typename _Tp, typename _Alloc>
       {
         iterator __next = __first;
         ++__next;
-        if (__pred(*__first)) erase(__first);
+        if (*__first == __value)
+          erase(__first);
         __first = __next;
       }
     }
-
-template<typename _Tp, typename _Alloc>
-  template <typename _BinaryPredicate>
+  
+  template<typename _Tp, typename _Alloc>
     void
     list<_Tp,_Alloc>::
-    unique(_BinaryPredicate __binary_pred)
+    unique()
     {
       iterator __first = begin();
       iterator __last = end();
@@ -307,26 +203,25 @@ template<typename _Tp, typename _Alloc>
       iterator __next = __first;
       while (++__next != __last)
       {
-        if (__binary_pred(*__first, *__next))
+        if (*__first == *__next)
           erase(__next);
         else
           __first = __next;
         __next = __first;
       }
     }
-
-template<typename _Tp, typename _Alloc>
-  template <typename _StrictWeakOrdering>
+  
+  template<typename _Tp, typename _Alloc>
     void
     list<_Tp,_Alloc>::
-    merge(list& __x, _StrictWeakOrdering __comp)
+    merge(list& __x)
     {
       iterator __first1 = begin();
       iterator __last1 = end();
       iterator __first2 = __x.begin();
       iterator __last2 = __x.end();
       while (__first1 != __last1 && __first2 != __last2)
-        if (__comp(*__first2, *__first1))
+        if (*__first2 < *__first1)
         {
           iterator __next = __first2;
           _M_transfer(__first1, __first2, ++__next);
@@ -334,41 +229,140 @@ template<typename _Tp, typename _Alloc>
         }
         else
           ++__first1;
-      if (__first2 != __last2) _M_transfer(__last1, __first2, __last2);
+      if (__first2 != __last2)
+        _M_transfer(__last1, __first2, __last2);
     }
-
-template<typename _Tp, typename _Alloc>
-  template <typename _StrictWeakOrdering>
-  void
-  list<_Tp,_Alloc>::
-  sort(_StrictWeakOrdering __comp)
+  
+  // FIXME put this somewhere else
+  inline void
+  __List_base_reverse(_List_node_base* __p)
   {
-    // Do nothing if the list has length 0 or 1.
-    if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node)
+    _List_node_base* __tmp = __p;
+    do {
+      std::swap(__tmp->_M_next, __tmp->_M_prev);
+      __tmp = __tmp->_M_prev;     // Old next node is now prev.
+    } while (__tmp != __p);
+  }
+  
+  template<typename _Tp, typename _Alloc>
+    void
+    list<_Tp,_Alloc>::
+    sort()
     {
-      list __carry;
-      list __counter[64];
-      int __fill = 0;
-      while (!empty())
+      // Do nothing if the list has length 0 or 1.
+      if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node)
       {
-        __carry.splice(__carry.begin(), *this, begin());
-        int __i = 0;
-        while(__i < __fill && !__counter[__i].empty())
+        list __carry;
+        list __counter[64];
+        int __fill = 0;
+        while (!empty())
         {
-          __counter[__i].merge(__carry, __comp);
-          __carry.swap(__counter[__i++]);
+          __carry.splice(__carry.begin(), *this, begin());
+          int __i = 0;
+          while(__i < __fill && !__counter[__i].empty())
+          {
+            __counter[__i].merge(__carry);
+            __carry.swap(__counter[__i++]);
+          }
+          __carry.swap(__counter[__i]);
+          if (__i == __fill) ++__fill;
         }
-        __carry.swap(__counter[__i]);
-        if (__i == __fill) ++__fill;
+  
+        for (int __i = 1; __i < __fill; ++__i)
+          __counter[__i].merge(__counter[__i-1]);
+        swap(__counter[__fill-1]);
+      }
+    }
+  
+  template<typename _Tp, typename _Alloc>
+    template <typename _Predicate>
+      void
+      list<_Tp,_Alloc>::
+      remove_if(_Predicate __pred)
+      {
+        iterator __first = begin();
+        iterator __last = end();
+        while (__first != __last)
+        {
+          iterator __next = __first;
+          ++__next;
+          if (__pred(*__first)) erase(__first);
+          __first = __next;
+        }
+      }
+  
+  template<typename _Tp, typename _Alloc>
+    template <typename _BinaryPredicate>
+      void
+      list<_Tp,_Alloc>::
+      unique(_BinaryPredicate __binary_pred)
+      {
+        iterator __first = begin();
+        iterator __last = end();
+        if (__first == __last) return;
+        iterator __next = __first;
+        while (++__next != __last)
+        {
+          if (__binary_pred(*__first, *__next))
+            erase(__next);
+          else
+            __first = __next;
+          __next = __first;
+        }
+      }
+  
+  template<typename _Tp, typename _Alloc>
+    template <typename _StrictWeakOrdering>
+      void
+      list<_Tp,_Alloc>::
+      merge(list& __x, _StrictWeakOrdering __comp)
+      {
+        iterator __first1 = begin();
+        iterator __last1 = end();
+        iterator __first2 = __x.begin();
+        iterator __last2 = __x.end();
+        while (__first1 != __last1 && __first2 != __last2)
+          if (__comp(*__first2, *__first1))
+          {
+            iterator __next = __first2;
+            _M_transfer(__first1, __first2, ++__next);
+            __first2 = __next;
+          }
+          else
+            ++__first1;
+        if (__first2 != __last2) _M_transfer(__last1, __first2, __last2);
+      }
+  
+  template<typename _Tp, typename _Alloc>
+    template <typename _StrictWeakOrdering>
+    void
+    list<_Tp,_Alloc>::
+    sort(_StrictWeakOrdering __comp)
+    {
+      // Do nothing if the list has length 0 or 1.
+      if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node)
+      {
+        list __carry;
+        list __counter[64];
+        int __fill = 0;
+        while (!empty())
+        {
+          __carry.splice(__carry.begin(), *this, begin());
+          int __i = 0;
+          while(__i < __fill && !__counter[__i].empty())
+          {
+            __counter[__i].merge(__carry, __comp);
+            __carry.swap(__counter[__i++]);
+          }
+          __carry.swap(__counter[__i]);
+          if (__i == __fill) ++__fill;
+        }
+  
+        for (int __i = 1; __i < __fill; ++__i)
+          __counter[__i].merge(__counter[__i-1], __comp);
+        swap(__counter[__fill-1]);
       }
-
-      for (int __i = 1; __i < __fill; ++__i)
-        __counter[__i].merge(__counter[__i-1], __comp);
-      swap(__counter[__fill-1]);
     }
-  }
-
 } // namespace std
 
 #endif /* __GLIBCPP_INTERNAL_LIST_TCC */
-
index 711d921..aa1eef8 100644 (file)
 #include <bits/stl_iterator_base_types.h>
 #include <bits/stl_iterator_base_funcs.h>
 
-// Since this entire file is within namespace std, there's no reason to
-// waste two spaces along the left column.  Thus the leading indentation is
-// slightly violated from here on.
 namespace std
 { 
-
-/**
- *  @if maint
- *  @brief This function controls the size of memory nodes.
- *  @param  size  The size of an element.
- *  @return   The number (not byte size) of elements per node.
- *
- *  This function started off as a compiler kludge from SGI, but seems to
- *  be a useful wrapper around a repeated constant expression.  The '512' is
- *  tuneable (and no other code needs to change), but no investigation has
- *  been done since inheriting the SGI code.
- *  @endif
-*/
-inline size_t 
-__deque_buf_size(size_t __size) 
-  { return __size < 512 ? size_t(512 / __size) : size_t(1); }
-
-
-/**
- *  @brief A deque::iterator.
- *
- *  Quite a bit of intelligence here.  Much of the functionality of deque is
- *  actually passed off to this class.  A deque holds two of these internally,
- *  marking its valid range.  Access to elements is done as offsets of either
- *  of those two, relying on operator overloading in this class.
- *
- *  @if maint
- *  All the functions are op overloads except for _M_set_node.
- *  @endif
-*/
-template <typename _Tp, typename _Ref, typename _Ptr>
-  struct _Deque_iterator
-{
-  typedef _Deque_iterator<_Tp, _Tp&, _Tp*>             iterator;
-  typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
-  static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
-
-  typedef random_access_iterator_tag iterator_category;
-  typedef _Tp                        value_type;
-  typedef _Ptr                       pointer;
-  typedef _Ref                       reference;
-  typedef size_t                     size_type;
-  typedef ptrdiff_t                  difference_type;
-  typedef _Tp**                      _Map_pointer;
-  typedef _Deque_iterator            _Self;
-
-  _Tp* _M_cur;
-  _Tp* _M_first;
-  _Tp* _M_last;
-  _Map_pointer _M_node;
-
-  _Deque_iterator(_Tp* __x, _Map_pointer __y) 
-    : _M_cur(__x), _M_first(*__y),
-      _M_last(*__y + _S_buffer_size()), _M_node(__y) {}
-  _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {}
-  _Deque_iterator(const iterator& __x)
-    : _M_cur(__x._M_cur), _M_first(__x._M_first), 
-      _M_last(__x._M_last), _M_node(__x._M_node) {}
-
-  reference operator*() const { return *_M_cur; }
-  pointer operator->() const { return _M_cur; }
-
-  _Self& operator++() {
-    ++_M_cur;
-    if (_M_cur == _M_last) {
-      _M_set_node(_M_node + 1);
-      _M_cur = _M_first;
+  /**
+   *  @if maint
+   *  @brief This function controls the size of memory nodes.
+   *  @param  size  The size of an element.
+   *  @return   The number (not byte size) of elements per node.
+   *
+   *  This function started off as a compiler kludge from SGI, but seems to
+   *  be a useful wrapper around a repeated constant expression.  The '512' is
+   *  tuneable (and no other code needs to change), but no investigation has
+   *  been done since inheriting the SGI code.
+   *  @endif
+  */
+  inline size_t 
+  __deque_buf_size(size_t __size) 
+    { return __size < 512 ? size_t(512 / __size) : size_t(1); }
+  
+  
+  /**
+   *  @brief A deque::iterator.
+   *
+   *  Quite a bit of intelligence here.  Much of the functionality of deque is
+   *  actually passed off to this class.  A deque holds two of these internally,
+   *  marking its valid range.  Access to elements is done as offsets of either
+   *  of those two, relying on operator overloading in this class.
+   *
+   *  @if maint
+   *  All the functions are op overloads except for _M_set_node.
+   *  @endif
+  */
+  template <typename _Tp, typename _Ref, typename _Ptr>
+    struct _Deque_iterator
+  {
+    typedef _Deque_iterator<_Tp, _Tp&, _Tp*>             iterator;
+    typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
+    static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
+  
+    typedef random_access_iterator_tag iterator_category;
+    typedef _Tp                        value_type;
+    typedef _Ptr                       pointer;
+    typedef _Ref                       reference;
+    typedef size_t                     size_type;
+    typedef ptrdiff_t                  difference_type;
+    typedef _Tp**                      _Map_pointer;
+    typedef _Deque_iterator            _Self;
+  
+    _Tp* _M_cur;
+    _Tp* _M_first;
+    _Tp* _M_last;
+    _Map_pointer _M_node;
+  
+    _Deque_iterator(_Tp* __x, _Map_pointer __y) 
+      : _M_cur(__x), _M_first(*__y),
+        _M_last(*__y + _S_buffer_size()), _M_node(__y) {}
+    _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {}
+    _Deque_iterator(const iterator& __x)
+      : _M_cur(__x._M_cur), _M_first(__x._M_first), 
+        _M_last(__x._M_last), _M_node(__x._M_node) {}
+  
+    reference operator*() const { return *_M_cur; }
+    pointer operator->() const { return _M_cur; }
+  
+    _Self& operator++() {
+      ++_M_cur;
+      if (_M_cur == _M_last) {
+        _M_set_node(_M_node + 1);
+        _M_cur = _M_first;
+      }
+      return *this; 
     }
-    return *this; 
-  }
-  _Self operator++(int)  {
-    _Self __tmp = *this;
-    ++*this;
-    return __tmp;
-  }
-
-  _Self& operator--() {
-    if (_M_cur == _M_first) {
-      _M_set_node(_M_node - 1);
-      _M_cur = _M_last;
+    _Self operator++(int)  {
+      _Self __tmp = *this;
+      ++*this;
+      return __tmp;
     }
-    --_M_cur;
-    return *this;
-  }
-  _Self operator--(int) {
-    _Self __tmp = *this;
-    --*this;
-    return __tmp;
-  }
-
-  _Self& operator+=(difference_type __n)
-  {
-    difference_type __offset = __n + (_M_cur - _M_first);
-    if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
-      _M_cur += __n;
-    else {
-      difference_type __node_offset =
-        __offset > 0 ? __offset / difference_type(_S_buffer_size())
-                   : -difference_type((-__offset - 1) / _S_buffer_size()) - 1;
-      _M_set_node(_M_node + __node_offset);
-      _M_cur = _M_first + 
-        (__offset - __node_offset * difference_type(_S_buffer_size()));
+  
+    _Self& operator--() {
+      if (_M_cur == _M_first) {
+        _M_set_node(_M_node - 1);
+        _M_cur = _M_last;
+      }
+      --_M_cur;
+      return *this;
     }
-    return *this;
-  }
-
-  _Self operator+(difference_type __n) const
+    _Self operator--(int) {
+      _Self __tmp = *this;
+      --*this;
+      return __tmp;
+    }
+  
+    _Self& operator+=(difference_type __n)
+    {
+      difference_type __offset = __n + (_M_cur - _M_first);
+      if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
+        _M_cur += __n;
+      else {
+        difference_type __node_offset =
+          __offset > 0 ? __offset / difference_type(_S_buffer_size())
+                     : -difference_type((-__offset - 1) / _S_buffer_size()) - 1;
+        _M_set_node(_M_node + __node_offset);
+        _M_cur = _M_first + 
+          (__offset - __node_offset * difference_type(_S_buffer_size()));
+      }
+      return *this;
+    }
+  
+    _Self operator+(difference_type __n) const
+    {
+      _Self __tmp = *this;
+      return __tmp += __n;
+    }
+  
+    _Self& operator-=(difference_type __n) { return *this += -__n; }
+   
+    _Self operator-(difference_type __n) const {
+      _Self __tmp = *this;
+      return __tmp -= __n;
+    }
+  
+    reference operator[](difference_type __n) const { return *(*this + __n); }
+  
+    /** @if maint
+     *  Prepares to traverse new_node.  Sets everything except _M_cur, which
+     *  should therefore be set by the caller immediately afterwards, based on
+     *  _M_first and _M_last.
+     *  @endif
+    */
+    void
+    _M_set_node(_Map_pointer __new_node)
+    {
+      _M_node = __new_node;
+      _M_first = *__new_node;
+      _M_last = _M_first + difference_type(_S_buffer_size());
+    }
+  };
+  
+  // Note: we also provide overloads whose operands are of the same type in
+  // order to avoid ambiguous overload resolution when std::rel_ops operators
+  // are in scope (for additional details, see libstdc++/3628)
+  template <typename _Tp, typename _Ref, typename _Ptr>
+  inline bool
+  operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
+          const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
   {
-    _Self __tmp = *this;
-    return __tmp += __n;
+    return __x._M_cur == __y._M_cur;
   }
-
-  _Self& operator-=(difference_type __n) { return *this += -__n; }
-  _Self operator-(difference_type __n) const {
-    _Self __tmp = *this;
-    return __tmp -= __n;
+  
+  template <typename _Tp, typename _RefL, typename _PtrL,
+                          typename _RefR, typename _PtrR>
+  inline bool
+  operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
+          const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
+  {
+    return __x._M_cur == __y._M_cur;
   }
-
-  reference operator[](difference_type __n) const { return *(*this + __n); }
-
-  /** @if maint
-   *  Prepares to traverse new_node.  Sets everything except _M_cur, which
-   *  should therefore be set by the caller immediately afterwards, based on
-   *  _M_first and _M_last.
-   *  @endif
-  */
-  void
-  _M_set_node(_Map_pointer __new_node)
+  
+  template <typename _Tp, typename _Ref, typename _Ptr>
+  inline bool
+  operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
+          const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
   {
-    _M_node = __new_node;
-    _M_first = *__new_node;
-    _M_last = _M_first + difference_type(_S_buffer_size());
+    return !(__x == __y);
   }
-};
-
-// Note: we also provide overloads whose operands are of the same type in
-// order to avoid ambiguous overload resolution when std::rel_ops operators
-// are in scope (for additional details, see libstdc++/3628)
-template <typename _Tp, typename _Ref, typename _Ptr>
-inline bool
-operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
-          const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
-{
-  return __x._M_cur == __y._M_cur;
-}
-
-template <typename _Tp, typename _RefL, typename _PtrL,
-                        typename _RefR, typename _PtrR>
-inline bool
-operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
-          const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
-{
-  return __x._M_cur == __y._M_cur;
-}
-
-template <typename _Tp, typename _Ref, typename _Ptr>
-inline bool
-operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
-          const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
-{
-  return !(__x == __y);
-}
-
-template <typename _Tp, typename _RefL, typename _PtrL,
-                        typename _RefR, typename _PtrR>
-inline bool
-operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
-          const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
-{
-  return !(__x == __y);
-}
-
-template <typename _Tp, typename _Ref, typename _Ptr>
-inline bool
-operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
-          const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
-{
-  return (__x._M_node == __y._M_node) ? 
-    (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
-}
-
-template <typename _Tp, typename _RefL, typename _PtrL,
-                        typename _RefR, typename _PtrR>
-inline bool
-operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
-          const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
-{
-  return (__x._M_node == __y._M_node) ? 
-    (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
-}
-
-template <typename _Tp, typename _Ref, typename _Ptr>
-inline bool
-operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
-          const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
-{
-  return __y < __x;
-}
-
-template <typename _Tp, typename _RefL, typename _PtrL,
-                        typename _RefR, typename _PtrR>
-inline bool
-operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
-          const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
-{
-  return __y < __x;
-}
-
-template <typename _Tp, typename _Ref, typename _Ptr>
-inline bool
-operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
-          const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
-{
-  return !(__y < __x);
-}
-
-template <typename _Tp, typename _RefL, typename _PtrL,
-                        typename _RefR, typename _PtrR>
-inline bool
-operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
-          const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
-{
-  return !(__y < __x);
-}
-
-template <typename _Tp, typename _Ref, typename _Ptr>
-inline bool
-operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
-          const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
-{
-  return !(__x < __y);
-}
-
-template <typename _Tp, typename _RefL, typename _PtrL,
-                        typename _RefR, typename _PtrR>
-inline bool
-operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
-          const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
-{
-  return !(__x < __y);
-}
-
-// _GLIBCPP_RESOLVE_LIB_DEFECTS
-// According to the resolution of DR179 not only the various comparison
-// operators but also operator- must accept mixed iterator/const_iterator
-// parameters.
-template <typename _Tp, typename _RefL, typename _PtrL,
-                        typename _RefR, typename _PtrR>
-inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
-operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
-         const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
-{
-  return _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
-    (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) *
-    (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) +
-    (__y._M_last - __y._M_cur);
-}
-
-template <typename _Tp, typename _Ref, typename _Ptr>
-inline _Deque_iterator<_Tp, _Ref, _Ptr>
-operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
-{
-  return __x + __n;
-}
-
-
-/// @if maint Primary default version.  @endif
-/**
- *  @if maint
- *  Deque base class.  It has two purposes.  First, its constructor
- *  and destructor allocate (but don't initialize) storage.  This makes
- *  %exception safety easier.  Second, the base class encapsulates all of
- *  the differences between SGI-style allocators and standard-conforming
- *  allocators.  (See stl_alloc.h for more on this topic.)  There are two
- *  versions:  this ordinary one, and the space-saving specialization for
- *  instanceless allocators.
- *  @endif
-*/
-template <typename _Tp, typename _Alloc, bool __is_static>
-  class _Deque_alloc_base
-{
-public:
-  typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
-  allocator_type get_allocator() const { return _M_node_allocator; }
-
-  _Deque_alloc_base(const allocator_type& __a)
-    : _M_node_allocator(__a), _M_map_allocator(__a),
-      _M_map(0), _M_map_size(0)
-  {}
-  
-protected:
-  typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type
-          _Map_allocator_type;
-
-  _Tp*
-  _M_allocate_node()
+  
+  template <typename _Tp, typename _RefL, typename _PtrL,
+                          typename _RefR, typename _PtrR>
+  inline bool
+  operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
+          const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
   {
-    return _M_node_allocator.allocate(__deque_buf_size(sizeof(_Tp)));
+    return !(__x == __y);
   }
-
-  void
-  _M_deallocate_node(_Tp* __p)
+  
+  template <typename _Tp, typename _Ref, typename _Ptr>
+  inline bool
+  operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
+          const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
   {
-    _M_node_allocator.deallocate(__p, __deque_buf_size(sizeof(_Tp)));
+    return (__x._M_node == __y._M_node) ? 
+      (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
   }
-
-  _Tp**
-  _M_allocate_map(size_t __n) 
-    { return _M_map_allocator.allocate(__n); }
-
-  void
-  _M_deallocate_map(_Tp** __p, size_t __n) 
-    { _M_map_allocator.deallocate(__p, __n); }
-
-  allocator_type       _M_node_allocator;
-  _Map_allocator_type  _M_map_allocator;
-  _Tp**                _M_map;
-  size_t               _M_map_size;
-};
-
-/// @if maint Specialization for instanceless allocators.  @endif
-template <typename _Tp, typename _Alloc>
-  class _Deque_alloc_base<_Tp, _Alloc, true>
-{
-public:
-  typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
-  allocator_type get_allocator() const { return allocator_type(); }
-
-  _Deque_alloc_base(const allocator_type&)
-    : _M_map(0), _M_map_size(0)
-  {}
   
-protected:
-  typedef typename _Alloc_traits<_Tp,_Alloc>::_Alloc_type  _Node_alloc_type;
-  typedef typename _Alloc_traits<_Tp*,_Alloc>::_Alloc_type _Map_alloc_type;
-
-  _Tp*
-  _M_allocate_node()
+  template <typename _Tp, typename _RefL, typename _PtrL,
+                          typename _RefR, typename _PtrR>
+  inline bool
+  operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
+          const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
   {
-    return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp)));
+    return (__x._M_node == __y._M_node) ? 
+      (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node);
   }
-
-  void
-  _M_deallocate_node(_Tp* __p)
+  
+  template <typename _Tp, typename _Ref, typename _Ptr>
+  inline bool
+  operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
+          const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
   {
-    _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
+    return __y < __x;
   }
-
-  _Tp**
-  _M_allocate_map(size_t __n) 
-    { return _Map_alloc_type::allocate(__n); }
-
-  void
-  _M_deallocate_map(_Tp** __p, size_t __n) 
-    { _Map_alloc_type::deallocate(__p, __n); }
-
-  _Tp**   _M_map;
-  size_t  _M_map_size;
-};
-
-
-/**
- *  @if maint
- *  Deque base class.  Using _Alloc_traits in the instantiation of the parent
- *  class provides the compile-time dispatching mentioned in the parent's docs.
- *  This class provides the unified face for %deque's allocation.
- *
- *  Nothing in this class ever constructs or destroys an actual Tp element.
- *  (Deque handles that itself.)  Only/All memory management is performed here.
- *  @endif
-*/
-template <typename _Tp, typename _Alloc>
-  class _Deque_base
-  : public _Deque_alloc_base<_Tp,_Alloc,
-                              _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
-{
-public:
-  typedef _Deque_alloc_base<_Tp,_Alloc,
-                             _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
-          _Base;
-  typedef typename _Base::allocator_type             allocator_type;
-  typedef _Deque_iterator<_Tp,_Tp&,_Tp*>             iterator;
-  typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
-
-  _Deque_base(const allocator_type& __a, size_t __num_elements)
-    : _Base(__a), _M_start(), _M_finish()
-    { _M_initialize_map(__num_elements); }
-  _Deque_base(const allocator_type& __a) 
-    : _Base(__a), _M_start(), _M_finish() {}
-  ~_Deque_base();    
-
-protected:
-  void _M_initialize_map(size_t);
-  void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
-  void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
-  enum { _S_initial_map_size = 8 };
-
-  iterator _M_start;
-  iterator _M_finish;
-};
-
-
-template <typename _Tp, typename _Alloc>
-_Deque_base<_Tp,_Alloc>::~_Deque_base()
-{
-  if (_M_map)
+  
+  template <typename _Tp, typename _RefL, typename _PtrL,
+                          typename _RefR, typename _PtrR>
+  inline bool
+  operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
+          const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
   {
-    _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1);
-    _M_deallocate_map(_M_map, _M_map_size);
+    return __y < __x;
   }
-}
-
-/**
- *  @if maint
- *  @brief Layout storage.
- *  @param  num_elements  The count of T's for which to allocate space at first.
- *  @return   Nothing.
- *
- *  The initial underlying memory layout is a bit complicated...
- *  @endif
-*/
-template <typename _Tp, typename _Alloc>
-void
-_Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements)
-{
-  size_t __num_nodes = 
-    __num_elements / __deque_buf_size(sizeof(_Tp)) + 1;
-
-  _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2);
-  _M_map = _M_allocate_map(_M_map_size);
-
-  // For "small" maps (needing less than _M_map_size nodes), allocation
-  // starts in the middle elements and grows outwards.  So nstart may be the
-  // beginning of _M_map, but for small maps it may be as far in as _M_map+3.
-
-  _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2;
-  _Tp** __nfinish = __nstart + __num_nodes;
-    
-  try 
-    { _M_create_nodes(__nstart, __nfinish); }
-  catch(...)
-    {
-      _M_deallocate_map(_M_map, _M_map_size);
-      _M_map = 0;
-      _M_map_size = 0;
-      __throw_exception_again;
-    }
   
-  _M_start._M_set_node(__nstart);
-  _M_finish._M_set_node(__nfinish - 1);
-  _M_start._M_cur = _M_start._M_first;
-  _M_finish._M_cur = _M_finish._M_first +
-                     __num_elements % __deque_buf_size(sizeof(_Tp));
-}
-
-template <typename _Tp, typename _Alloc>
-void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish)
-{
-  _Tp** __cur;
-  try
-    {
-      for (__cur = __nstart; __cur < __nfinish; ++__cur)
-        *__cur = _M_allocate_node();
-    }
-  catch(...)
-    { 
-      _M_destroy_nodes(__nstart, __cur);
-      __throw_exception_again; 
-    }
-}
-
-template <typename _Tp, typename _Alloc>
-void
-_Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
-{
-  for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
-    _M_deallocate_node(*__n);
-}
-
-
-/**
- *  @brief  A standard container using fixed-size memory allocation and
- *  constant-time manipulation of elements at either end.
- *
- *  @ingroup Containers
- *  @ingroup Sequences
- *
- *  Meets the requirements of a <a href="tables.html#65">container</a>, a
- *  <a href="tables.html#66">reversible container</a>, and a
- *  <a href="tables.html#67">sequence</a>, including the
- *  <a href="tables.html#68">optional sequence requirements</a>.
- *
- *  In previous HP/SGI versions of deque, there was an extra template parameter
- *  so users could control the node size.  This extension turned out to violate
- *  the C++ standard (it can be detected using template template parameters),
- *  and it was removed.
- *
- *  @if maint
- *  Here's how a deque<Tp> manages memory.  Each deque has 4 members:
- *  
- *  - Tp**        _M_map
- *  - size_t      _M_map_size
- *  - iterator    _M_start, _M_finish
- *  
- *  map_size is at least 8.  %map is an array of map_size pointers-to-"nodes".
- *  (The name %map has nothing to do with the std::map class, and "nodes"
- *  should not be confused with std::list's usage of "node".)
- *  
- *  A "node" has no specific type name as such, but it is referred to as
- *  "node" in this file.  It is a simple array-of-Tp.  If Tp is very large,
- *  there will be one Tp element per node (i.e., an "array" of one).
- *  For non-huge Tp's, node size is inversely related to Tp size:  the
- *  larger the Tp, the fewer Tp's will fit in a node.  The goal here is to
- *  keep the total size of a node relatively small and constant over different
- *  Tp's, to improve allocator efficiency.
- *  
- *  **** As I write this, the nodes are /not/ allocated using the high-speed
- *  memory pool.  There are 20 hours left in the year; perhaps I can fix
- *  this before 2002.
- *  
- *  Not every pointer in the %map array will point to a node.  If the initial
- *  number of elements in the deque is small, the /middle/ %map pointers will
- *  be valid, and the ones at the edges will be unused.  This same situation
- *  will arise as the %map grows:  available %map pointers, if any, will be on
- *  the ends.  As new nodes are created, only a subset of the %map's pointers
- *  need to be copied "outward".
- *
- *  Class invariants:
- * - For any nonsingular iterator i:
- *    - i.node points to a member of the %map array.  (Yes, you read that
- *      correctly:  i.node does not actually point to a node.)  The member of
- *      the %map array is what actually points to the node.
- *    - i.first == *(i.node)    (This points to the node (first Tp element).)
- *    - i.last  == i.first + node_size
- *    - i.cur is a pointer in the range [i.first, i.last).  NOTE:
- *      the implication of this is that i.cur is always a dereferenceable
- *      pointer, even if i is a past-the-end iterator.
- * - Start and Finish are always nonsingular iterators.  NOTE: this means that
- *   an empty deque must have one node, a deque with <N elements (where N is
- *   the node buffer size) must have one node, a deque with N through (2N-1)
- *   elements must have two nodes, etc.
- * - For every node other than start.node and finish.node, every element in the
- *   node is an initialized object.  If start.node == finish.node, then
- *   [start.cur, finish.cur) are initialized objects, and the elements outside
- *   that range are uninitialized storage.  Otherwise, [start.cur, start.last)
- *   and [finish.first, finish.cur) are initialized objects, and [start.first,
- *   start.cur) and [finish.cur, finish.last) are uninitialized storage.
- * - [%map, %map + map_size) is a valid, non-empty range.  
- * - [start.node, finish.node] is a valid range contained within 
- *   [%map, %map + map_size).  
- * - A pointer in the range [%map, %map + map_size) points to an allocated node
- *   if and only if the pointer is in the range [start.node, finish.node].
- *
- *  Here's the magic:  nothing in deque is "aware" of the discontiguous storage!
- *
- *  The memory setup and layout occurs in the parent, _Base, and the iterator
- *  class is entirely responsible for "leaping" from one node to the next.  All
- *  the implementation routines for deque itself work only through the start
- *  and finish iterators.  This keeps the routines simple and sane, and we can
- *  use other standard algorithms as well.
- *  @endif
-*/
-template <typename _Tp, typename _Alloc = allocator<_Tp> >
-  class deque : protected _Deque_base<_Tp, _Alloc>
-{
-  // concept requirements
-  __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
-
-  typedef _Deque_base<_Tp, _Alloc>           _Base;
-
-public:
-  typedef _Tp                                value_type;
-  typedef value_type*                        pointer;
-  typedef const value_type*                  const_pointer;
-  typedef typename _Base::iterator           iterator;
-  typedef typename _Base::const_iterator     const_iterator;
-  typedef reverse_iterator<const_iterator>   const_reverse_iterator;
-  typedef reverse_iterator<iterator>         reverse_iterator;
-  typedef value_type&                        reference;
-  typedef const value_type&                  const_reference;
-  typedef size_t                             size_type;
-  typedef ptrdiff_t                          difference_type;
-  typedef typename _Base::allocator_type     allocator_type;
-
-protected:
-  typedef pointer*                           _Map_pointer;
-  static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
-
-  // Functions controlling memory layout, and nothing else.
-  using _Base::_M_initialize_map;
-  using _Base::_M_create_nodes;
-  using _Base::_M_destroy_nodes;
-  using _Base::_M_allocate_node;
-  using _Base::_M_deallocate_node;
-  using _Base::_M_allocate_map;
-  using _Base::_M_deallocate_map;
-
-  /** @if maint
-   *  A total of four data members accumulated down the heirarchy.  If the
-   *  _Alloc type requires separate instances, then two of them will also be
-   *  included in each deque.
-   *  @endif
-  */
-  using _Base::_M_map;
-  using _Base::_M_map_size;
-  using _Base::_M_start;
-  using _Base::_M_finish;
-
-public:
-  // [23.2.1.1] construct/copy/destroy
-  // (assign() and get_allocator() are also listed in this section)
-  /**
-   *  @brief  Default constructor creates no elements.
-  */
-  explicit
-  deque(const allocator_type& __a = allocator_type()) 
-    : _Base(__a, 0) {}
-
-  /**
-   *  @brief  Create a %deque with copies of an exemplar element.
-   *  @param  n  The number of elements to initially create.
-   *  @param  value  An element to copy.
-   * 
-   *  This constructor fills the %deque with @a n copies of @a value.
-  */
-  deque(size_type __n, const value_type& __value,
-        const allocator_type& __a = allocator_type())
-    : _Base(__a, __n)
-    { _M_fill_initialize(__value); }
-
-  /**
-   *  @brief  Create a %deque with default elements.
-   *  @param  n  The number of elements to initially create.
-   * 
-   *  This constructor fills the %deque with @a n copies of a
-   *  default-constructed element.
-  */
-  explicit
-  deque(size_type __n)
-    : _Base(allocator_type(), __n)
-    { _M_fill_initialize(value_type()); }
-
-  /**
-   *  @brief  %Deque copy constructor.
-   *  @param  x  A %deque of identical element and allocator types.
-   * 
-   *  The newly-created %deque uses a copy of the allocation object used
-   *  by @a x.
-  */
-  deque(const deque& __x)
-    : _Base(__x.get_allocator(), __x.size()) 
-    { uninitialized_copy(__x.begin(), __x.end(), _M_start); }
-
-  /**
-   *  @brief  Builds a %deque from a range.
-   *  @param  first  An input iterator.
-   *  @param  last  An input iterator.
-   * 
-   *  Create a %deque consisting of copies of the elements from [first,last).
-   *
-   *  If the iterators are forward, bidirectional, or random-access, then
-   *  this will call the elements' copy constructor N times (where N is
-   *  distance(first,last)) and do no memory reallocation.  But if only
-   *  input iterators are used, then this will do at most 2N calls to the
-   *  copy constructor, and logN memory reallocations.
-  */
-  template<typename _InputIterator>
-    deque(_InputIterator __first, _InputIterator __last,
-          const allocator_type& __a = allocator_type())
-      : _Base(__a)
-    {
-      // Check whether it's an integral type.  If so, it's not an iterator.
-      typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
-      _M_initialize_dispatch(__first, __last, _Integral());
-    }
-
-  /**
-   *  The dtor only erases the elements, and note that if the elements
-   *  themselves are pointers, the pointed-to memory is not touched in any
-   *  way.  Managing the pointer is the user's responsibilty.
-  */
-  ~deque() { _Destroy(_M_start, _M_finish); }
-
-  /**
-   *  @brief  %Deque assignment operator.
-   *  @param  x  A %deque of identical element and allocator types.
-   * 
-   *  All the elements of @a x are copied, but unlike the copy constructor, the
-   *  allocator object is not copied.
-  */
-  deque&
-  operator=(const deque& __x);
-
-  /**
-   *  @brief  Assigns a given value to a %deque.
-   *  @param  n  Number of elements to be assigned.
-   *  @param  val  Value to be assigned.
-   *
-   *  This function fills a %deque with @a n copies of the given value.
-   *  Note that the assignment completely changes the %deque and that the
-   *  resulting %deque's size is the same as the number of elements assigned.
-   *  Old data may be lost.
-  */
-  void
-  assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); }
-
-  /**
-   *  @brief  Assigns a range to a %deque.
-   *  @param  first  An input iterator.
-   *  @param  last   An input iterator.
-   *
-   *  This function fills a %deque with copies of the elements in the
-   *  range [first,last).
-   *
-   *  Note that the assignment completely changes the %deque and that the
-   *  resulting %deque's size is the same as the number of elements assigned.
-   *  Old data may be lost.
-  */
-  template<typename _InputIterator>
-    void
-    assign(_InputIterator __first, _InputIterator __last)
-    {
-      typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
-      _M_assign_dispatch(__first, __last, _Integral());
-    }
-
-  /// Get a copy of the memory allocation object.
-  allocator_type
-  get_allocator() const { return _Base::get_allocator(); }
-
-  // iterators
-  /**
-   *  Returns a read/write iterator that points to the first element in the
-   *  %deque.  Iteration is done in ordinary element order.
-  */
-  iterator
-  begin() { return _M_start; }
-
-  /**
-   *  Returns a read-only (constant) iterator that points to the first element
-   *  in the %deque.  Iteration is done in ordinary element order.
-  */
-  const_iterator
-  begin() const { return _M_start; }
-
-  /**
-   *  Returns a read/write iterator that points one past the last element in
-   *  the %deque.  Iteration is done in ordinary element order.
-  */
-  iterator
-  end() { return _M_finish; }
-
-  /**
-   *  Returns a read-only (constant) iterator that points one past the last
-   *  element in the %deque.  Iteration is done in ordinary element order.
-  */
-  const_iterator
-  end() const { return _M_finish; }
-
-  /**
-   *  Returns a read/write reverse iterator that points to the last element in
-   *  the %deque.  Iteration is done in reverse element order.
-  */
-  reverse_iterator
-  rbegin() { return reverse_iterator(_M_finish); }
-
-  /**
-   *  Returns a read-only (constant) reverse iterator that points to the last
-   *  element in the %deque.  Iteration is done in reverse element order.
-  */
-  const_reverse_iterator
-  rbegin() const { return const_reverse_iterator(_M_finish); }
-
-  /**
-   *  Returns a read/write reverse iterator that points to one before the
-   *  first element in the %deque.  Iteration is done in reverse element
-   *  order.
-  */
-  reverse_iterator
-  rend() { return reverse_iterator(_M_start); }
-
-  /**
-   *  Returns a read-only (constant) reverse iterator that points to one
-   *  before the first element in the %deque.  Iteration is done in reverse
-   *  element order.
-  */
-  const_reverse_iterator
-  rend() const { return const_reverse_iterator(_M_start); }
-
-  // [23.2.1.2] capacity
-  /**  Returns the number of elements in the %deque.  */
-  size_type
-  size() const { return _M_finish - _M_start; }
-
-  /**  Returns the size() of the largest possible %deque.  */
-  size_type
-  max_size() const { return size_type(-1); }
-
-  /**
-   *  @brief  Resizes the %deque to the specified number of elements.
-   *  @param  new_size  Number of elements the %deque should contain.
-   *  @param  x  Data with which new elements should be populated.
-   *
-   *  This function will %resize the %deque to the specified number of
-   *  elements.  If the number is smaller than the %deque's current size the
-   *  %deque is truncated, otherwise the %deque is extended and new elements
-   *  are populated with given data.
-  */
-  void
-  resize(size_type __new_size, const value_type& __x)
+  template <typename _Tp, typename _Ref, typename _Ptr>
+  inline bool
+  operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
+          const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
   {
-    const size_type __len = size();
-    if (__new_size < __len) 
-      erase(_M_start + __new_size, _M_finish);
-    else
-      insert(_M_finish, __new_size - __len, __x);
+    return !(__y < __x);
   }
-
-  /**
-   *  @brief  Resizes the %deque to the specified number of elements.
-   *  @param  new_size  Number of elements the %deque should contain.
-   *
-   *  This function will resize the %deque to the specified number of
-   *  elements.  If the number is smaller than the %deque's current size the
-   *  %deque is truncated, otherwise the %deque is extended and new elements
-   *  are default-constructed.
-  */
-  void
-  resize(size_type new_size) { resize(new_size, value_type()); }
-
-  /**
-   *  Returns true if the %deque is empty.  (Thus begin() would equal end().)
-  */
-  bool empty() const { return _M_finish == _M_start; }
-
-  // element access
-  /**
-   *  @brief  Subscript access to the data contained in the %deque.
-   *  @param  n  The index of the element for which data should be accessed.
-   *  @return  Read/write reference to data.
-   *
-   *  This operator allows for easy, array-style, data access.
-   *  Note that data access with this operator is unchecked and out_of_range
-   *  lookups are not defined. (For checked lookups see at().)
-  */
-  reference
-  operator[](size_type __n) { return _M_start[difference_type(__n)]; }
-
-  /**
-   *  @brief  Subscript access to the data contained in the %deque.
-   *  @param  n  The index of the element for which data should be accessed.
-   *  @return  Read-only (constant) reference to data.
-   *
-   *  This operator allows for easy, array-style, data access.
-   *  Note that data access with this operator is unchecked and out_of_range
-   *  lookups are not defined. (For checked lookups see at().)
-  */
-  const_reference
-  operator[](size_type __n) const { return _M_start[difference_type(__n)]; }
-
-protected:
-  /// @if maint Safety check used only from at().  @endif
-  void
-  _M_range_check(size_type __n) const
+  
+  template <typename _Tp, typename _RefL, typename _PtrL,
+                          typename _RefR, typename _PtrR>
+  inline bool
+  operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
+          const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
   {
-    if (__n >= this->size())
-      __throw_out_of_range("deque [] access out of range");
+    return !(__y < __x);
   }
-
-public:
-  /**
-   *  @brief  Provides access to the data contained in the %deque.
-   *  @param  n  The index of the element for which data should be accessed.
-   *  @return  Read/write reference to data.
-   *  @throw  std::out_of_range  If @a n is an invalid index.
-   *
-   *  This function provides for safer data access.  The parameter is first
-   *  checked that it is in the range of the deque.  The function throws
-   *  out_of_range if the check fails.
-  */
-  reference
-  at(size_type __n) { _M_range_check(__n); return (*this)[__n]; }
-
-  /**
-   *  @brief  Provides access to the data contained in the %deque.
-   *  @param  n  The index of the element for which data should be accessed.
-   *  @return  Read-only (constant) reference to data.
-   *  @throw  std::out_of_range  If @a n is an invalid index.
-   *
-   *  This function provides for safer data access.  The parameter is first
-   *  checked that it is in the range of the deque.  The function throws
-   *  out_of_range if the check fails.
-  */
-  const_reference
-  at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; }
-
-  /**
-   *  Returns a read/write reference to the data at the first element of the
-   *  %deque.
-  */
-  reference
-  front() { return *_M_start; }
-
-  /**
-   *  Returns a read-only (constant) reference to the data at the first
-   *  element of the %deque.
-  */
-  const_reference
-  front() const { return *_M_start; }
-
-  /**
-   *  Returns a read/write reference to the data at the last element of the
-   *  %deque.
-  */
-  reference
-  back()
+  
+  template <typename _Tp, typename _Ref, typename _Ptr>
+  inline bool
+  operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
+          const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
   {
-    iterator __tmp = _M_finish;
-    --__tmp;
-    return *__tmp;
+    return !(__x < __y);
   }
-
-  /**
-   *  Returns a read-only (constant) reference to the data at the last
-   *  element of the %deque.
-  */
-  const_reference
-  back() const
+  
+  template <typename _Tp, typename _RefL, typename _PtrL,
+                          typename _RefR, typename _PtrR>
+  inline bool
+  operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
+          const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
   {
-    const_iterator __tmp = _M_finish;
-    --__tmp;
-    return *__tmp;
+    return !(__x < __y);
   }
-
-  // [23.2.1.2] modifiers
-  /**
-   *  @brief  Add data to the front of the %deque.
-   *  @param  x  Data to be added.
-   *
-   *  This is a typical stack operation.  The function creates an element at
-   *  the front of the %deque and assigns the given data to it.  Due to the
-   *  nature of a %deque this operation can be done in constant time.
-  */
-  void
-  push_front(const value_type& __x) 
+  
+  // _GLIBCPP_RESOLVE_LIB_DEFECTS
+  // According to the resolution of DR179 not only the various comparison
+  // operators but also operator- must accept mixed iterator/const_iterator
+  // parameters.
+  template <typename _Tp, typename _RefL, typename _PtrL,
+                          typename _RefR, typename _PtrR>
+  inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
+  operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
+         const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
   {
-    if (_M_start._M_cur != _M_start._M_first) {
-      _Construct(_M_start._M_cur - 1, __x);
-      --_M_start._M_cur;
-    }
-    else
-      _M_push_front_aux(__x);
+    return _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
+      (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) *
+      (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) +
+      (__y._M_last - __y._M_cur);
   }
-
-#ifdef _GLIBCPP_DEPRECATED
-  /**
-   *  @brief  Add data to the front of the %deque.
-   *
-   *  This is a typical stack operation.  The function creates a
-   *  default-constructed element at the front of the %deque.  Due to the nature
-   *  of a %deque this operation can be done in constant time.  You should
-   *  consider using push_front(value_type()) instead.
-   *
-   *  @note This was deprecated in 3.2 and will be removed in 3.4.  You must
-   *        define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see
-   *        c++config.h.
-  */
-  void
-  push_front()
+  
+  template <typename _Tp, typename _Ref, typename _Ptr>
+  inline _Deque_iterator<_Tp, _Ref, _Ptr>
+  operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
   {
-    if (_M_start._M_cur != _M_start._M_first) {
-      _Construct(_M_start._M_cur - 1);
-      --_M_start._M_cur;
-    }
-    else
-      _M_push_front_aux();
+    return __x + __n;
   }
-#endif
-
+  
+  
+  /// @if maint Primary default version.  @endif
   /**
-   *  @brief  Add data to the end of the %deque.
-   *  @param  x  Data to be added.
-   *
-   *  This is a typical stack operation.  The function creates an element at
-   *  the end of the %deque and assigns the given data to it.  Due to the
-   *  nature of a %deque this operation can be done in constant time.
+   *  @if maint
+   *  Deque base class.  It has two purposes.  First, its constructor
+   *  and destructor allocate (but don't initialize) storage.  This makes
+   *  %exception safety easier.  Second, the base class encapsulates all of
+   *  the differences between SGI-style allocators and standard-conforming
+   *  allocators.  (See stl_alloc.h for more on this topic.)  There are two
+   *  versions:  this ordinary one, and the space-saving specialization for
+   *  instanceless allocators.
+   *  @endif
   */
-  void
-  push_back(const value_type& __x)
+  template <typename _Tp, typename _Alloc, bool __is_static>
+    class _Deque_alloc_base
   {
-    if (_M_finish._M_cur != _M_finish._M_last - 1) {
-      _Construct(_M_finish._M_cur, __x);
-      ++_M_finish._M_cur;
+  public:
+    typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
+    allocator_type get_allocator() const { return _M_node_allocator; }
+  
+    _Deque_alloc_base(const allocator_type& __a)
+      : _M_node_allocator(__a), _M_map_allocator(__a),
+        _M_map(0), _M_map_size(0)
+    {}
+    
+  protected:
+    typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type
+            _Map_allocator_type;
+  
+    _Tp*
+    _M_allocate_node()
+    {
+      return _M_node_allocator.allocate(__deque_buf_size(sizeof(_Tp)));
     }
-    else
-      _M_push_back_aux(__x);
-  }
-
-#ifdef _GLIBCPP_DEPRECATED
-  /**
-   *  @brief  Add data to the end of the %deque.
-   *
-   *  This is a typical stack operation.  The function creates a
-   *  default-constructed element at the end of the %deque.  Due to the nature
-   *  of a %deque this operation can be done in constant time.  You should
-   *  consider using push_back(value_type()) instead.
-   *
-   *  @note This was deprecated in 3.2 and will be removed in 3.4.  You must
-   *        define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see
-   *        c++config.h.
-  */
-  void
-  push_back()
+  
+    void
+    _M_deallocate_node(_Tp* __p)
+    {
+      _M_node_allocator.deallocate(__p, __deque_buf_size(sizeof(_Tp)));
+    }
+  
+    _Tp**
+    _M_allocate_map(size_t __n) 
+      { return _M_map_allocator.allocate(__n); }
+  
+    void
+    _M_deallocate_map(_Tp** __p, size_t __n) 
+      { _M_map_allocator.deallocate(__p, __n); }
+  
+    allocator_type       _M_node_allocator;
+    _Map_allocator_type  _M_map_allocator;
+    _Tp**                _M_map;
+    size_t               _M_map_size;
+  };
+  
+  /// @if maint Specialization for instanceless allocators.  @endif
+  template <typename _Tp, typename _Alloc>
+    class _Deque_alloc_base<_Tp, _Alloc, true>
   {
-    if (_M_finish._M_cur != _M_finish._M_last - 1) {
-      _Construct(_M_finish._M_cur);
-      ++_M_finish._M_cur;
+  public:
+    typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
+    allocator_type get_allocator() const { return allocator_type(); }
+  
+    _Deque_alloc_base(const allocator_type&)
+      : _M_map(0), _M_map_size(0)
+    {}
+    
+  protected:
+    typedef typename _Alloc_traits<_Tp,_Alloc>::_Alloc_type  _Node_alloc_type;
+    typedef typename _Alloc_traits<_Tp*,_Alloc>::_Alloc_type _Map_alloc_type;
+  
+    _Tp*
+    _M_allocate_node()
+    {
+      return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp)));
     }
-    else
-      _M_push_back_aux();
-  }
-#endif
-
+  
+    void
+    _M_deallocate_node(_Tp* __p)
+    {
+      _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
+    }
+  
+    _Tp**
+    _M_allocate_map(size_t __n) 
+      { return _Map_alloc_type::allocate(__n); }
+  
+    void
+    _M_deallocate_map(_Tp** __p, size_t __n) 
+      { _Map_alloc_type::deallocate(__p, __n); }
+  
+    _Tp**   _M_map;
+    size_t  _M_map_size;
+  };
+  
+  
   /**
-   *  @brief  Removes first element.
-   *
-   *  This is a typical stack operation.  It shrinks the %deque by one.
+   *  @if maint
+   *  Deque base class.  Using _Alloc_traits in the instantiation of the parent
+   *  class provides the compile-time dispatching mentioned in the parent's
+   *  docs.  This class provides the unified face for %deque's allocation.
    *
-   *  Note that no data is returned, and if the first element's data is
-   *  needed, it should be retrieved before pop_front() is called.
+   *  Nothing in this class ever constructs or destroys an actual Tp element.
+   *  (Deque handles that itself.)  Only/All memory management is performed
+   *  here.
+   *  @endif
   */
-  void
-  pop_front()
+  template <typename _Tp, typename _Alloc>
+    class _Deque_base
+    : public _Deque_alloc_base<_Tp,_Alloc,
+                                _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
+  {
+  public:
+    typedef _Deque_alloc_base<_Tp,_Alloc,
+                               _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
+            _Base;
+    typedef typename _Base::allocator_type             allocator_type;
+    typedef _Deque_iterator<_Tp,_Tp&,_Tp*>             iterator;
+    typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
+  
+    _Deque_base(const allocator_type& __a, size_t __num_elements)
+      : _Base(__a), _M_start(), _M_finish()
+      { _M_initialize_map(__num_elements); }
+    _Deque_base(const allocator_type& __a) 
+      : _Base(__a), _M_start(), _M_finish() {}
+    ~_Deque_base();    
+  
+  protected:
+    void _M_initialize_map(size_t);
+    void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
+    void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
+    enum { _S_initial_map_size = 8 };
+  
+    iterator _M_start;
+    iterator _M_finish;
+  };
+  
+  
+  template <typename _Tp, typename _Alloc>
+  _Deque_base<_Tp,_Alloc>::~_Deque_base()
   {
-    if (_M_start._M_cur != _M_start._M_last - 1) {
-      _Destroy(_M_start._M_cur);
-      ++_M_start._M_cur;
+    if (_M_map)
+    {
+      _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1);
+      _M_deallocate_map(_M_map, _M_map_size);
     }
-    else 
-      _M_pop_front_aux();
   }
-
+  
   /**
-   *  @brief  Removes last element.
-   *
-   *  This is a typical stack operation.  It shrinks the %deque by one.
+   *  @if maint
+   *  @brief Layout storage.
+   *  @param  num_elements  The count of T's for which to allocate space
+   *                        at first.
+   *  @return   Nothing.
    *
-   *  Note that no data is returned, and if the last element's data is
-   *  needed, it should be retrieved before pop_back() is called.
+   *  The initial underlying memory layout is a bit complicated...
+   *  @endif
   */
+  template <typename _Tp, typename _Alloc>
   void
-  pop_back()
+  _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements)
   {
-    if (_M_finish._M_cur != _M_finish._M_first) {
-      --_M_finish._M_cur;
-      _Destroy(_M_finish._M_cur);
-    }
-    else
-      _M_pop_back_aux();
+    size_t __num_nodes = 
+      __num_elements / __deque_buf_size(sizeof(_Tp)) + 1;
+  
+    _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2);
+    _M_map = _M_allocate_map(_M_map_size);
+  
+    // For "small" maps (needing less than _M_map_size nodes), allocation
+    // starts in the middle elements and grows outwards.  So nstart may be the
+    // beginning of _M_map, but for small maps it may be as far in as _M_map+3.
+  
+    _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2;
+    _Tp** __nfinish = __nstart + __num_nodes;
+      
+    try 
+      { _M_create_nodes(__nstart, __nfinish); }
+    catch(...)
+      {
+        _M_deallocate_map(_M_map, _M_map_size);
+        _M_map = 0;
+        _M_map_size = 0;
+        __throw_exception_again;
+      }
+    
+    _M_start._M_set_node(__nstart);
+    _M_finish._M_set_node(__nfinish - 1);
+    _M_start._M_cur = _M_start._M_first;
+    _M_finish._M_cur = _M_finish._M_first +
+                       __num_elements % __deque_buf_size(sizeof(_Tp));
   }
-
-  /**
-   *  @brief  Inserts given value into %deque before specified iterator.
-   *  @param  position  An iterator into the %deque.
-   *  @param  x  Data to be inserted.
-   *  @return  An iterator that points to the inserted data.
-   *
-   *  This function will insert a copy of the given value before the specified
-   *  location.
-  */
-  iterator
-  insert(iterator position, const value_type& __x);
-
-#ifdef _GLIBCPP_DEPRECATED
-  /**
-   *  @brief  Inserts an element into the %deque.
-   *  @param  position  An iterator into the %deque.
-   *  @return  An iterator that points to the inserted element.
-   *
-   *  This function will insert a default-constructed element before the
-   *  specified location.  You should consider using
-   *  insert(position,value_type()) instead.
-   *
-   *  @note This was deprecated in 3.2 and will be removed in 3.4.  You must
-   *        define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see
-   *        c++config.h.
-  */
-  iterator
-  insert(iterator __position)
-    { return insert(__position, value_type()); }
-#endif
-
-  /**
-   *  @brief  Inserts a number of copies of given data into the %deque.
-   *  @param  position  An iterator into the %deque.
-   *  @param  n  Number of elements to be inserted.
-   *  @param  x  Data to be inserted.
-   *
-   *  This function will insert a specified number of copies of the given data
-   *  before the location specified by @a position.
-  */
+  
+  template <typename _Tp, typename _Alloc>
+  void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish)
+  {
+    _Tp** __cur;
+    try
+      {
+        for (__cur = __nstart; __cur < __nfinish; ++__cur)
+          *__cur = _M_allocate_node();
+      }
+    catch(...)
+      { 
+        _M_destroy_nodes(__nstart, __cur);
+        __throw_exception_again; 
+      }
+  }
+  
+  template <typename _Tp, typename _Alloc>
   void
-  insert(iterator __position, size_type __n, const value_type& __x)
-    { _M_fill_insert(__position, __n, __x); }
-
+  _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
+  {
+    for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
+      _M_deallocate_node(*__n);
+  }
+  
+  
   /**
-   *  @brief  Inserts a range into the %deque.
-   *  @param  pos  An iterator into the %deque.
-   *  @param  first  An input iterator.
-   *  @param  last   An input iterator.
+   *  @brief  A standard container using fixed-size memory allocation and
+   *  constant-time manipulation of elements at either end.
    *
-   *  This function will insert copies of the data in the range [first,last)
-   *  into the %deque before the location specified by @a pos.  This is
-   *  known as "range insert."
-  */
-  template<typename _InputIterator>
-    void
-    insert(iterator __pos, _InputIterator __first, _InputIterator __last)
-    {
-      // Check whether it's an integral type.  If so, it's not an iterator.
-      typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
-      _M_insert_dispatch(__pos, __first, __last, _Integral());
-    }
-
-  /**
-   *  @brief  Remove element at given position.
-   *  @param  position  Iterator pointing to element to be erased.
-   *  @return  An iterator pointing to the next element (or end()).
+   *  @ingroup Containers
+   *  @ingroup Sequences
    *
-   *  This function will erase the element at the given position and thus
-   *  shorten the %deque by one.
+   *  Meets the requirements of a <a href="tables.html#65">container</a>, a
+   *  <a href="tables.html#66">reversible container</a>, and a
+   *  <a href="tables.html#67">sequence</a>, including the
+   *  <a href="tables.html#68">optional sequence requirements</a>.
    *
-   *  The user is cautioned that
-   *  this function only erases the element, and that if the element is itself
-   *  a pointer, the pointed-to memory is not touched in any way.  Managing
-   *  the pointer is the user's responsibilty.
-  */
-  iterator
-  erase(iterator __position);
-
-  /**
-   *  @brief  Remove a range of elements.
-   *  @param  first  Iterator pointing to the first element to be erased.
-   *  @param  last  Iterator pointing to one past the last element to be erased.
-   *  @return  An iterator pointing to the element pointed to by @a last
-   *           prior to erasing (or end()).
+   *  In previous HP/SGI versions of deque, there was an extra template
+   *  parameter so users could control the node size.  This extension turned
+   *  out to violate the C++ standard (it can be detected using template
+   *  template parameters), and it was removed.
    *
-   *  This function will erase the elements in the range [first,last) and
-   *  shorten the %deque accordingly.
+   *  @if maint
+   *  Here's how a deque<Tp> manages memory.  Each deque has 4 members:
+   *  
+   *  - Tp**        _M_map
+   *  - size_t      _M_map_size
+   *  - iterator    _M_start, _M_finish
+   *  
+   *  map_size is at least 8.  %map is an array of map_size pointers-to-"nodes".
+   *  (The name %map has nothing to do with the std::map class, and "nodes"
+   *  should not be confused with std::list's usage of "node".)
+   *  
+   *  A "node" has no specific type name as such, but it is referred to as
+   *  "node" in this file.  It is a simple array-of-Tp.  If Tp is very large,
+   *  there will be one Tp element per node (i.e., an "array" of one).
+   *  For non-huge Tp's, node size is inversely related to Tp size:  the
+   *  larger the Tp, the fewer Tp's will fit in a node.  The goal here is to
+   *  keep the total size of a node relatively small and constant over different
+   *  Tp's, to improve allocator efficiency.
+   *  
+   *  **** As I write this, the nodes are /not/ allocated using the high-speed
+   *  memory pool.  There are 20 hours left in the year; perhaps I can fix
+   *  this before 2002.
+   *  
+   *  Not every pointer in the %map array will point to a node.  If the initial
+   *  number of elements in the deque is small, the /middle/ %map pointers will
+   *  be valid, and the ones at the edges will be unused.  This same situation
+   *  will arise as the %map grows:  available %map pointers, if any, will be on
+   *  the ends.  As new nodes are created, only a subset of the %map's pointers
+   *  need to be copied "outward".
    *
-   *  The user is cautioned that
-   *  this function only erases the elements, and that if the elements
-   *  themselves are pointers, the pointed-to memory is not touched in any
-   *  way.  Managing the pointer is the user's responsibilty.
-  */
-  iterator
-  erase(iterator __first, iterator __last);
-
-  /**
-   *  @brief  Swaps data with another %deque.
-   *  @param  x  A %deque of the same element and allocator types.
+   *  Class invariants:
+   * - For any nonsingular iterator i:
+   *    - i.node points to a member of the %map array.  (Yes, you read that
+   *      correctly:  i.node does not actually point to a node.)  The member of
+   *      the %map array is what actually points to the node.
+   *    - i.first == *(i.node)    (This points to the node (first Tp element).)
+   *    - i.last  == i.first + node_size
+   *    - i.cur is a pointer in the range [i.first, i.last).  NOTE:
+   *      the implication of this is that i.cur is always a dereferenceable
+   *      pointer, even if i is a past-the-end iterator.
+   * - Start and Finish are always nonsingular iterators.  NOTE: this means that
+   *   an empty deque must have one node, a deque with <N elements (where N is
+   *   the node buffer size) must have one node, a deque with N through (2N-1)
+   *   elements must have two nodes, etc.
+   * - For every node other than start.node and finish.node, every element in
+   *   the node is an initialized object.  If start.node == finish.node, then
+   *   [start.cur, finish.cur) are initialized objects, and the elements outside
+   *   that range are uninitialized storage.  Otherwise, [start.cur, start.last)
+   *   and [finish.first, finish.cur) are initialized objects, and [start.first,
+   *   start.cur) and [finish.cur, finish.last) are uninitialized storage.
+   * - [%map, %map + map_size) is a valid, non-empty range.  
+   * - [start.node, finish.node] is a valid range contained within 
+   *   [%map, %map + map_size).  
+   * - A pointer in the range [%map, %map + map_size) points to an allocated
+   *   node if and only if the pointer is in the range
+   *   [start.node, finish.node].
    *
-   *  This exchanges the elements between two deques in constant time.
-   *  (Four pointers, so it should be quite fast.)
-   *  Note that the global std::swap() function is specialized such that
-   *  std::swap(d1,d2) will feed to this function.
+   *  Here's the magic:  nothing in deque is "aware" of the discontiguous
+   *  storage!
+   *
+   *  The memory setup and layout occurs in the parent, _Base, and the iterator
+   *  class is entirely responsible for "leaping" from one node to the next.
+   *  All the implementation routines for deque itself work only through the
+   *  start and finish iterators.  This keeps the routines simple and sane,
+   *  and we can use other standard algorithms as well.
+   *  @endif
   */
-  void
-  swap(deque& __x)
+  template <typename _Tp, typename _Alloc = allocator<_Tp> >
+    class deque : protected _Deque_base<_Tp, _Alloc>
   {
-    std::swap(_M_start, __x._M_start);
-    std::swap(_M_finish, __x._M_finish);
-    std::swap(_M_map, __x._M_map);
-    std::swap(_M_map_size, __x._M_map_size);
-  }
-
-  /**
-   *  Erases all the elements.  Note that this function only erases the
-   *  elements, and that if the elements themselves are pointers, the
-   *  pointed-to memory is not touched in any way.  Managing the pointer is
-   *  the user's responsibilty.
-  */
-  void clear(); 
-
-protected:
-  // Internal constructor functions follow.
-
-  // called by the range constructor to implement [23.1.1]/9
-  template<typename _Integer>
+    // concept requirements
+    __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+  
+    typedef _Deque_base<_Tp, _Alloc>           _Base;
+  
+  public:
+    typedef _Tp                                value_type;
+    typedef value_type*                        pointer;
+    typedef const value_type*                  const_pointer;
+    typedef typename _Base::iterator           iterator;
+    typedef typename _Base::const_iterator     const_iterator;
+    typedef reverse_iterator<const_iterator>   const_reverse_iterator;
+    typedef reverse_iterator<iterator>         reverse_iterator;
+    typedef value_type&                        reference;
+    typedef const value_type&                  const_reference;
+    typedef size_t                             size_type;
+    typedef ptrdiff_t                          difference_type;
+    typedef typename _Base::allocator_type     allocator_type;
+  
+  protected:
+    typedef pointer*                           _Map_pointer;
+    static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); }
+  
+    // Functions controlling memory layout, and nothing else.
+    using _Base::_M_initialize_map;
+    using _Base::_M_create_nodes;
+    using _Base::_M_destroy_nodes;
+    using _Base::_M_allocate_node;
+    using _Base::_M_deallocate_node;
+    using _Base::_M_allocate_map;
+    using _Base::_M_deallocate_map;
+  
+    /** @if maint
+     *  A total of four data members accumulated down the heirarchy.  If the
+     *  _Alloc type requires separate instances, then two of them will also be
+     *  included in each deque.
+     *  @endif
+    */
+    using _Base::_M_map;
+    using _Base::_M_map_size;
+    using _Base::_M_start;
+    using _Base::_M_finish;
+  
+  public:
+    // [23.2.1.1] construct/copy/destroy
+    // (assign() and get_allocator() are also listed in this section)
+    /**
+     *  @brief  Default constructor creates no elements.
+    */
+    explicit
+    deque(const allocator_type& __a = allocator_type()) 
+      : _Base(__a, 0) {}
+  
+    /**
+     *  @brief  Create a %deque with copies of an exemplar element.
+     *  @param  n  The number of elements to initially create.
+     *  @param  value  An element to copy.
+     * 
+     *  This constructor fills the %deque with @a n copies of @a value.
+    */
+    deque(size_type __n, const value_type& __value,
+          const allocator_type& __a = allocator_type())
+      : _Base(__a, __n)
+      { _M_fill_initialize(__value); }
+  
+    /**
+     *  @brief  Create a %deque with default elements.
+     *  @param  n  The number of elements to initially create.
+     * 
+     *  This constructor fills the %deque with @a n copies of a
+     *  default-constructed element.
+    */
+    explicit
+    deque(size_type __n)
+      : _Base(allocator_type(), __n)
+      { _M_fill_initialize(value_type()); }
+  
+    /**
+     *  @brief  %Deque copy constructor.
+     *  @param  x  A %deque of identical element and allocator types.
+     * 
+     *  The newly-created %deque uses a copy of the allocation object used
+     *  by @a x.
+    */
+    deque(const deque& __x)
+      : _Base(__x.get_allocator(), __x.size()) 
+      { uninitialized_copy(__x.begin(), __x.end(), _M_start); }
+  
+    /**
+     *  @brief  Builds a %deque from a range.
+     *  @param  first  An input iterator.
+     *  @param  last  An input iterator.
+     * 
+     *  Create a %deque consisting of copies of the elements from [first,last).
+     *
+     *  If the iterators are forward, bidirectional, or random-access, then
+     *  this will call the elements' copy constructor N times (where N is
+     *  distance(first,last)) and do no memory reallocation.  But if only
+     *  input iterators are used, then this will do at most 2N calls to the
+     *  copy constructor, and logN memory reallocations.
+    */
+    template<typename _InputIterator>
+      deque(_InputIterator __first, _InputIterator __last,
+            const allocator_type& __a = allocator_type())
+        : _Base(__a)
+      {
+        // Check whether it's an integral type.  If so, it's not an iterator.
+        typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+        _M_initialize_dispatch(__first, __last, _Integral());
+      }
+  
+    /**
+     *  The dtor only erases the elements, and note that if the elements
+     *  themselves are pointers, the pointed-to memory is not touched in any
+     *  way.  Managing the pointer is the user's responsibilty.
+    */
+    ~deque() { _Destroy(_M_start, _M_finish); }
+  
+    /**
+     *  @brief  %Deque assignment operator.
+     *  @param  x  A %deque of identical element and allocator types.
+     * 
+     *  All the elements of @a x are copied, but unlike the copy constructor,
+     *  the allocator object is not copied.
+    */
+    deque&
+    operator=(const deque& __x);
+  
+    /**
+     *  @brief  Assigns a given value to a %deque.
+     *  @param  n  Number of elements to be assigned.
+     *  @param  val  Value to be assigned.
+     *
+     *  This function fills a %deque with @a n copies of the given value.
+     *  Note that the assignment completely changes the %deque and that the
+     *  resulting %deque's size is the same as the number of elements assigned.
+     *  Old data may be lost.
+    */
+    void
+    assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); }
+  
+    /**
+     *  @brief  Assigns a range to a %deque.
+     *  @param  first  An input iterator.
+     *  @param  last   An input iterator.
+     *
+     *  This function fills a %deque with copies of the elements in the
+     *  range [first,last).
+     *
+     *  Note that the assignment completely changes the %deque and that the
+     *  resulting %deque's size is the same as the number of elements assigned.
+     *  Old data may be lost.
+    */
+    template<typename _InputIterator>
+      void
+      assign(_InputIterator __first, _InputIterator __last)
+      {
+        typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+        _M_assign_dispatch(__first, __last, _Integral());
+      }
+  
+    /// Get a copy of the memory allocation object.
+    allocator_type
+    get_allocator() const { return _Base::get_allocator(); }
+  
+    // iterators
+    /**
+     *  Returns a read/write iterator that points to the first element in the
+     *  %deque.  Iteration is done in ordinary element order.
+    */
+    iterator
+    begin() { return _M_start; }
+  
+    /**
+     *  Returns a read-only (constant) iterator that points to the first element
+     *  in the %deque.  Iteration is done in ordinary element order.
+    */
+    const_iterator
+    begin() const { return _M_start; }
+  
+    /**
+     *  Returns a read/write iterator that points one past the last element in
+     *  the %deque.  Iteration is done in ordinary element order.
+    */
+    iterator
+    end() { return _M_finish; }
+  
+    /**
+     *  Returns a read-only (constant) iterator that points one past the last
+     *  element in the %deque.  Iteration is done in ordinary element order.
+    */
+    const_iterator
+    end() const { return _M_finish; }
+  
+    /**
+     *  Returns a read/write reverse iterator that points to the last element in
+     *  the %deque.  Iteration is done in reverse element order.
+    */
+    reverse_iterator
+    rbegin() { return reverse_iterator(_M_finish); }
+  
+    /**
+     *  Returns a read-only (constant) reverse iterator that points to the last
+     *  element in the %deque.  Iteration is done in reverse element order.
+    */
+    const_reverse_iterator
+    rbegin() const { return const_reverse_iterator(_M_finish); }
+  
+    /**
+     *  Returns a read/write reverse iterator that points to one before the
+     *  first element in the %deque.  Iteration is done in reverse element
+     *  order.
+    */
+    reverse_iterator
+    rend() { return reverse_iterator(_M_start); }
+  
+    /**
+     *  Returns a read-only (constant) reverse iterator that points to one
+     *  before the first element in the %deque.  Iteration is done in reverse
+     *  element order.
+    */
+    const_reverse_iterator
+    rend() const { return const_reverse_iterator(_M_start); }
+  
+    // [23.2.1.2] capacity
+    /**  Returns the number of elements in the %deque.  */
+    size_type
+    size() const { return _M_finish - _M_start; }
+  
+    /**  Returns the size() of the largest possible %deque.  */
+    size_type
+    max_size() const { return size_type(-1); }
+  
+    /**
+     *  @brief  Resizes the %deque to the specified number of elements.
+     *  @param  new_size  Number of elements the %deque should contain.
+     *  @param  x  Data with which new elements should be populated.
+     *
+     *  This function will %resize the %deque to the specified number of
+     *  elements.  If the number is smaller than the %deque's current size the
+     *  %deque is truncated, otherwise the %deque is extended and new elements
+     *  are populated with given data.
+    */
     void
-    _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
+    resize(size_type __new_size, const value_type& __x)
     {
-      _M_initialize_map(__n);
-      _M_fill_initialize(__x);
+      const size_type __len = size();
+      if (__new_size < __len) 
+        erase(_M_start + __new_size, _M_finish);
+      else
+        insert(_M_finish, __new_size - __len, __x);
     }
-
-  // called by the range constructor to implement [23.1.1]/9
-  template<typename _InputIter>
+  
+    /**
+     *  @brief  Resizes the %deque to the specified number of elements.
+     *  @param  new_size  Number of elements the %deque should contain.
+     *
+     *  This function will resize the %deque to the specified number of
+     *  elements.  If the number is smaller than the %deque's current size the
+     *  %deque is truncated, otherwise the %deque is extended and new elements
+     *  are default-constructed.
+    */
     void
-    _M_initialize_dispatch(_InputIter __first, _InputIter __last, __false_type)
+    resize(size_type new_size) { resize(new_size, value_type()); }
+  
+    /**
+     *  Returns true if the %deque is empty.  (Thus begin() would equal end().)
+    */
+    bool empty() const { return _M_finish == _M_start; }
+  
+    // element access
+    /**
+     *  @brief  Subscript access to the data contained in the %deque.
+     *  @param  n  The index of the element for which data should be accessed.
+     *  @return  Read/write reference to data.
+     *
+     *  This operator allows for easy, array-style, data access.
+     *  Note that data access with this operator is unchecked and out_of_range
+     *  lookups are not defined. (For checked lookups see at().)
+    */
+    reference
+    operator[](size_type __n) { return _M_start[difference_type(__n)]; }
+  
+    /**
+     *  @brief  Subscript access to the data contained in the %deque.
+     *  @param  n  The index of the element for which data should be accessed.
+     *  @return  Read-only (constant) reference to data.
+     *
+     *  This operator allows for easy, array-style, data access.
+     *  Note that data access with this operator is unchecked and out_of_range
+     *  lookups are not defined. (For checked lookups see at().)
+    */
+    const_reference
+    operator[](size_type __n) const { return _M_start[difference_type(__n)]; }
+  
+  protected:
+    /// @if maint Safety check used only from at().  @endif
+    void
+    _M_range_check(size_type __n) const
     {
-      typedef typename iterator_traits<_InputIter>::iterator_category
-                       _IterCategory;
-      _M_range_initialize(__first, __last, _IterCategory());
+      if (__n >= this->size())
+        __throw_out_of_range("deque [] access out of range");
     }
-
-  // called by the second initialize_dispatch above
-  /** @{
-   *  @if maint
-   *  @brief Fills the deque with whatever is in [first,last).
-   *  @param  first  An input iterator.
-   *  @param  last  An input iterator.
-   *  @return   Nothing.
-   *
-   *  If the iterators are actually forward iterators (or better), then the
-   *  memory layout can be done all at once.  Else we move forward using
-   *  push_back on each value from the iterator.
-   *  @endif
-  */
-  template <typename _InputIterator>
+  
+  public:
+    /**
+     *  @brief  Provides access to the data contained in the %deque.
+     *  @param  n  The index of the element for which data should be accessed.
+     *  @return  Read/write reference to data.
+     *  @throw  std::out_of_range  If @a n is an invalid index.
+     *
+     *  This function provides for safer data access.  The parameter is first
+     *  checked that it is in the range of the deque.  The function throws
+     *  out_of_range if the check fails.
+    */
+    reference
+    at(size_type __n) { _M_range_check(__n); return (*this)[__n]; }
+  
+    /**
+     *  @brief  Provides access to the data contained in the %deque.
+     *  @param  n  The index of the element for which data should be accessed.
+     *  @return  Read-only (constant) reference to data.
+     *  @throw  std::out_of_range  If @a n is an invalid index.
+     *
+     *  This function provides for safer data access.  The parameter is first
+     *  checked that it is in the range of the deque.  The function throws
+     *  out_of_range if the check fails.
+    */
+    const_reference
+    at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; }
+  
+    /**
+     *  Returns a read/write reference to the data at the first element of the
+     *  %deque.
+    */
+    reference
+    front() { return *_M_start; }
+  
+    /**
+     *  Returns a read-only (constant) reference to the data at the first
+     *  element of the %deque.
+    */
+    const_reference
+    front() const { return *_M_start; }
+  
+    /**
+     *  Returns a read/write reference to the data at the last element of the
+     *  %deque.
+    */
+    reference
+    back()
+    {
+      iterator __tmp = _M_finish;
+      --__tmp;
+      return *__tmp;
+    }
+  
+    /**
+     *  Returns a read-only (constant) reference to the data at the last
+     *  element of the %deque.
+    */
+    const_reference
+    back() const
+    {
+      const_iterator __tmp = _M_finish;
+      --__tmp;
+      return *__tmp;
+    }
+  
+    // [23.2.1.2] modifiers
+    /**
+     *  @brief  Add data to the front of the %deque.
+     *  @param  x  Data to be added.
+     *
+     *  This is a typical stack operation.  The function creates an element at
+     *  the front of the %deque and assigns the given data to it.  Due to the
+     *  nature of a %deque this operation can be done in constant time.
+    */
     void
-    _M_range_initialize(_InputIterator __first, _InputIterator __last,
-                        input_iterator_tag);
-
-  // called by the second initialize_dispatch above
-  template <typename _ForwardIterator>
+    push_front(const value_type& __x) 
+    {
+      if (_M_start._M_cur != _M_start._M_first) {
+        _Construct(_M_start._M_cur - 1, __x);
+        --_M_start._M_cur;
+      }
+      else
+        _M_push_front_aux(__x);
+    }
+  
+  #ifdef _GLIBCPP_DEPRECATED
+    /**
+     *  @brief  Add data to the front of the %deque.
+     *
+     *  This is a typical stack operation.  The function creates a
+     *  default-constructed element at the front of the %deque.  Due to the
+     *  nature of a %deque this operation can be done in constant time.  You
+     *  should consider using push_front(value_type()) instead.
+     *
+     *  @note This was deprecated in 3.2 and will be removed in 3.4.  You must
+     *        define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see
+     *        c++config.h.
+    */
     void
-    _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
-                        forward_iterator_tag);
-  /** @} */
-
-  /**
-   *  @if maint
-   *  @brief Fills the %deque with copies of value.
-   *  @param  value  Initial value.
-   *  @return   Nothing.
-   *  @pre _M_start and _M_finish have already been initialized, but none of
-   *       the %deque's elements have yet been constructed.
-   *
-   *  This function is called only when the user provides an explicit size
-   *  (with or without an explicit exemplar value).
-   *  @endif
-  */
-  void
-  _M_fill_initialize(const value_type& __value);
-
-
-  // Internal assign functions follow.  The *_aux functions do the actual
-  // assignment work for the range versions.
-
-  // called by the range assign to implement [23.1.1]/9
-  template<typename _Integer>
+    push_front()
+    {
+      if (_M_start._M_cur != _M_start._M_first) {
+        _Construct(_M_start._M_cur - 1);
+        --_M_start._M_cur;
+      }
+      else
+        _M_push_front_aux();
+    }
+  #endif
+  
+    /**
+     *  @brief  Add data to the end of the %deque.
+     *  @param  x  Data to be added.
+     *
+     *  This is a typical stack operation.  The function creates an element at
+     *  the end of the %deque and assigns the given data to it.  Due to the
+     *  nature of a %deque this operation can be done in constant time.
+    */
     void
-    _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
+    push_back(const value_type& __x)
     {
-      _M_fill_assign(static_cast<size_type>(__n),
-                     static_cast<value_type>(__val));
+      if (_M_finish._M_cur != _M_finish._M_last - 1) {
+        _Construct(_M_finish._M_cur, __x);
+        ++_M_finish._M_cur;
+      }
+      else
+        _M_push_back_aux(__x);
     }
-
-  // called by the range assign to implement [23.1.1]/9
-  template<typename _InputIter>
+  
+  #ifdef _GLIBCPP_DEPRECATED
+    /**
+     *  @brief  Add data to the end of the %deque.
+     *
+     *  This is a typical stack operation.  The function creates a
+     *  default-constructed element at the end of the %deque.  Due to the nature
+     *  of a %deque this operation can be done in constant time.  You should
+     *  consider using push_back(value_type()) instead.
+     *
+     *  @note This was deprecated in 3.2 and will be removed in 3.4.  You must
+     *        define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see
+     *        c++config.h.
+    */
     void
-    _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type)
+    push_back()
     {
-      typedef typename iterator_traits<_InputIter>::iterator_category
-                       _IterCategory;
-      _M_assign_aux(__first, __last, _IterCategory());
+      if (_M_finish._M_cur != _M_finish._M_last - 1) {
+        _Construct(_M_finish._M_cur);
+        ++_M_finish._M_cur;
+      }
+      else
+        _M_push_back_aux();
     }
-
-  // called by the second assign_dispatch above
-  template <typename _InputIterator>
+  #endif
+  
+    /**
+     *  @brief  Removes first element.
+     *
+     *  This is a typical stack operation.  It shrinks the %deque by one.
+     *
+     *  Note that no data is returned, and if the first element's data is
+     *  needed, it should be retrieved before pop_front() is called.
+    */
     void
-    _M_assign_aux(_InputIterator __first, _InputIterator __last,
-                  input_iterator_tag);
-
-  // called by the second assign_dispatch above
-  template <typename _ForwardIterator>
+    pop_front()
+    {
+      if (_M_start._M_cur != _M_start._M_last - 1) {
+        _Destroy(_M_start._M_cur);
+        ++_M_start._M_cur;
+      }
+      else 
+        _M_pop_front_aux();
+    }
+  
+    /**
+     *  @brief  Removes last element.
+     *
+     *  This is a typical stack operation.  It shrinks the %deque by one.
+     *
+     *  Note that no data is returned, and if the last element's data is
+     *  needed, it should be retrieved before pop_back() is called.
+    */
     void
-    _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
-                  forward_iterator_tag)
+    pop_back()
     {
-      size_type __len = distance(__first, __last);
-      if (__len > size()) {
-        _ForwardIterator __mid = __first;
-        advance(__mid, size());
-        copy(__first, __mid, begin());
-        insert(end(), __mid, __last);
+      if (_M_finish._M_cur != _M_finish._M_first) {
+        --_M_finish._M_cur;
+        _Destroy(_M_finish._M_cur);
       }
       else
-        erase(copy(__first, __last, begin()), end());
+        _M_pop_back_aux();
     }
-
-  // Called by assign(n,t), and the range assign when it turns out to be the
-  // same thing.
-  void
-  _M_fill_assign(size_type __n, const value_type& __val)
-  {
-    if (__n > size())
+  
+    /**
+     *  @brief  Inserts given value into %deque before specified iterator.
+     *  @param  position  An iterator into the %deque.
+     *  @param  x  Data to be inserted.
+     *  @return  An iterator that points to the inserted data.
+     *
+     *  This function will insert a copy of the given value before the specified
+     *  location.
+    */
+    iterator
+    insert(iterator position, const value_type& __x);
+  
+  #ifdef _GLIBCPP_DEPRECATED
+    /**
+     *  @brief  Inserts an element into the %deque.
+     *  @param  position  An iterator into the %deque.
+     *  @return  An iterator that points to the inserted element.
+     *
+     *  This function will insert a default-constructed element before the
+     *  specified location.  You should consider using
+     *  insert(position,value_type()) instead.
+     *
+     *  @note This was deprecated in 3.2 and will be removed in 3.4.  You must
+     *        define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see
+     *        c++config.h.
+    */
+    iterator
+    insert(iterator __position)
+      { return insert(__position, value_type()); }
+  #endif
+  
+    /**
+     *  @brief  Inserts a number of copies of given data into the %deque.
+     *  @param  position  An iterator into the %deque.
+     *  @param  n  Number of elements to be inserted.
+     *  @param  x  Data to be inserted.
+     *
+     *  This function will insert a specified number of copies of the given data
+     *  before the location specified by @a position.
+    */
+    void
+    insert(iterator __position, size_type __n, const value_type& __x)
+      { _M_fill_insert(__position, __n, __x); }
+  
+    /**
+     *  @brief  Inserts a range into the %deque.
+     *  @param  pos  An iterator into the %deque.
+     *  @param  first  An input iterator.
+     *  @param  last   An input iterator.
+     *
+     *  This function will insert copies of the data in the range [first,last)
+     *  into the %deque before the location specified by @a pos.  This is
+     *  known as "range insert."
+    */
+    template<typename _InputIterator>
+      void
+      insert(iterator __pos, _InputIterator __first, _InputIterator __last)
+      {
+        // Check whether it's an integral type.  If so, it's not an iterator.
+        typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+        _M_insert_dispatch(__pos, __first, __last, _Integral());
+      }
+  
+    /**
+     *  @brief  Remove element at given position.
+     *  @param  position  Iterator pointing to element to be erased.
+     *  @return  An iterator pointing to the next element (or end()).
+     *
+     *  This function will erase the element at the given position and thus
+     *  shorten the %deque by one.
+     *
+     *  The user is cautioned that
+     *  this function only erases the element, and that if the element is itself
+     *  a pointer, the pointed-to memory is not touched in any way.  Managing
+     *  the pointer is the user's responsibilty.
+    */
+    iterator
+    erase(iterator __position);
+  
+    /**
+     *  @brief  Remove a range of elements.
+     *  @param  first  Iterator pointing to the first element to be erased.
+     *  @param  last  Iterator pointing to one past the last element to be
+     *                erased.
+     *  @return  An iterator pointing to the element pointed to by @a last
+     *           prior to erasing (or end()).
+     *
+     *  This function will erase the elements in the range [first,last) and
+     *  shorten the %deque accordingly.
+     *
+     *  The user is cautioned that
+     *  this function only erases the elements, and that if the elements
+     *  themselves are pointers, the pointed-to memory is not touched in any
+     *  way.  Managing the pointer is the user's responsibilty.
+    */
+    iterator
+    erase(iterator __first, iterator __last);
+  
+    /**
+     *  @brief  Swaps data with another %deque.
+     *  @param  x  A %deque of the same element and allocator types.
+     *
+     *  This exchanges the elements between two deques in constant time.
+     *  (Four pointers, so it should be quite fast.)
+     *  Note that the global std::swap() function is specialized such that
+     *  std::swap(d1,d2) will feed to this function.
+    */
+    void
+    swap(deque& __x)
     {
-      fill(begin(), end(), __val);
-      insert(end(), __n - size(), __val);
+      std::swap(_M_start, __x._M_start);
+      std::swap(_M_finish, __x._M_finish);
+      std::swap(_M_map, __x._M_map);
+      std::swap(_M_map_size, __x._M_map_size);
     }
-    else
+  
+    /**
+     *  Erases all the elements.  Note that this function only erases the
+     *  elements, and that if the elements themselves are pointers, the
+     *  pointed-to memory is not touched in any way.  Managing the pointer is
+     *  the user's responsibilty.
+    */
+    void clear(); 
+  
+  protected:
+    // Internal constructor functions follow.
+  
+    // called by the range constructor to implement [23.1.1]/9
+    template<typename _Integer>
+      void
+      _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
+      {
+        _M_initialize_map(__n);
+        _M_fill_initialize(__x);
+      }
+  
+    // called by the range constructor to implement [23.1.1]/9
+    template<typename _InputIter>
+      void
+      _M_initialize_dispatch(_InputIter __first, _InputIter __last,
+                             __false_type)
+      {
+        typedef typename iterator_traits<_InputIter>::iterator_category
+                         _IterCategory;
+        _M_range_initialize(__first, __last, _IterCategory());
+      }
+  
+    // called by the second initialize_dispatch above
+    /** @{
+     *  @if maint
+     *  @brief Fills the deque with whatever is in [first,last).
+     *  @param  first  An input iterator.
+     *  @param  last  An input iterator.
+     *  @return   Nothing.
+     *
+     *  If the iterators are actually forward iterators (or better), then the
+     *  memory layout can be done all at once.  Else we move forward using
+     *  push_back on each value from the iterator.
+     *  @endif
+    */
+    template <typename _InputIterator>
+      void
+      _M_range_initialize(_InputIterator __first, _InputIterator __last,
+                          input_iterator_tag);
+  
+    // called by the second initialize_dispatch above
+    template <typename _ForwardIterator>
+      void
+      _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
+                          forward_iterator_tag);
+    /** @} */
+  
+    /**
+     *  @if maint
+     *  @brief Fills the %deque with copies of value.
+     *  @param  value  Initial value.
+     *  @return   Nothing.
+     *  @pre _M_start and _M_finish have already been initialized, but none of
+     *       the %deque's elements have yet been constructed.
+     *
+     *  This function is called only when the user provides an explicit size
+     *  (with or without an explicit exemplar value).
+     *  @endif
+    */
+    void
+    _M_fill_initialize(const value_type& __value);
+  
+  
+    // Internal assign functions follow.  The *_aux functions do the actual
+    // assignment work for the range versions.
+  
+    // called by the range assign to implement [23.1.1]/9
+    template<typename _Integer>
+      void
+      _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
+      {
+        _M_fill_assign(static_cast<size_type>(__n),
+                       static_cast<value_type>(__val));
+      }
+  
+    // called by the range assign to implement [23.1.1]/9
+    template<typename _InputIter>
+      void
+      _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type)
+      {
+        typedef typename iterator_traits<_InputIter>::iterator_category
+                         _IterCategory;
+        _M_assign_aux(__first, __last, _IterCategory());
+      }
+  
+    // called by the second assign_dispatch above
+    template <typename _InputIterator>
+      void
+      _M_assign_aux(_InputIterator __first, _InputIterator __last,
+                    input_iterator_tag);
+  
+    // called by the second assign_dispatch above
+    template <typename _ForwardIterator>
+      void
+      _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
+                    forward_iterator_tag)
+      {
+        size_type __len = distance(__first, __last);
+        if (__len > size()) {
+          _ForwardIterator __mid = __first;
+          advance(__mid, size());
+          copy(__first, __mid, begin());
+          insert(end(), __mid, __last);
+        }
+        else
+          erase(copy(__first, __last, begin()), end());
+      }
+  
+    // Called by assign(n,t), and the range assign when it turns out to be the
+    // same thing.
+    void
+    _M_fill_assign(size_type __n, const value_type& __val)
     {
-      erase(begin() + __n, end());
-      fill(begin(), end(), __val);
+      if (__n > size())
+      {
+        fill(begin(), end(), __val);
+        insert(end(), __n - size(), __val);
+      }
+      else
+      {
+        erase(begin() + __n, end());
+        fill(begin(), end(), __val);
+      }
     }
-  }
-
-
-  /** @{
-   *  @if maint
-   *  @brief Helper functions for push_* and pop_*.
-   *  @endif
-  */
-  void _M_push_back_aux(const value_type&);
-  void _M_push_front_aux(const value_type&);
-#ifdef _GLIBCPP_DEPRECATED
-  void _M_push_back_aux();
-  void _M_push_front_aux();
-#endif
-  void _M_pop_back_aux();
-  void _M_pop_front_aux();
-  /** @} */
-
-
-  // Internal insert functions follow.  The *_aux functions do the actual
-  // insertion work when all shortcuts fail.
-
-  // called by the range insert to implement [23.1.1]/9
-  template<typename _Integer>
+  
+  
+    /** @{
+     *  @if maint
+     *  @brief Helper functions for push_* and pop_*.
+     *  @endif
+    */
+    void _M_push_back_aux(const value_type&);
+    void _M_push_front_aux(const value_type&);
+  #ifdef _GLIBCPP_DEPRECATED
+    void _M_push_back_aux();
+    void _M_push_front_aux();
+  #endif
+    void _M_pop_back_aux();
+    void _M_pop_front_aux();
+    /** @} */
+  
+  
+    // Internal insert functions follow.  The *_aux functions do the actual
+    // insertion work when all shortcuts fail.
+  
+    // called by the range insert to implement [23.1.1]/9
+    template<typename _Integer>
+      void
+      _M_insert_dispatch(iterator __pos,
+                         _Integer __n, _Integer __x, __true_type)
+      {
+        _M_fill_insert(__pos, static_cast<size_type>(__n),
+                       static_cast<value_type>(__x));
+      }
+  
+    // called by the range insert to implement [23.1.1]/9
+    template<typename _InputIterator>
+      void
+      _M_insert_dispatch(iterator __pos,
+                         _InputIterator __first, _InputIterator __last,
+                         __false_type)
+      {
+        typedef typename iterator_traits<_InputIterator>::iterator_category
+                         _IterCategory;
+        _M_range_insert_aux(__pos, __first, __last, _IterCategory());
+      }
+  
+    // called by the second insert_dispatch above
+    template <typename _InputIterator>
+      void
+      _M_range_insert_aux(iterator __pos, _InputIterator __first,
+                          _InputIterator __last, input_iterator_tag);
+  
+    // called by the second insert_dispatch above
+    template <typename _ForwardIterator>
+      void
+      _M_range_insert_aux(iterator __pos, _ForwardIterator __first,
+                          _ForwardIterator __last, forward_iterator_tag);
+  
+    // Called by insert(p,n,x), and the range insert when it turns out to be
+    // the same thing.  Can use fill functions in optimal situations, otherwise
+    // passes off to insert_aux(p,n,x).
+    void
+    _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); 
+  
+    // called by insert(p,x)
+    iterator
+    _M_insert_aux(iterator __pos, const value_type& __x);
+  
+    // called by insert(p,n,x) via fill_insert
     void
-    _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, __true_type)
+    _M_insert_aux(iterator __pos, size_type __n, const value_type& __x);
+  
+    // called by range_insert_aux for forward iterators
+    template <typename _ForwardIterator>
+      void
+      _M_insert_aux(iterator __pos, 
+                    _ForwardIterator __first, _ForwardIterator __last,
+                    size_type __n);
+  
+  #ifdef _GLIBCPP_DEPRECATED
+    // unused, see comment in implementation
+    iterator _M_insert_aux(iterator __pos);
+  #endif
+  
+    /** @{
+     *  @if maint
+     *  @brief Memory-handling helpers for the previous internal insert
+     *         functions.
+     *  @endif
+    */
+    iterator
+    _M_reserve_elements_at_front(size_type __n)
     {
-      _M_fill_insert(__pos, static_cast<size_type>(__n),
-                     static_cast<value_type>(__x));
+      size_type __vacancies = _M_start._M_cur - _M_start._M_first;
+      if (__n > __vacancies) 
+        _M_new_elements_at_front(__n - __vacancies);
+      return _M_start - difference_type(__n);
     }
-
-  // called by the range insert to implement [23.1.1]/9
-  template<typename _InputIterator>
-    void
-    _M_insert_dispatch(iterator __pos,
-                       _InputIterator __first, _InputIterator __last,
-                       __false_type)
+  
+    iterator
+    _M_reserve_elements_at_back(size_type __n)
     {
-      typedef typename iterator_traits<_InputIterator>::iterator_category
-                       _IterCategory;
-      _M_range_insert_aux(__pos, __first, __last, _IterCategory());
+      size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1;
+      if (__n > __vacancies)
+        _M_new_elements_at_back(__n - __vacancies);
+      return _M_finish + difference_type(__n);
     }
-
-  // called by the second insert_dispatch above
-  template <typename _InputIterator>
+  
     void
-    _M_range_insert_aux(iterator __pos, _InputIterator __first,
-                        _InputIterator __last, input_iterator_tag);
-
-  // called by the second insert_dispatch above
-  template <typename _ForwardIterator>
+    _M_new_elements_at_front(size_type __new_elements);
+  
     void
-    _M_range_insert_aux(iterator __pos, _ForwardIterator __first,
-                        _ForwardIterator __last, forward_iterator_tag);
-
-  // Called by insert(p,n,x), and the range insert when it turns out to be
-  // the same thing.  Can use fill functions in optimal situations, otherwise
-  // passes off to insert_aux(p,n,x).
-  void
-  _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); 
-
-  // called by insert(p,x)
-  iterator
-  _M_insert_aux(iterator __pos, const value_type& __x);
-
-  // called by insert(p,n,x) via fill_insert
-  void
-  _M_insert_aux(iterator __pos, size_type __n, const value_type& __x);
-
-  // called by range_insert_aux for forward iterators
-  template <typename _ForwardIterator>
+    _M_new_elements_at_back(size_type __new_elements);
+    /** @} */
+  
+  
+    /** @{
+     *  @if maint
+     *  @brief Memory-handling helpers for the major %map.
+     *
+     *  Makes sure the _M_map has space for new nodes.  Does not actually add
+     *  the nodes.  Can invalidate _M_map pointers.  (And consequently, %deque
+     *  iterators.)
+     *  @endif
+    */
     void
-    _M_insert_aux(iterator __pos, 
-                  _ForwardIterator __first, _ForwardIterator __last,
-                  size_type __n);
-
-#ifdef _GLIBCPP_DEPRECATED
-  // unused, see comment in implementation
-  iterator _M_insert_aux(iterator __pos);
-#endif
-
-  /** @{
-   *  @if maint
-   *  @brief Memory-handling helpers for the previous internal insert functions.
-   *  @endif
+    _M_reserve_map_at_back (size_type __nodes_to_add = 1)
+    {
+      if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map))
+        _M_reallocate_map(__nodes_to_add, false);
+    }
+  
+    void
+    _M_reserve_map_at_front (size_type __nodes_to_add = 1)
+    {
+      if (__nodes_to_add > size_type(_M_start._M_node - _M_map))
+        _M_reallocate_map(__nodes_to_add, true);
+    }
+  
+    void
+    _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front);
+    /** @} */
+  };
+  
+  
+  /**
+   *  @brief  Deque equality comparison.
+   *  @param  x  A %deque.
+   *  @param  y  A %deque of the same type as @a x.
+   *  @return  True iff the size and elements of the deques are equal.
+   *
+   *  This is an equivalence relation.  It is linear in the size of the
+   *  deques.  Deques are considered equivalent if their sizes are equal,
+   *  and if corresponding elements compare equal.
   */
-  iterator
-  _M_reserve_elements_at_front(size_type __n)
-  {
-    size_type __vacancies = _M_start._M_cur - _M_start._M_first;
-    if (__n > __vacancies) 
-      _M_new_elements_at_front(__n - __vacancies);
-    return _M_start - difference_type(__n);
-  }
-
-  iterator
-  _M_reserve_elements_at_back(size_type __n)
+  template <typename _Tp, typename _Alloc>
+  inline bool operator==(const deque<_Tp, _Alloc>& __x,
+                         const deque<_Tp, _Alloc>& __y)
   {
-    size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1;
-    if (__n > __vacancies)
-      _M_new_elements_at_back(__n - __vacancies);
-    return _M_finish + difference_type(__n);
+    return __x.size() == __y.size() &&
+           equal(__x.begin(), __x.end(), __y.begin());
   }
-
-  void
-  _M_new_elements_at_front(size_type __new_elements);
-
-  void
-  _M_new_elements_at_back(size_type __new_elements);
-  /** @} */
-
-
-  /** @{
-   *  @if maint
-   *  @brief Memory-handling helpers for the major %map.
+  
+  /**
+   *  @brief  Deque ordering relation.
+   *  @param  x  A %deque.
+   *  @param  y  A %deque of the same type as @a x.
+   *  @return  True iff @a x is lexographically less than @a y.
    *
-   *  Makes sure the _M_map has space for new nodes.  Does not actually add
-   *  the nodes.  Can invalidate _M_map pointers.  (And consequently, %deque
-   *  iterators.)
-   *  @endif
+   *  This is a total ordering relation.  It is linear in the size of the
+   *  deques.  The elements must be comparable with @c <.
+   *
+   *  See std::lexographical_compare() for how the determination is made.
   */
-  void
-  _M_reserve_map_at_back (size_type __nodes_to_add = 1)
+  template <typename _Tp, typename _Alloc>
+  inline bool operator<(const deque<_Tp, _Alloc>& __x,
+                        const deque<_Tp, _Alloc>& __y)
   {
-    if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map))
-      _M_reallocate_map(__nodes_to_add, false);
+    return lexicographical_compare(__x.begin(), __x.end(), 
+                                   __y.begin(), __y.end());
   }
-
-  void
-  _M_reserve_map_at_front (size_type __nodes_to_add = 1)
+  
+  /// Based on operator==
+  template <typename _Tp, typename _Alloc>
+  inline bool operator!=(const deque<_Tp, _Alloc>& __x,
+                         const deque<_Tp, _Alloc>& __y) {
+    return !(__x == __y);
+  }
+  
+  /// Based on operator<
+  template <typename _Tp, typename _Alloc>
+  inline bool operator>(const deque<_Tp, _Alloc>& __x,
+                        const deque<_Tp, _Alloc>& __y) {
+    return __y < __x;
+  }
+  
+  /// Based on operator<
+  template <typename _Tp, typename _Alloc>
+  inline bool operator<=(const deque<_Tp, _Alloc>& __x,
+                         const deque<_Tp, _Alloc>& __y) {
+    return !(__y < __x);
+  }
+  
+  /// Based on operator<
+  template <typename _Tp, typename _Alloc>
+  inline bool operator>=(const deque<_Tp, _Alloc>& __x,
+                         const deque<_Tp, _Alloc>& __y) {
+    return !(__x < __y);
+  }
+  
+  /// See std::deque::swap().
+  template <typename _Tp, typename _Alloc>
+  inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y)
   {
-    if (__nodes_to_add > size_type(_M_start._M_node - _M_map))
-      _M_reallocate_map(__nodes_to_add, true);
+    __x.swap(__y);
   }
-
-  void
-  _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front);
-  /** @} */
-};
-
-
-/**
- *  @brief  Deque equality comparison.
- *  @param  x  A %deque.
- *  @param  y  A %deque of the same type as @a x.
- *  @return  True iff the size and elements of the deques are equal.
- *
- *  This is an equivalence relation.  It is linear in the size of the
- *  deques.  Deques are considered equivalent if their sizes are equal,
- *  and if corresponding elements compare equal.
-*/
-template <typename _Tp, typename _Alloc>
-inline bool operator==(const deque<_Tp, _Alloc>& __x,
-                       const deque<_Tp, _Alloc>& __y)
-{
-  return __x.size() == __y.size() &&
-         equal(__x.begin(), __x.end(), __y.begin());
-}
-
-/**
- *  @brief  Deque ordering relation.
- *  @param  x  A %deque.
- *  @param  y  A %deque of the same type as @a x.
- *  @return  True iff @a x is lexographically less than @a y.
- *
- *  This is a total ordering relation.  It is linear in the size of the
- *  deques.  The elements must be comparable with @c <.
- *
- *  See std::lexographical_compare() for how the determination is made.
-*/
-template <typename _Tp, typename _Alloc>
-inline bool operator<(const deque<_Tp, _Alloc>& __x,
-                      const deque<_Tp, _Alloc>& __y)
-{
-  return lexicographical_compare(__x.begin(), __x.end(), 
-                                 __y.begin(), __y.end());
-}
-
-/// Based on operator==
-template <typename _Tp, typename _Alloc>
-inline bool operator!=(const deque<_Tp, _Alloc>& __x,
-                       const deque<_Tp, _Alloc>& __y) {
-  return !(__x == __y);
-}
-
-/// Based on operator<
-template <typename _Tp, typename _Alloc>
-inline bool operator>(const deque<_Tp, _Alloc>& __x,
-                      const deque<_Tp, _Alloc>& __y) {
-  return __y < __x;
-}
-
-/// Based on operator<
-template <typename _Tp, typename _Alloc>
-inline bool operator<=(const deque<_Tp, _Alloc>& __x,
-                       const deque<_Tp, _Alloc>& __y) {
-  return !(__y < __x);
-}
-
-/// Based on operator<
-template <typename _Tp, typename _Alloc>
-inline bool operator>=(const deque<_Tp, _Alloc>& __x,
-                       const deque<_Tp, _Alloc>& __y) {
-  return !(__x < __y);
-}
-
-/// See std::deque::swap().
-template <typename _Tp, typename _Alloc>
-inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y)
-{
-  __x.swap(__y);
-}
-
 } // namespace std 
   
 #endif /* __GLIBCPP_INTERNAL_DEQUE_H */
-
index 8389f5e..7c245d0 100644 (file)
 #pragma GCC system_header
 #include <bits/concept_check.h>
 
-// Since this entire file is within namespace std, there's no reason to
-// waste two spaces along the left column.  Thus the leading indentation is
-// slightly violated from here on.
 namespace std
 {
-template<typename _InputIterator>
-  inline typename iterator_traits<_InputIterator>::difference_type
-  __distance(_InputIterator __first, _InputIterator __last, input_iterator_tag)
-  {
-    // concept requirements
-    __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>)
-
-    typename iterator_traits<_InputIterator>::difference_type __n = 0;
-    while (__first != __last) {
-      ++__first; ++__n;
+  template<typename _InputIterator>
+    inline typename iterator_traits<_InputIterator>::difference_type
+    __distance(_InputIterator __first, _InputIterator __last,
+               input_iterator_tag)
+    {
+      // concept requirements
+      __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>)
+  
+      typename iterator_traits<_InputIterator>::difference_type __n = 0;
+      while (__first != __last) {
+        ++__first; ++__n;
+      }
+      return __n;
     }
-    return __n;
-  }
-
-template<typename _RandomAccessIterator>
-  inline typename iterator_traits<_RandomAccessIterator>::difference_type
-  __distance(_RandomAccessIterator __first, _RandomAccessIterator __last,
-             random_access_iterator_tag)
-  {
-    // concept requirements
-    __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>)
-    return __last - __first;
-  }
-
-/**
- *  @brief A generalization of pointer arithmetic.
- *  @param  first  An input iterator.
- *  @param  last  An input iterator.
- *  @return  The distance between them.
- *
- *  Returns @c n such that first + n == last.  This requires that @p last
- *  must be reachable from @p first.  Note that @c n may be negative.
- *
- *  For random access iterators, this uses their @c + and @c - operations
- *  and are constant time.  For other %iterator classes they are linear time.
-*/
-template<typename _InputIterator>
-  inline typename iterator_traits<_InputIterator>::difference_type
-  distance(_InputIterator __first, _InputIterator __last)
-  {
-    // concept requirements -- taken care of in __distance
-    return __distance(__first, __last, __iterator_category(__first));
-  }
-
-template<typename _InputIter, typename _Distance>
-  inline void
-  __advance(_InputIter& __i, _Distance __n, input_iterator_tag)
-  {
-    // concept requirements
-    __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
-    while (__n--) ++__i;
-  }
-
-template<typename _BidirectionalIterator, typename _Distance>
-  inline void
-  __advance(_BidirectionalIterator& __i, _Distance __n,
-            bidirectional_iterator_tag)
-  {
-    // concept requirements
-    __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIterator>)
-
-    if (__n > 0)
+  
+  template<typename _RandomAccessIterator>
+    inline typename iterator_traits<_RandomAccessIterator>::difference_type
+    __distance(_RandomAccessIterator __first, _RandomAccessIterator __last,
+               random_access_iterator_tag)
+    {
+      // concept requirements
+      __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>)
+      return __last - __first;
+    }
+  
+  /**
+   *  @brief A generalization of pointer arithmetic.
+   *  @param  first  An input iterator.
+   *  @param  last  An input iterator.
+   *  @return  The distance between them.
+   *
+   *  Returns @c n such that first + n == last.  This requires that @p last
+   *  must be reachable from @p first.  Note that @c n may be negative.
+   *
+   *  For random access iterators, this uses their @c + and @c - operations
+   *  and are constant time.  For other %iterator classes they are linear time.
+  */
+  template<typename _InputIterator>
+    inline typename iterator_traits<_InputIterator>::difference_type
+    distance(_InputIterator __first, _InputIterator __last)
+    {
+      // concept requirements -- taken care of in __distance
+      return __distance(__first, __last, __iterator_category(__first));
+    }
+  
+  template<typename _InputIter, typename _Distance>
+    inline void
+    __advance(_InputIter& __i, _Distance __n, input_iterator_tag)
+    {
+      // concept requirements
+      __glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
       while (__n--) ++__i;
-    else
-      while (__n++) --__i;
-  }
-
-template<typename _RandomAccessIterator, typename _Distance>
-  inline void
-  __advance(_RandomAccessIterator& __i, _Distance __n,
-            random_access_iterator_tag)
-  {
-    // concept requirements
-    __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>)
-    __i += __n;
-  }
-
-/**
- *  @brief A generalization of pointer arithmetic.
- *  @param  i  An input iterator.
- *  @param  n  The "delta" by which to change @p i.
- *  @return  Nothing.
- *
- *  This increments @p i by @p n.  For bidirectional and random access
- *  iterators, @p n may be negative, in which case @p i is decremented.
- *
- *  For random access iterators, this uses their @c + and @c - operations
- *  and are constant time.  For other %iterator classes they are linear time.
-*/
-template<typename _InputIterator, typename _Distance>
-  inline void
-  advance(_InputIterator& __i, _Distance __n)
-  {
-    // concept requirements -- taken care of in __advance
-    __advance(__i, __n, __iterator_category(__i));
-  }
-
+    }
+  
+  template<typename _BidirectionalIterator, typename _Distance>
+    inline void
+    __advance(_BidirectionalIterator& __i, _Distance __n,
+              bidirectional_iterator_tag)
+    {
+      // concept requirements
+      __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIterator>)
+  
+      if (__n > 0)
+        while (__n--) ++__i;
+      else
+        while (__n++) --__i;
+    }
+  
+  template<typename _RandomAccessIterator, typename _Distance>
+    inline void
+    __advance(_RandomAccessIterator& __i, _Distance __n,
+              random_access_iterator_tag)
+    {
+      // concept requirements
+      __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>)
+      __i += __n;
+    }
+  
+  /**
+   *  @brief A generalization of pointer arithmetic.
+   *  @param  i  An input iterator.
+   *  @param  n  The "delta" by which to change @p i.
+   *  @return  Nothing.
+   *
+   *  This increments @p i by @p n.  For bidirectional and random access
+   *  iterators, @p n may be negative, in which case @p i is decremented.
+   *
+   *  For random access iterators, this uses their @c + and @c - operations
+   *  and are constant time.  For other %iterator classes they are linear time.
+  */
+  template<typename _InputIterator, typename _Distance>
+    inline void
+    advance(_InputIterator& __i, _Distance __n)
+    {
+      // concept requirements -- taken care of in __advance
+      __advance(__i, __n, __iterator_category(__i));
+    }
 } // namespace std
 
 #endif /* __GLIBCPP_INTERNAL_ITERATOR_BASE_FUNCS_H */
-
-
-// Local Variables:
-// mode:C++
-// End:
index e55c337..9051d2c 100644 (file)
 
 #include <bits/concept_check.h>
 
-// Since this entire file is within namespace std, there's no reason to
-// waste two spaces along the left column.  Thus the leading indentation is
-// slightly violated from here on.
 namespace std
 {
-
-// Supporting structures are split into common and templated types; the
-// latter publicly inherits from the former in an effort to reduce code
-// duplication.  This results in some "needless" static_cast'ing later on,
-// but it's all safe downcasting.
-
-/// @if maint Common part of a node in the %list.  @endif
-struct _List_node_base
-{
-  _List_node_base* _M_next;   ///< Self-explanatory
-  _List_node_base* _M_prev;   ///< Self-explanatory
-};
-
-/// @if maint An actual node in the %list.  @endif
-template<typename _Tp>
-  struct _List_node : public _List_node_base
-{
-  _Tp _M_data;                ///< User's data.
-};
-
-
-/**
- *  @if maint
- *  @brief Common part of a list::iterator.
- *
- *  A simple type to walk a doubly-linked list.  All operations here should
- *  be self-explanatory after taking any decent introductory data structures
- *  course.
- *  @endif
-*/
-struct _List_iterator_base
-{
-  typedef size_t                        size_type;
-  typedef ptrdiff_t                     difference_type;
-  typedef bidirectional_iterator_tag    iterator_category;
-
-  /// The only member points to the %list element.
-  _List_node_base* _M_node;
-
-  _List_iterator_base(_List_node_base* __x)
-  : _M_node(__x)
-  { }
-
-  _List_iterator_base()
-  { }
-
-  /// Walk the %list forward.
-  void
-  _M_incr()
-    { _M_node = _M_node->_M_next; }
-
-  /// Walk the %list backward.
-  void
-  _M_decr()
-    { _M_node = _M_node->_M_prev; }
-
-  bool
-  operator==(const _List_iterator_base& __x) const
-    { return _M_node == __x._M_node; }
-
-  bool
-  operator!=(const _List_iterator_base& __x) const
-    { return _M_node != __x._M_node; }
-};
-
-/**
- *  @brief A list::iterator.
- *
- *  In addition to being used externally, a list holds one of these internally,
- *  pointing to the sequence of data.
- *
- *  @if maint
- *  All the functions are op overloads.
- *  @endif
-*/
-template<typename _Tp, typename _Ref, typename _Ptr>
-  struct _List_iterator : public _List_iterator_base
-{
-  typedef _List_iterator<_Tp,_Tp&,_Tp*>             iterator;
-  typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
-  typedef _List_iterator<_Tp,_Ref,_Ptr>             _Self;
-
-  typedef _Tp                                       value_type;
-  typedef _Ptr                                      pointer;
-  typedef _Ref                                      reference;
-  typedef _List_node<_Tp>                           _Node;
-
-  _List_iterator(_Node* __x)
-  : _List_iterator_base(__x)
-  { }
-
-  _List_iterator()
-  { }
-
-  _List_iterator(const iterator& __x)
-  : _List_iterator_base(__x._M_node)
-  { }
-
-  reference
-  operator*() const
-    { return static_cast<_Node*>(_M_node)->_M_data; }
-    // Must downcast from List_node_base to _List_node to get to _M_data.
-
-  pointer
-  operator->() const
-    { return &(operator*()); }
-
-  _Self&
-  operator++()
+  // Supporting structures are split into common and templated types; the
+  // latter publicly inherits from the former in an effort to reduce code
+  // duplication.  This results in some "needless" static_cast'ing later on,
+  // but it's all safe downcasting.
+  
+  /// @if maint Common part of a node in the %list.  @endif
+  struct _List_node_base
   {
-    this->_M_incr();
-    return *this;
-  }
-
-  _Self
-  operator++(int)
+    _List_node_base* _M_next;   ///< Self-explanatory
+    _List_node_base* _M_prev;   ///< Self-explanatory
+  };
+  
+  /// @if maint An actual node in the %list.  @endif
+  template<typename _Tp>
+    struct _List_node : public _List_node_base
   {
-    _Self __tmp = *this;
-    this->_M_incr();
-    return __tmp;
-  }
-
-  _Self&
-  operator--()
-  {
-    this->_M_decr();
-    return *this;
-  }
-
-  _Self
-  operator--(int)
-  {
-    _Self __tmp = *this;
-    this->_M_decr();
-    return __tmp;
-  }
-};
-
-
-/// @if maint Primary default version.  @endif
-/**
- *  @if maint
- *  See bits/stl_deque.h's _Deque_alloc_base for an explanation.
- *  @endif
-*/
-template<typename _Tp, typename _Allocator, bool _IsStatic>
-  class _List_alloc_base
-{
-public:
-  typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
-          allocator_type;
-
-  allocator_type
-  get_allocator() const { return _M_node_allocator; }
-
-  _List_alloc_base(const allocator_type& __a)
-  : _M_node_allocator(__a)
-  { }
-
-protected:
-  _List_node<_Tp>*
-  _M_get_node()
-    { return _M_node_allocator.allocate(1); }
-
-  void
-  _M_put_node(_List_node<_Tp>* __p)
-    { _M_node_allocator.deallocate(__p, 1); }
-
-  // NOTA BENE
-  // The stored instance is not actually of "allocator_type"'s type.  Instead
-  // we rebind the type to Allocator<List_node<Tp>>, which according to
-  // [20.1.5]/4 should probably be the same.  List_node<Tp> is not the same
-  // size as Tp (it's two pointers larger), and specializations on Tp may go
-  // unused because List_node<Tp> is being bound instead.
-  //
-  // We put this to the test in get_allocator above; if the two types are
-  // actually different, there had better be a conversion between them.
-  //
-  // None of the predefined allocators shipped with the library (as of 3.1)
-  // use this instantiation anyhow; they're all instanceless.
-  typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type
-           _M_node_allocator;
-
-  _List_node<_Tp>* _M_node;
-};
-
-/// @if maint Specialization for instanceless allocators.  @endif
-template<typename _Tp, typename _Allocator>
-  class _List_alloc_base<_Tp, _Allocator, true>
-{
-public:
-  typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
-          allocator_type;
-
-  allocator_type
-  get_allocator() const { return allocator_type(); }
-
-  _List_alloc_base(const allocator_type&)
-  { }
-
-protected:
-  // See comment in primary template class about why this is safe for the
-  // standard predefined classes.
-  typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type
-          _Alloc_type;
-
-  _List_node<_Tp>*
-  _M_get_node()
-    { return _Alloc_type::allocate(1); }
-
-  void
-  _M_put_node(_List_node<_Tp>* __p)
-    { _Alloc_type::deallocate(__p, 1); }
-
-  _List_node<_Tp>* _M_node;
-};
-
-
-/**
- *  @if maint
- *  See bits/stl_deque.h's _Deque_base for an explanation.
- *  @endif
-*/
-template <typename _Tp, typename _Alloc>
-  class _List_base
-  : public _List_alloc_base<_Tp, _Alloc,
-                            _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
-{
-public:
-  typedef _List_alloc_base<_Tp, _Alloc,
-                           _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
-          _Base;
-  typedef typename _Base::allocator_type allocator_type;
-
-  _List_base(const allocator_type& __a)
-  : _Base(__a)
-  {
-    _M_node = _M_get_node();
-    _M_node->_M_next = _M_node;
-    _M_node->_M_prev = _M_node;
-  }
-
-  // This is what actually destroys the list.
-  ~_List_base()
-  {
-    __clear();
-    _M_put_node(_M_node);
-  }
-
-  void
-  __clear();
-};
-
-
-/**
- *  @brief  A standard container with linear time access to elements, and
- *  fixed time insertion/deletion at any point in the sequence.
- *
- *  @ingroup Containers
- *  @ingroup Sequences
- *
- *  Meets the requirements of a <a href="tables.html#65">container</a>, a
- *  <a href="tables.html#66">reversible container</a>, and a
- *  <a href="tables.html#67">sequence</a>, including the
- *  <a href="tables.html#68">optional sequence requirements</a> with the
- *  %exception of @c at and @c operator[].
- *
- *  This is a @e doubly @e linked %list.  Traversal up and down the %list
- *  requires linear time, but adding and removing elements (or @e nodes) is
- *  done in constant time, regardless of where the change takes place.
- *  Unlike std::vector and std::deque, random-access iterators are not
- *  provided, so subscripting ( @c [] ) access is not allowed.  For algorithms
- *  which only need sequential access, this lack makes no difference.
- *
- *  Also unlike the other standard containers, std::list provides specialized 
- *  algorithms %unique to linked lists, such as splicing, sorting, and
- *  in-place reversal.
- *
- *  @if maint
- *  A couple points on memory allocation for list<Tp>:
- *
- *  First, we never actually allocate a Tp, we actally allocate List_node<Tp>'s
- *  and trust [20.1.5]/4 to DTRT.  This is to ensure that after elements from
- *  %list<X,Alloc1> are spliced into %list<X,Alloc2>, destroying the memory of
- *  the second %list is a valid operation, i.e., Alloc1 giveth and Alloc2
- *  taketh away.
- *
- *  Second, a %list conceptually represented as
- *  @code
- *    A <---> B <---> C <---> D
- *  @endcode
- *  is actually circular; a link exists between A and D.  The %list class
- *  holds (as its only data member) a private list::iterator pointing to
- *  @e D, not to @e A!  To get to the head of the %list, we start at the tail
- *  and move forward by one.  When this member iterator's next/previous
- *  pointers refer to itself, the %list is %empty.
- *  @endif
-*/
-template<typename _Tp, typename _Alloc = allocator<_Tp> >
-  class list : protected _List_base<_Tp, _Alloc>
-{
-  // concept requirements
-  __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
-
-  typedef _List_base<_Tp, _Alloc>                       _Base;
-
-public:
-  typedef _Tp                                           value_type;
-  typedef value_type*                                   pointer;
-  typedef const value_type*                             const_pointer;
-  typedef _List_iterator<_Tp,_Tp&,_Tp*>                 iterator;
-  typedef _List_iterator<_Tp,const _Tp&,const _Tp*>     const_iterator;
-  typedef reverse_iterator<const_iterator>              const_reverse_iterator;
-  typedef reverse_iterator<iterator>                    reverse_iterator;
-  typedef value_type&                                   reference;
-  typedef const value_type&                             const_reference;
-  typedef size_t                                        size_type;
-  typedef ptrdiff_t                                     difference_type;
-  typedef typename _Base::allocator_type                allocator_type;
-
-protected:
-  // Note that pointers-to-_Node's can be ctor-converted to iterator types.
-  typedef _List_node<_Tp>                               _Node;
-
-  /** @if maint
-   *  One data member plus two memory-handling functions.  If the _Alloc
-   *  type requires separate instances, then one of those will also be
-   *  included, accumulated from the topmost parent.
-   *  @endif
-  */
-  using _Base::_M_node;
-  using _Base::_M_put_node;
-  using _Base::_M_get_node;
-
+    _Tp _M_data;                ///< User's data.
+  };
+  
+  
   /**
    *  @if maint
-   *  @param  x  An instance of user data.
+   *  @brief Common part of a list::iterator.
    *
-   *  Allocates space for a new node and constructs a copy of @a x in it.
+   *  A simple type to walk a doubly-linked list.  All operations here should
+   *  be self-explanatory after taking any decent introductory data structures
+   *  course.
    *  @endif
   */
-  _Node*
-  _M_create_node(const value_type& __x)
+  struct _List_iterator_base
   {
-    _Node* __p = _M_get_node();
-    try {
-      _Construct(&__p->_M_data, __x);
-    }
-    catch(...)
-    {
-      _M_put_node(__p);
-      __throw_exception_again;
-    }
-    return __p;
-  }
-
+    typedef size_t                        size_type;
+    typedef ptrdiff_t                     difference_type;
+    typedef bidirectional_iterator_tag    iterator_category;
+  
+    /// The only member points to the %list element.
+    _List_node_base* _M_node;
+  
+    _List_iterator_base(_List_node_base* __x)
+    : _M_node(__x)
+    { }
+  
+    _List_iterator_base()
+    { }
+  
+    /// Walk the %list forward.
+    void
+    _M_incr()
+      { _M_node = _M_node->_M_next; }
+  
+    /// Walk the %list backward.
+    void
+    _M_decr()
+      { _M_node = _M_node->_M_prev; }
+  
+    bool
+    operator==(const _List_iterator_base& __x) const
+      { return _M_node == __x._M_node; }
+  
+    bool
+    operator!=(const _List_iterator_base& __x) const
+      { return _M_node != __x._M_node; }
+  };
+  
   /**
+   *  @brief A list::iterator.
+   *
+   *  In addition to being used externally, a list holds one of these
+   *  internally, pointing to the sequence of data.
+   *
    *  @if maint
-   *  Allocates space for a new node and default-constructs a new instance
-   *  of @c value_type in it.
+   *  All the functions are op overloads.
    *  @endif
   */
-  _Node*
-  _M_create_node()
+  template<typename _Tp, typename _Ref, typename _Ptr>
+    struct _List_iterator : public _List_iterator_base
   {
-    _Node* __p = _M_get_node();
-    try {
-      _Construct(&__p->_M_data);
+    typedef _List_iterator<_Tp,_Tp&,_Tp*>             iterator;
+    typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
+    typedef _List_iterator<_Tp,_Ref,_Ptr>             _Self;
+  
+    typedef _Tp                                       value_type;
+    typedef _Ptr                                      pointer;
+    typedef _Ref                                      reference;
+    typedef _List_node<_Tp>                           _Node;
+  
+    _List_iterator(_Node* __x)
+    : _List_iterator_base(__x)
+    { }
+  
+    _List_iterator()
+    { }
+  
+    _List_iterator(const iterator& __x)
+    : _List_iterator_base(__x._M_node)
+    { }
+  
+    reference
+    operator*() const
+      { return static_cast<_Node*>(_M_node)->_M_data; }
+      // Must downcast from List_node_base to _List_node to get to _M_data.
+  
+    pointer
+    operator->() const
+      { return &(operator*()); }
+  
+    _Self&
+    operator++()
+    {
+      this->_M_incr();
+      return *this;
     }
-    catch(...)
+  
+    _Self
+    operator++(int)
     {
-      _M_put_node(__p);
-      __throw_exception_again;
+      _Self __tmp = *this;
+      this->_M_incr();
+      return __tmp;
     }
-    return __p;
-  }
-
-public:
-  // [23.2.2.1] construct/copy/destroy
-  // (assign() and get_allocator() are also listed in this section)
-  /**
-   *  @brief  Default constructor creates no elements.
-  */
-  explicit
-  list(const allocator_type& __a = allocator_type())
-  : _Base(__a) { }
-
-  /**
-   *  @brief  Create a %list with copies of an exemplar element.
-   *  @param  n  The number of elements to initially create.
-   *  @param  value  An element to copy.
-   * 
-   *  This constructor fills the %list with @a n copies of @a value.
-  */
-  list(size_type __n, const value_type& __value,
-       const allocator_type& __a = allocator_type())
-    : _Base(__a)
-    { this->insert(begin(), __n, __value); }
-
-  /**
-   *  @brief  Create a %list with default elements.
-   *  @param  n  The number of elements to initially create.
-   * 
-   *  This constructor fills the %list with @a n copies of a
-   *  default-constructed element.
-  */
-  explicit
-  list(size_type __n)
-    : _Base(allocator_type())
-    { this->insert(begin(), __n, value_type()); }
-
+  
+    _Self&
+    operator--()
+    {
+      this->_M_decr();
+      return *this;
+    }
+  
+    _Self
+    operator--(int)
+    {
+      _Self __tmp = *this;
+      this->_M_decr();
+      return __tmp;
+    }
+  };
+  
+  
+  /// @if maint Primary default version.  @endif
   /**
-   *  @brief  %List copy constructor.
-   *  @param  x  A %list of identical element and allocator types.
-   * 
-   *  The newly-created %list uses a copy of the allocation object used
-   *  by @a x.
+   *  @if maint
+   *  See bits/stl_deque.h's _Deque_alloc_base for an explanation.
+   *  @endif
   */
-  list(const list& __x)
-    : _Base(__x.get_allocator())
-    { this->insert(begin(), __x.begin(), __x.end()); }
-
+  template<typename _Tp, typename _Allocator, bool _IsStatic>
+    class _List_alloc_base
+  {
+  public:
+    typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
+            allocator_type;
+  
+    allocator_type
+    get_allocator() const { return _M_node_allocator; }
+  
+    _List_alloc_base(const allocator_type& __a)
+    : _M_node_allocator(__a)
+    { }
+  
+  protected:
+    _List_node<_Tp>*
+    _M_get_node()
+      { return _M_node_allocator.allocate(1); }
+  
+    void
+    _M_put_node(_List_node<_Tp>* __p)
+      { _M_node_allocator.deallocate(__p, 1); }
+  
+    // NOTA BENE
+    // The stored instance is not actually of "allocator_type"'s type.  Instead
+    // we rebind the type to Allocator<List_node<Tp>>, which according to
+    // [20.1.5]/4 should probably be the same.  List_node<Tp> is not the same
+    // size as Tp (it's two pointers larger), and specializations on Tp may go
+    // unused because List_node<Tp> is being bound instead.
+    //
+    // We put this to the test in get_allocator above; if the two types are
+    // actually different, there had better be a conversion between them.
+    //
+    // None of the predefined allocators shipped with the library (as of 3.1)
+    // use this instantiation anyhow; they're all instanceless.
+    typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type
+             _M_node_allocator;
+  
+    _List_node<_Tp>* _M_node;
+  };
+  
+  /// @if maint Specialization for instanceless allocators.  @endif
+  template<typename _Tp, typename _Allocator>
+    class _List_alloc_base<_Tp, _Allocator, true>
+  {
+  public:
+    typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
+            allocator_type;
+  
+    allocator_type
+    get_allocator() const { return allocator_type(); }
+  
+    _List_alloc_base(const allocator_type&)
+    { }
+  
+  protected:
+    // See comment in primary template class about why this is safe for the
+    // standard predefined classes.
+    typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type
+            _Alloc_type;
+  
+    _List_node<_Tp>*
+    _M_get_node()
+      { return _Alloc_type::allocate(1); }
+  
+    void
+    _M_put_node(_List_node<_Tp>* __p)
+      { _Alloc_type::deallocate(__p, 1); }
+  
+    _List_node<_Tp>* _M_node;
+  };
+  
+  
   /**
-   *  @brief  Builds a %list from a range.
-   *  @param  first  An input iterator.
-   *  @param  last  An input iterator.
-   * 
-   *  Create a %list consisting of copies of the elements from [first,last).
-   *  This is linear in N (where N is distance(first,last)).
-   *
    *  @if maint
-   *  We don't need any dispatching tricks here, because insert does all of
-   *  that anyway.
+   *  See bits/stl_deque.h's _Deque_base for an explanation.
    *  @endif
   */
-  template<typename _InputIterator>
-    list(_InputIterator __first, _InputIterator __last,
-         const allocator_type& __a = allocator_type())
+  template <typename _Tp, typename _Alloc>
+    class _List_base
+    : public _List_alloc_base<_Tp, _Alloc,
+                              _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
+  {
+  public:
+    typedef _List_alloc_base<_Tp, _Alloc,
+                             _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
+            _Base;
+    typedef typename _Base::allocator_type allocator_type;
+  
+    _List_base(const allocator_type& __a)
     : _Base(__a)
-    { this->insert(begin(), __first, __last); }
-
-  /**
-   *  The dtor only erases the elements, and note that if the elements
-   *  themselves are pointers, the pointed-to memory is not touched in any
-   *  way.  Managing the pointer is the user's responsibilty.
-  */
-  ~list() { }
-
-  /**
-   *  @brief  %List assignment operator.
-   *  @param  x  A %list of identical element and allocator types.
-   * 
-   *  All the elements of @a x are copied, but unlike the copy constructor, the
-   *  allocator object is not copied.
-  */
-  list&
-  operator=(const list& __x);
-
-  /**
-   *  @brief  Assigns a given value to a %list.
-   *  @param  n  Number of elements to be assigned.
-   *  @param  val  Value to be assigned.
-   *
-   *  This function fills a %list with @a n copies of the given value.
-   *  Note that the assignment completely changes the %list and that the
-   *  resulting %list's size is the same as the number of elements assigned.
-   *  Old data may be lost.
-  */
-  void
-  assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); }
-
-  /**
-   *  @brief  Assigns a range to a %list.
-   *  @param  first  An input iterator.
-   *  @param  last   An input iterator.
-   *
-   *  This function fills a %list with copies of the elements in the
-   *  range [first,last).
-   *
-   *  Note that the assignment completely changes the %list and that the
-   *  resulting %list's size is the same as the number of elements assigned.
-   *  Old data may be lost.
-  */
-  template<typename _InputIterator>
-    void
-    assign(_InputIterator __first, _InputIterator __last)
     {
-      // Check whether it's an integral type.  If so, it's not an iterator.
-      typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
-      _M_assign_dispatch(__first, __last, _Integral());
+      _M_node = _M_get_node();
+      _M_node->_M_next = _M_node;
+      _M_node->_M_prev = _M_node;
     }
-
-  /// Get a copy of the memory allocation object.
-  allocator_type
-  get_allocator() const { return _Base::get_allocator(); }
-
-  // iterators
-  /**
-   *  Returns a read/write iterator that points to the first element in the
-   *  %list.  Iteration is done in ordinary element order.
-  */
-  iterator
-  begin() { return static_cast<_Node*>(_M_node->_M_next); }
-
-  /**
-   *  Returns a read-only (constant) iterator that points to the first element
-   *  in the %list.  Iteration is done in ordinary element order.
-  */
-  const_iterator
-  begin() const { return static_cast<_Node*>(_M_node->_M_next); }
-
-  /**
-   *  Returns a read/write iterator that points one past the last element in
-   *  the %list.  Iteration is done in ordinary element order.
-  */
-  iterator
-  end() { return _M_node; }
-
-  /**
-   *  Returns a read-only (constant) iterator that points one past the last
-   *  element in the %list.  Iteration is done in ordinary element order.
-  */
-  const_iterator
-  end() const { return _M_node; }
-
-  /**
-   *  Returns a read/write reverse iterator that points to the last element in
-   *  the %list.  Iteration is done in reverse element order.
-  */
-  reverse_iterator
-  rbegin() { return reverse_iterator(end()); }
-
-  /**
-   *  Returns a read-only (constant) reverse iterator that points to the last
-   *  element in the %list.  Iteration is done in reverse element order.
-  */
-  const_reverse_iterator
-  rbegin() const { return const_reverse_iterator(end()); }
-
-  /**
-   *  Returns a read/write reverse iterator that points to one before the
-   *  first element in the %list.  Iteration is done in reverse element
-   *  order.
-  */
-  reverse_iterator
-  rend() { return reverse_iterator(begin()); }
-
-  /**
-   *  Returns a read-only (constant) reverse iterator that points to one
-   *  before the first element in the %list.  Iteration is done in reverse
-   *  element order.
-  */
-  const_reverse_iterator
-  rend() const
-  { return const_reverse_iterator(begin()); }
-
-  // [23.2.2.2] capacity
-  /**
-   *  Returns true if the %list is empty.  (Thus begin() would equal end().)
-  */
-  bool
-  empty() const { return _M_node->_M_next == _M_node; }
-
-  /**  Returns the number of elements in the %list.  */
-  size_type
-  size() const { return distance(begin(), end()); }
-
-  /**  Returns the size() of the largest possible %list.  */
-  size_type
-  max_size() const { return size_type(-1); }
-
-  /**
-   *  @brief  Resizes the %list to the specified number of elements.
-   *  @param  new_size  Number of elements the %list should contain.
-   *  @param  x  Data with which new elements should be populated.
-   *
-   *  This function will %resize the %list to the specified number of
-   *  elements.  If the number is smaller than the %list's current size the
-   *  %list is truncated, otherwise the %list is extended and new elements
-   *  are populated with given data.
-  */
-  void
-  resize(size_type __new_size, const value_type& __x);
-
-  /**
-   *  @brief  Resizes the %list to the specified number of elements.
-   *  @param  new_size  Number of elements the %list should contain.
-   *
-   *  This function will resize the %list to the specified number of
-   *  elements.  If the number is smaller than the %list's current size the
-   *  %list is truncated, otherwise the %list is extended and new elements
-   *  are default-constructed.
-  */
-  void
-  resize(size_type __new_size) { this->resize(__new_size, value_type()); }
-
-  // element access
-  /**
-   *  Returns a read/write reference to the data at the first element of the
-   *  %list.
-  */
-  reference
-  front() { return *begin(); }
-
-  /**
-   *  Returns a read-only (constant) reference to the data at the first
-   *  element of the %list.
-  */
-  const_reference
-  front() const { return *begin(); }
-
-  /**
-   *  Returns a read/write reference to the data at the last element of the
-   *  %list.
-  */
-  reference
-  back() { return *(--end()); }
-
-  /**
-   *  Returns a read-only (constant) reference to the data at the last
-   *  element of the %list.
-  */
-  const_reference
-  back() const { return *(--end()); }
-
-  // [23.2.2.3] modifiers
-  /**
-   *  @brief  Add data to the front of the %list.
-   *  @param  x  Data to be added.
-   *
-   *  This is a typical stack operation.  The function creates an element at
-   *  the front of the %list and assigns the given data to it.  Due to the
-   *  nature of a %list this operation can be done in constant time, and
-   *  does not invalidate iterators and references.
-  */
-  void
-  push_front(const value_type& __x) { this->insert(begin(), __x); }
-
-#ifdef _GLIBCPP_DEPRECATED
-  /**
-   *  @brief  Add data to the front of the %list.
-   *
-   *  This is a typical stack operation.  The function creates a
-   *  default-constructed element at the front of the %list.  Due to the nature
-   *  of a %list this operation can be done in constant time.  You should
-   *  consider using push_front(value_type()) instead.
-   *
-   *  @note This was deprecated in 3.2 and will be removed in 3.4.  You must
-   *        define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see
-   *        c++config.h.
-  */
-  void
-  push_front() { this->insert(begin(), value_type()); }
-#endif
-
+  
+    // This is what actually destroys the list.
+    ~_List_base()
+    {
+      __clear();
+      _M_put_node(_M_node);
+    }
+  
+    void
+    __clear();
+  };
+  
+  
   /**
-   *  @brief  Removes first element.
+   *  @brief  A standard container with linear time access to elements, and
+   *  fixed time insertion/deletion at any point in the sequence.
    *
-   *  This is a typical stack operation.  It shrinks the %list by one.
-   *  Due to the nature of a %list this operation can be done in constant
-   *  time, and only invalidates iterators/references to the element being
-   *  removed.
+   *  @ingroup Containers
+   *  @ingroup Sequences
    *
-   *  Note that no data is returned, and if the first element's data is
-   *  needed, it should be retrieved before pop_front() is called.
-  */
-  void
-  pop_front() { this->erase(begin()); }
-
-  /**
-   *  @brief  Add data to the end of the %list.
-   *  @param  x  Data to be added.
+   *  Meets the requirements of a <a href="tables.html#65">container</a>, a
+   *  <a href="tables.html#66">reversible container</a>, and a
+   *  <a href="tables.html#67">sequence</a>, including the
+   *  <a href="tables.html#68">optional sequence requirements</a> with the
+   *  %exception of @c at and @c operator[].
    *
-   *  This is a typical stack operation.  The function creates an element at
-   *  the end of the %list and assigns the given data to it.  Due to the
-   *  nature of a %list this operation can be done in constant time, and
-   *  does not invalidate iterators and references.
-  */
-  void
-  push_back(const value_type& __x) { this->insert(end(), __x); }
-
-#ifdef _GLIBCPP_DEPRECATED
-  /**
-   *  @brief  Add data to the end of the %list.
+   *  This is a @e doubly @e linked %list.  Traversal up and down the %list
+   *  requires linear time, but adding and removing elements (or @e nodes) is
+   *  done in constant time, regardless of where the change takes place.
+   *  Unlike std::vector and std::deque, random-access iterators are not
+   *  provided, so subscripting ( @c [] ) access is not allowed.  For algorithms
+   *  which only need sequential access, this lack makes no difference.
    *
-   *  This is a typical stack operation.  The function creates a
-   *  default-constructed element at the end of the %list.  Due to the nature
-   *  of a %list this operation can be done in constant time.  You should
-   *  consider using push_back(value_type()) instead.
+   *  Also unlike the other standard containers, std::list provides specialized 
+   *  algorithms %unique to linked lists, such as splicing, sorting, and
+   *  in-place reversal.
    *
-   *  @note This was deprecated in 3.2 and will be removed in 3.4.  You must
-   *        define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see
-   *        c++config.h.
-  */
-  void
-  push_back() { this->insert(end(), value_type()); }
-#endif
-
-  /**
-   *  @brief  Removes last element.
+   *  @if maint
+   *  A couple points on memory allocation for list<Tp>:
    *
-   *  This is a typical stack operation.  It shrinks the %list by one.
-   *  Due to the nature of a %list this operation can be done in constant
-   *  time, and only invalidates iterators/references to the element being
-   *  removed.
+   *  First, we never actually allocate a Tp, we allocate List_node<Tp>'s
+   *  and trust [20.1.5]/4 to DTRT.  This is to ensure that after elements from
+   *  %list<X,Alloc1> are spliced into %list<X,Alloc2>, destroying the memory of
+   *  the second %list is a valid operation, i.e., Alloc1 giveth and Alloc2
+   *  taketh away.
    *
-   *  Note that no data is returned, and if the last element's data is
-   *  needed, it should be retrieved before pop_back() is called.
+   *  Second, a %list conceptually represented as
+   *  @code
+   *    A <---> B <---> C <---> D
+   *  @endcode
+   *  is actually circular; a link exists between A and D.  The %list class
+   *  holds (as its only data member) a private list::iterator pointing to
+   *  @e D, not to @e A!  To get to the head of the %list, we start at the tail
+   *  and move forward by one.  When this member iterator's next/previous
+   *  pointers refer to itself, the %list is %empty.
+   *  @endif
   */
-  void
-  pop_back()
+  template<typename _Tp, typename _Alloc = allocator<_Tp> >
+    class list : protected _List_base<_Tp, _Alloc>
   {
-    iterator __tmp = end();
-    this->erase(--__tmp);
-  }
-
-  /**
-   *  @brief  Inserts given value into %list before specified iterator.
-   *  @param  position  An iterator into the %list.
-   *  @param  x  Data to be inserted.
-   *  @return  An iterator that points to the inserted data.
-   *
-   *  This function will insert a copy of the given value before the specified
-   *  location.
-   *  Due to the nature of a %list this operation can be done in constant
-   *  time, and does not invalidate iterators and references.
-  */
-  iterator
-  insert(iterator __position, const value_type& __x);
-
-#ifdef _GLIBCPP_DEPRECATED
-  /**
-   *  @brief  Inserts an element into the %list.
-   *  @param  position  An iterator into the %list.
-   *  @return  An iterator that points to the inserted element.
-   *
-   *  This function will insert a default-constructed element before the
-   *  specified location.  You should consider using
-   *  insert(position,value_type()) instead.
-   *  Due to the nature of a %list this operation can be done in constant
-   *  time, and does not invalidate iterators and references.
-   *
-   *  @note This was deprecated in 3.2 and will be removed in 3.4.  You must
-   *        define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see
-   *        c++config.h.
-  */
-  iterator
-  insert(iterator __position) { return insert(__position, value_type()); }
-#endif
-
-  /**
-   *  @brief  Inserts a number of copies of given data into the %list.
-   *  @param  position  An iterator into the %list.
-   *  @param  n  Number of elements to be inserted.
-   *  @param  x  Data to be inserted.
-   *
-   *  This function will insert a specified number of copies of the given data
-   *  before the location specified by @a position.
-   *
-   *  Due to the nature of a %list this operation can be done in constant
-   *  time, and does not invalidate iterators and references.
-  */
-  void
-  insert(iterator __pos, size_type __n, const value_type& __x)
-    { _M_fill_insert(__pos, __n, __x); }
-
-  /**
-   *  @brief  Inserts a range into the %list.
-   *  @param  pos  An iterator into the %list.
-   *  @param  first  An input iterator.
-   *  @param  last   An input iterator.
-   *
-   *  This function will insert copies of the data in the range [first,last)
-   *  into the %list before the location specified by @a pos.
-   *
-   *  Due to the nature of a %list this operation can be done in constant
-   *  time, and does not invalidate iterators and references.
-  */
-  template<typename _InputIterator>
-    void
-    insert(iterator __pos, _InputIterator __first, _InputIterator __last)
+    // concept requirements
+    __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+  
+    typedef _List_base<_Tp, _Alloc>                       _Base;
+  
+  public:
+    typedef _Tp                                           value_type;
+    typedef value_type*                                   pointer;
+    typedef const value_type*                             const_pointer;
+    typedef _List_iterator<_Tp,_Tp&,_Tp*>                 iterator;
+    typedef _List_iterator<_Tp,const _Tp&,const _Tp*>     const_iterator;
+    typedef reverse_iterator<const_iterator>              const_reverse_iterator;
+    typedef reverse_iterator<iterator>                    reverse_iterator;
+    typedef value_type&                                   reference;
+    typedef const value_type&                             const_reference;
+    typedef size_t                                        size_type;
+    typedef ptrdiff_t                                     difference_type;
+    typedef typename _Base::allocator_type                allocator_type;
+  
+  protected:
+    // Note that pointers-to-_Node's can be ctor-converted to iterator types.
+    typedef _List_node<_Tp>                               _Node;
+  
+    /** @if maint
+     *  One data member plus two memory-handling functions.  If the _Alloc
+     *  type requires separate instances, then one of those will also be
+     *  included, accumulated from the topmost parent.
+     *  @endif
+    */
+    using _Base::_M_node;
+    using _Base::_M_put_node;
+    using _Base::_M_get_node;
+  
+    /**
+     *  @if maint
+     *  @param  x  An instance of user data.
+     *
+     *  Allocates space for a new node and constructs a copy of @a x in it.
+     *  @endif
+    */
+    _Node*
+    _M_create_node(const value_type& __x)
     {
-      // Check whether it's an integral type.  If so, it's not an iterator.
-      typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
-      _M_insert_dispatch(__pos, __first, __last, _Integral());
+      _Node* __p = _M_get_node();
+      try {
+        _Construct(&__p->_M_data, __x);
+      }
+      catch(...)
+      {
+        _M_put_node(__p);
+        __throw_exception_again;
+      }
+      return __p;
     }
-
-  /**
-   *  @brief  Remove element at given position.
-   *  @param  position  Iterator pointing to element to be erased.
-   *  @return  An iterator pointing to the next element (or end()).
-   *
-   *  This function will erase the element at the given position and thus
-   *  shorten the %list by one.
-   *
-   *  Due to the nature of a %list this operation can be done in constant
-   *  time, and only invalidates iterators/references to the element being
-   *  removed.
-   *  The user is also cautioned that
-   *  this function only erases the element, and that if the element is itself
-   *  a pointer, the pointed-to memory is not touched in any way.  Managing
-   *  the pointer is the user's responsibilty.
-  */
-  iterator
-  erase(iterator __position);
-
-  /**
-   *  @brief  Remove a range of elements.
-   *  @param  first  Iterator pointing to the first element to be erased.
-   *  @param  last  Iterator pointing to one past the last element to be erased.
-   *  @return  An iterator pointing to the element pointed to by @a last
-   *           prior to erasing (or end()).
-   *
-   *  This function will erase the elements in the range [first,last) and
-   *  shorten the %list accordingly.
-   *
-   *  Due to the nature of a %list this operation can be done in constant
-   *  time, and only invalidates iterators/references to the element being
-   *  removed.
-   *  The user is also cautioned that
-   *  this function only erases the elements, and that if the elements
-   *  themselves are pointers, the pointed-to memory is not touched in any
-   *  way.  Managing the pointer is the user's responsibilty.
-  */
-  iterator
-  erase(iterator __first, iterator __last)
-  {
-    while (__first != __last)
-      erase(__first++);
-    return __last;
-  }
-
-  /**
-   *  @brief  Swaps data with another %list.
-   *  @param  x  A %list of the same element and allocator types.
-   *
-   *  This exchanges the elements between two lists in constant time.
-   *  (It is only swapping a single pointer, so it should be quite fast.)
-   *  Note that the global std::swap() function is specialized such that
-   *  std::swap(l1,l2) will feed to this function.
-  */
-  void
-  swap(list& __x) { std::swap(_M_node, __x._M_node); }
-
-  /**
-   *  Erases all the elements.  Note that this function only erases the
-   *  elements, and that if the elements themselves are pointers, the
-   *  pointed-to memory is not touched in any way.  Managing the pointer is
-   *  the user's responsibilty.
-  */
-  void
-  clear() { _Base::__clear(); }
-
-  // [23.2.2.4] list operations
-  /**
-   *  @doctodo
-  */
-  void
-  splice(iterator __position, list& __x)
-  {
-    if (!__x.empty())
-      this->_M_transfer(__position, __x.begin(), __x.end());
-  }
-
-  /**
-   *  @doctodo
-  */
-  void
-  splice(iterator __position, list&, iterator __i)
-  {
-    iterator __j = __i;
-    ++__j;
-    if (__position == __i || __position == __j) return;
-    this->_M_transfer(__position, __i, __j);
-  }
-
-  /**
-   *  @doctodo
-  */
-  void
-  splice(iterator __position, list&, iterator __first, iterator __last)
-  {
-    if (__first != __last)
-      this->_M_transfer(__position, __first, __last);
-  }
-
-  /**
-   *  @doctodo
-  */
-  void
-  remove(const _Tp& __value);
-
-  /**
-   *  @doctodo
-  */
-  template<typename _Predicate>
+  
+    /**
+     *  @if maint
+     *  Allocates space for a new node and default-constructs a new instance
+     *  of @c value_type in it.
+     *  @endif
+    */
+    _Node*
+    _M_create_node()
+    {
+      _Node* __p = _M_get_node();
+      try {
+        _Construct(&__p->_M_data);
+      }
+      catch(...)
+      {
+        _M_put_node(__p);
+        __throw_exception_again;
+      }
+      return __p;
+    }
+  
+  public:
+    // [23.2.2.1] construct/copy/destroy
+    // (assign() and get_allocator() are also listed in this section)
+    /**
+     *  @brief  Default constructor creates no elements.
+    */
+    explicit
+    list(const allocator_type& __a = allocator_type())
+    : _Base(__a) { }
+  
+    /**
+     *  @brief  Create a %list with copies of an exemplar element.
+     *  @param  n  The number of elements to initially create.
+     *  @param  value  An element to copy.
+     * 
+     *  This constructor fills the %list with @a n copies of @a value.
+    */
+    list(size_type __n, const value_type& __value,
+         const allocator_type& __a = allocator_type())
+      : _Base(__a)
+      { this->insert(begin(), __n, __value); }
+  
+    /**
+     *  @brief  Create a %list with default elements.
+     *  @param  n  The number of elements to initially create.
+     * 
+     *  This constructor fills the %list with @a n copies of a
+     *  default-constructed element.
+    */
+    explicit
+    list(size_type __n)
+      : _Base(allocator_type())
+      { this->insert(begin(), __n, value_type()); }
+  
+    /**
+     *  @brief  %List copy constructor.
+     *  @param  x  A %list of identical element and allocator types.
+     * 
+     *  The newly-created %list uses a copy of the allocation object used
+     *  by @a x.
+    */
+    list(const list& __x)
+      : _Base(__x.get_allocator())
+      { this->insert(begin(), __x.begin(), __x.end()); }
+  
+    /**
+     *  @brief  Builds a %list from a range.
+     *  @param  first  An input iterator.
+     *  @param  last  An input iterator.
+     * 
+     *  Create a %list consisting of copies of the elements from [first,last).
+     *  This is linear in N (where N is distance(first,last)).
+     *
+     *  @if maint
+     *  We don't need any dispatching tricks here, because insert does all of
+     *  that anyway.
+     *  @endif
+    */
+    template<typename _InputIterator>
+      list(_InputIterator __first, _InputIterator __last,
+           const allocator_type& __a = allocator_type())
+      : _Base(__a)
+      { this->insert(begin(), __first, __last); }
+  
+    /**
+     *  The dtor only erases the elements, and note that if the elements
+     *  themselves are pointers, the pointed-to memory is not touched in any
+     *  way.  Managing the pointer is the user's responsibilty.
+    */
+    ~list() { }
+  
+    /**
+     *  @brief  %List assignment operator.
+     *  @param  x  A %list of identical element and allocator types.
+     * 
+     *  All the elements of @a x are copied, but unlike the copy constructor,
+     *  the allocator object is not copied.
+    */
+    list&
+    operator=(const list& __x);
+  
+    /**
+     *  @brief  Assigns a given value to a %list.
+     *  @param  n  Number of elements to be assigned.
+     *  @param  val  Value to be assigned.
+     *
+     *  This function fills a %list with @a n copies of the given value.
+     *  Note that the assignment completely changes the %list and that the
+     *  resulting %list's size is the same as the number of elements assigned.
+     *  Old data may be lost.
+    */
     void
-    remove_if(_Predicate);
-
-  /**
-   *  @doctodo
-  */
-  void
-  unique();
-
-  /**
-   *  @doctodo
-  */
-  template<typename _BinaryPredicate>
+    assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); }
+  
+    /**
+     *  @brief  Assigns a range to a %list.
+     *  @param  first  An input iterator.
+     *  @param  last   An input iterator.
+     *
+     *  This function fills a %list with copies of the elements in the
+     *  range [first,last).
+     *
+     *  Note that the assignment completely changes the %list and that the
+     *  resulting %list's size is the same as the number of elements assigned.
+     *  Old data may be lost.
+    */
+    template<typename _InputIterator>
+      void
+      assign(_InputIterator __first, _InputIterator __last)
+      {
+        // Check whether it's an integral type.  If so, it's not an iterator.
+        typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+        _M_assign_dispatch(__first, __last, _Integral());
+      }
+  
+    /// Get a copy of the memory allocation object.
+    allocator_type
+    get_allocator() const { return _Base::get_allocator(); }
+  
+    // iterators
+    /**
+     *  Returns a read/write iterator that points to the first element in the
+     *  %list.  Iteration is done in ordinary element order.
+    */
+    iterator
+    begin() { return static_cast<_Node*>(_M_node->_M_next); }
+  
+    /**
+     *  Returns a read-only (constant) iterator that points to the first element
+     *  in the %list.  Iteration is done in ordinary element order.
+    */
+    const_iterator
+    begin() const { return static_cast<_Node*>(_M_node->_M_next); }
+  
+    /**
+     *  Returns a read/write iterator that points one past the last element in
+     *  the %list.  Iteration is done in ordinary element order.
+    */
+    iterator
+    end() { return _M_node; }
+  
+    /**
+     *  Returns a read-only (constant) iterator that points one past the last
+     *  element in the %list.  Iteration is done in ordinary element order.
+    */
+    const_iterator
+    end() const { return _M_node; }
+  
+    /**
+     *  Returns a read/write reverse iterator that points to the last element in
+     *  the %list.  Iteration is done in reverse element order.
+    */
+    reverse_iterator
+    rbegin() { return reverse_iterator(end()); }
+  
+    /**
+     *  Returns a read-only (constant) reverse iterator that points to the last
+     *  element in the %list.  Iteration is done in reverse element order.
+    */
+    const_reverse_iterator
+    rbegin() const { return const_reverse_iterator(end()); }
+  
+    /**
+     *  Returns a read/write reverse iterator that points to one before the
+     *  first element in the %list.  Iteration is done in reverse element
+     *  order.
+    */
+    reverse_iterator
+    rend() { return reverse_iterator(begin()); }
+  
+    /**
+     *  Returns a read-only (constant) reverse iterator that points to one
+     *  before the first element in the %list.  Iteration is done in reverse
+     *  element order.
+    */
+    const_reverse_iterator
+    rend() const
+    { return const_reverse_iterator(begin()); }
+  
+    // [23.2.2.2] capacity
+    /**
+     *  Returns true if the %list is empty.  (Thus begin() would equal end().)
+    */
+    bool
+    empty() const { return _M_node->_M_next == _M_node; }
+  
+    /**  Returns the number of elements in the %list.  */
+    size_type
+    size() const { return distance(begin(), end()); }
+  
+    /**  Returns the size() of the largest possible %list.  */
+    size_type
+    max_size() const { return size_type(-1); }
+  
+    /**
+     *  @brief  Resizes the %list to the specified number of elements.
+     *  @param  new_size  Number of elements the %list should contain.
+     *  @param  x  Data with which new elements should be populated.
+     *
+     *  This function will %resize the %list to the specified number of
+     *  elements.  If the number is smaller than the %list's current size the
+     *  %list is truncated, otherwise the %list is extended and new elements
+     *  are populated with given data.
+    */
     void
-    unique(_BinaryPredicate);
-
-  /**
-   *  @doctodo
-  */
-  void
-  merge(list& __x);
-
-  /**
-   *  @doctodo
-  */
-  template<typename _StrictWeakOrdering>
+    resize(size_type __new_size, const value_type& __x);
+  
+    /**
+     *  @brief  Resizes the %list to the specified number of elements.
+     *  @param  new_size  Number of elements the %list should contain.
+     *
+     *  This function will resize the %list to the specified number of
+     *  elements.  If the number is smaller than the %list's current size the
+     *  %list is truncated, otherwise the %list is extended and new elements
+     *  are default-constructed.
+    */
     void
-    merge(list&, _StrictWeakOrdering);
-
-  /**
-   *  @doctodo
-  */
-  void
-  reverse() { __List_base_reverse(this->_M_node); }
-
-  /**
-   *  @doctodo
-  */
-  void
-  sort();
-
-  /**
-   *  @doctodo
-  */
-  template<typename _StrictWeakOrdering>
+    resize(size_type __new_size) { this->resize(__new_size, value_type()); }
+  
+    // element access
+    /**
+     *  Returns a read/write reference to the data at the first element of the
+     *  %list.
+    */
+    reference
+    front() { return *begin(); }
+  
+    /**
+     *  Returns a read-only (constant) reference to the data at the first
+     *  element of the %list.
+    */
+    const_reference
+    front() const { return *begin(); }
+  
+    /**
+     *  Returns a read/write reference to the data at the last element of the
+     *  %list.
+    */
+    reference
+    back() { return *(--end()); }
+  
+    /**
+     *  Returns a read-only (constant) reference to the data at the last
+     *  element of the %list.
+    */
+    const_reference
+    back() const { return *(--end()); }
+  
+    // [23.2.2.3] modifiers
+    /**
+     *  @brief  Add data to the front of the %list.
+     *  @param  x  Data to be added.
+     *
+     *  This is a typical stack operation.  The function creates an element at
+     *  the front of the %list and assigns the given data to it.  Due to the
+     *  nature of a %list this operation can be done in constant time, and
+     *  does not invalidate iterators and references.
+    */
     void
-    sort(_StrictWeakOrdering);
-
-protected:
-  // Internal assign functions follow.
-
-  // called by the range assign to implement [23.1.1]/9
-  template<typename _Integer>
+    push_front(const value_type& __x) { this->insert(begin(), __x); }
+  
+  #ifdef _GLIBCPP_DEPRECATED
+    /**
+     *  @brief  Add data to the front of the %list.
+     *
+     *  This is a typical stack operation.  The function creates a
+     *  default-constructed element at the front of the %list.  Due to the
+     *  nature of a %list this operation can be done in constant time.  You
+     *  should consider using push_front(value_type()) instead.
+     *
+     *  @note This was deprecated in 3.2 and will be removed in 3.4.  You must
+     *        define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see
+     *        c++config.h.
+    */
     void
-    _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
+    push_front() { this->insert(begin(), value_type()); }
+  #endif
+  
+    /**
+     *  @brief  Removes first element.
+     *
+     *  This is a typical stack operation.  It shrinks the %list by one.
+     *  Due to the nature of a %list this operation can be done in constant
+     *  time, and only invalidates iterators/references to the element being
+     *  removed.
+     *
+     *  Note that no data is returned, and if the first element's data is
+     *  needed, it should be retrieved before pop_front() is called.
+    */
+    void
+    pop_front() { this->erase(begin()); }
+  
+    /**
+     *  @brief  Add data to the end of the %list.
+     *  @param  x  Data to be added.
+     *
+     *  This is a typical stack operation.  The function creates an element at
+     *  the end of the %list and assigns the given data to it.  Due to the
+     *  nature of a %list this operation can be done in constant time, and
+     *  does not invalidate iterators and references.
+    */
+    void
+    push_back(const value_type& __x) { this->insert(end(), __x); }
+  
+  #ifdef _GLIBCPP_DEPRECATED
+    /**
+     *  @brief  Add data to the end of the %list.
+     *
+     *  This is a typical stack operation.  The function creates a
+     *  default-constructed element at the end of the %list.  Due to the nature
+     *  of a %list this operation can be done in constant time.  You should
+     *  consider using push_back(value_type()) instead.
+     *
+     *  @note This was deprecated in 3.2 and will be removed in 3.4.  You must
+     *        define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see
+     *        c++config.h.
+    */
+    void
+    push_back() { this->insert(end(), value_type()); }
+  #endif
+  
+    /**
+     *  @brief  Removes last element.
+     *
+     *  This is a typical stack operation.  It shrinks the %list by one.
+     *  Due to the nature of a %list this operation can be done in constant
+     *  time, and only invalidates iterators/references to the element being
+     *  removed.
+     *
+     *  Note that no data is returned, and if the last element's data is
+     *  needed, it should be retrieved before pop_back() is called.
+    */
+    void
+    pop_back()
     {
-      _M_fill_assign(static_cast<size_type>(__n),
-                     static_cast<value_type>(__val));
+      iterator __tmp = end();
+      this->erase(--__tmp);
     }
-
-  // called by the range assign to implement [23.1.1]/9
-  template<typename _InputIter>
+  
+    /**
+     *  @brief  Inserts given value into %list before specified iterator.
+     *  @param  position  An iterator into the %list.
+     *  @param  x  Data to be inserted.
+     *  @return  An iterator that points to the inserted data.
+     *
+     *  This function will insert a copy of the given value before the specified
+     *  location.
+     *  Due to the nature of a %list this operation can be done in constant
+     *  time, and does not invalidate iterators and references.
+    */
+    iterator
+    insert(iterator __position, const value_type& __x);
+  
+  #ifdef _GLIBCPP_DEPRECATED
+    /**
+     *  @brief  Inserts an element into the %list.
+     *  @param  position  An iterator into the %list.
+     *  @return  An iterator that points to the inserted element.
+     *
+     *  This function will insert a default-constructed element before the
+     *  specified location.  You should consider using
+     *  insert(position,value_type()) instead.
+     *  Due to the nature of a %list this operation can be done in constant
+     *  time, and does not invalidate iterators and references.
+     *
+     *  @note This was deprecated in 3.2 and will be removed in 3.4.  You must
+     *        define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see
+     *        c++config.h.
+    */
+    iterator
+    insert(iterator __position) { return insert(__position, value_type()); }
+  #endif
+  
+    /**
+     *  @brief  Inserts a number of copies of given data into the %list.
+     *  @param  position  An iterator into the %list.
+     *  @param  n  Number of elements to be inserted.
+     *  @param  x  Data to be inserted.
+     *
+     *  This function will insert a specified number of copies of the given data
+     *  before the location specified by @a position.
+     *
+     *  Due to the nature of a %list this operation can be done in constant
+     *  time, and does not invalidate iterators and references.
+    */
     void
-    _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type);
-
-  // Called by assign(n,t), and the range assign when it turns out to be the
-  // same thing.
-  void
-  _M_fill_assign(size_type __n, const value_type& __val);
-
-
-  // Internal insert functions follow.
-
-  // called by the range insert to implement [23.1.1]/9
-  template<typename _Integer>
+    insert(iterator __pos, size_type __n, const value_type& __x)
+      { _M_fill_insert(__pos, __n, __x); }
+  
+    /**
+     *  @brief  Inserts a range into the %list.
+     *  @param  pos  An iterator into the %list.
+     *  @param  first  An input iterator.
+     *  @param  last   An input iterator.
+     *
+     *  This function will insert copies of the data in the range [first,last)
+     *  into the %list before the location specified by @a pos.
+     *
+     *  Due to the nature of a %list this operation can be done in constant
+     *  time, and does not invalidate iterators and references.
+    */
+    template<typename _InputIterator>
+      void
+      insert(iterator __pos, _InputIterator __first, _InputIterator __last)
+      {
+        // Check whether it's an integral type.  If so, it's not an iterator.
+        typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+        _M_insert_dispatch(__pos, __first, __last, _Integral());
+      }
+  
+    /**
+     *  @brief  Remove element at given position.
+     *  @param  position  Iterator pointing to element to be erased.
+     *  @return  An iterator pointing to the next element (or end()).
+     *
+     *  This function will erase the element at the given position and thus
+     *  shorten the %list by one.
+     *
+     *  Due to the nature of a %list this operation can be done in constant
+     *  time, and only invalidates iterators/references to the element being
+     *  removed.
+     *  The user is also cautioned that
+     *  this function only erases the element, and that if the element is itself
+     *  a pointer, the pointed-to memory is not touched in any way.  Managing
+     *  the pointer is the user's responsibilty.
+    */
+    iterator
+    erase(iterator __position);
+  
+    /**
+     *  @brief  Remove a range of elements.
+     *  @param  first  Iterator pointing to the first element to be erased.
+     *  @param  last  Iterator pointing to one past the last element to be
+     *                erased.
+     *  @return  An iterator pointing to the element pointed to by @a last
+     *           prior to erasing (or end()).
+     *
+     *  This function will erase the elements in the range [first,last) and
+     *  shorten the %list accordingly.
+     *
+     *  Due to the nature of a %list this operation can be done in constant
+     *  time, and only invalidates iterators/references to the element being
+     *  removed.
+     *  The user is also cautioned that
+     *  this function only erases the elements, and that if the elements
+     *  themselves are pointers, the pointed-to memory is not touched in any
+     *  way.  Managing the pointer is the user's responsibilty.
+    */
+    iterator
+    erase(iterator __first, iterator __last)
+    {
+      while (__first != __last)
+        erase(__first++);
+      return __last;
+    }
+  
+    /**
+     *  @brief  Swaps data with another %list.
+     *  @param  x  A %list of the same element and allocator types.
+     *
+     *  This exchanges the elements between two lists in constant time.
+     *  (It is only swapping a single pointer, so it should be quite fast.)
+     *  Note that the global std::swap() function is specialized such that
+     *  std::swap(l1,l2) will feed to this function.
+    */
     void
-    _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, __true_type)
+    swap(list& __x) { std::swap(_M_node, __x._M_node); }
+  
+    /**
+     *  Erases all the elements.  Note that this function only erases the
+     *  elements, and that if the elements themselves are pointers, the
+     *  pointed-to memory is not touched in any way.  Managing the pointer is
+     *  the user's responsibilty.
+    */
+    void
+    clear() { _Base::__clear(); }
+  
+    // [23.2.2.4] list operations
+    /**
+     *  @doctodo
+    */
+    void
+    splice(iterator __position, list& __x)
     {
-      _M_fill_insert(__pos, static_cast<size_type>(__n),
-                     static_cast<value_type>(__x));
+      if (!__x.empty())
+        this->_M_transfer(__position, __x.begin(), __x.end());
     }
-
-  // called by the range insert to implement [23.1.1]/9
-  template<typename _InputIterator>
+  
+    /**
+     *  @doctodo
+    */
     void
-    _M_insert_dispatch(iterator __pos,
-                       _InputIterator __first, _InputIterator __last,
-                       __false_type)
+    splice(iterator __position, list&, iterator __i)
     {
-      for ( ; __first != __last; ++__first)
-        insert(__pos, *__first);
+      iterator __j = __i;
+      ++__j;
+      if (__position == __i || __position == __j) return;
+      this->_M_transfer(__position, __i, __j);
     }
-
-  // Called by insert(p,n,x), and the range insert when it turns out to be
-  // the same thing.
-  void
-  _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
-  {
-    for ( ; __n > 0; --__n)
-      insert(__pos, __x);
-  }
-
-
-  // Moves the elements from [first,last) before position.
-  void
-  _M_transfer(iterator __position, iterator __first, iterator __last)
-  {
-    if (__position != __last) {
-      // Remove [first, last) from its old position.
-      __last._M_node->_M_prev->_M_next     = __position._M_node;
-      __first._M_node->_M_prev->_M_next    = __last._M_node;
-      __position._M_node->_M_prev->_M_next = __first._M_node;
-
-      // Splice [first, last) into its new position.
-      _List_node_base* __tmp      = __position._M_node->_M_prev;
-      __position._M_node->_M_prev = __last._M_node->_M_prev;
-      __last._M_node->_M_prev     = __first._M_node->_M_prev;
-      __first._M_node->_M_prev    = __tmp;
+  
+    /**
+     *  @doctodo
+    */
+    void
+    splice(iterator __position, list&, iterator __first, iterator __last)
+    {
+      if (__first != __last)
+        this->_M_transfer(__position, __first, __last);
     }
-  }
-};
-
-
-/**
- *  @brief  List equality comparison.
- *  @param  x  A %list.
- *  @param  y  A %list of the same type as @a x.
- *  @return  True iff the size and elements of the lists are equal.
- *
- *  This is an equivalence relation.  It is linear in the size of the
- *  lists.  Lists are considered equivalent if their sizes are equal,
- *  and if corresponding elements compare equal.
-*/
-template<typename _Tp, typename _Alloc>
-inline bool
-  operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
-  {
-    typedef typename list<_Tp,_Alloc>::const_iterator const_iterator;
-    const_iterator __end1 = __x.end();
-    const_iterator __end2 = __y.end();
-
-    const_iterator __i1 = __x.begin();
-    const_iterator __i2 = __y.begin();
-    while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) {
-      ++__i1;
-      ++__i2;
+  
+    /**
+     *  @doctodo
+    */
+    void
+    remove(const _Tp& __value);
+  
+    /**
+     *  @doctodo
+    */
+    template<typename _Predicate>
+      void
+      remove_if(_Predicate);
+  
+    /**
+     *  @doctodo
+    */
+    void
+    unique();
+  
+    /**
+     *  @doctodo
+    */
+    template<typename _BinaryPredicate>
+      void
+      unique(_BinaryPredicate);
+  
+    /**
+     *  @doctodo
+    */
+    void
+    merge(list& __x);
+  
+    /**
+     *  @doctodo
+    */
+    template<typename _StrictWeakOrdering>
+      void
+      merge(list&, _StrictWeakOrdering);
+  
+    /**
+     *  @doctodo
+    */
+    void
+    reverse() { __List_base_reverse(this->_M_node); }
+  
+    /**
+     *  @doctodo
+    */
+    void
+    sort();
+  
+    /**
+     *  @doctodo
+    */
+    template<typename _StrictWeakOrdering>
+      void
+      sort(_StrictWeakOrdering);
+  
+  protected:
+    // Internal assign functions follow.
+  
+    // called by the range assign to implement [23.1.1]/9
+    template<typename _Integer>
+      void
+      _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
+      {
+        _M_fill_assign(static_cast<size_type>(__n),
+                       static_cast<value_type>(__val));
+      }
+  
+    // called by the range assign to implement [23.1.1]/9
+    template<typename _InputIter>
+      void
+      _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type);
+  
+    // Called by assign(n,t), and the range assign when it turns out to be the
+    // same thing.
+    void
+    _M_fill_assign(size_type __n, const value_type& __val);
+  
+  
+    // Internal insert functions follow.
+  
+    // called by the range insert to implement [23.1.1]/9
+    template<typename _Integer>
+      void
+      _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
+                         __true_type)
+      {
+        _M_fill_insert(__pos, static_cast<size_type>(__n),
+                       static_cast<value_type>(__x));
+      }
+  
+    // called by the range insert to implement [23.1.1]/9
+    template<typename _InputIterator>
+      void
+      _M_insert_dispatch(iterator __pos,
+                         _InputIterator __first, _InputIterator __last,
+                         __false_type)
+      {
+        for ( ; __first != __last; ++__first)
+          insert(__pos, *__first);
+      }
+  
+    // Called by insert(p,n,x), and the range insert when it turns out to be
+    // the same thing.
+    void
+    _M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
+    {
+      for ( ; __n > 0; --__n)
+        insert(__pos, __x);
     }
-    return __i1 == __end1 && __i2 == __end2;
-  }
-
-/**
- *  @brief  List ordering relation.
- *  @param  x  A %list.
- *  @param  y  A %list of the same type as @a x.
- *  @return  True iff @a x is lexographically less than @a y.
- *
- *  This is a total ordering relation.  It is linear in the size of the
- *  lists.  The elements must be comparable with @c <.
- *
- *  See std::lexographical_compare() for how the determination is made.
-*/
-template<typename _Tp, typename _Alloc>
-  inline bool
-  operator<(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
-  {
-    return lexicographical_compare(__x.begin(), __x.end(),
-                                   __y.begin(), __y.end());
-  }
-
-/// Based on operator==
-template<typename _Tp, typename _Alloc>
-  inline bool
-  operator!=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
-  { return !(__x == __y); }
-
-/// Based on operator<
-template<typename _Tp, typename _Alloc>
-  inline bool
-  operator>(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
-  { return __y < __x; }
-
-/// Based on operator<
-template<typename _Tp, typename _Alloc>
-  inline bool
-  operator<=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
-  { return !(__y < __x); }
-
-/// Based on operator<
-template<typename _Tp, typename _Alloc>
+  
+  
+    // Moves the elements from [first,last) before position.
+    void
+    _M_transfer(iterator __position, iterator __first, iterator __last)
+    {
+      if (__position != __last) {
+        // Remove [first, last) from its old position.
+        __last._M_node->_M_prev->_M_next     = __position._M_node;
+        __first._M_node->_M_prev->_M_next    = __last._M_node;
+        __position._M_node->_M_prev->_M_next = __first._M_node;
+  
+        // Splice [first, last) into its new position.
+        _List_node_base* __tmp      = __position._M_node->_M_prev;
+        __position._M_node->_M_prev = __last._M_node->_M_prev;
+        __last._M_node->_M_prev     = __first._M_node->_M_prev;
+        __first._M_node->_M_prev    = __tmp;
+      }
+    }
+  };
+  
+  
+  /**
+   *  @brief  List equality comparison.
+   *  @param  x  A %list.
+   *  @param  y  A %list of the same type as @a x.
+   *  @return  True iff the size and elements of the lists are equal.
+   *
+   *  This is an equivalence relation.  It is linear in the size of the
+   *  lists.  Lists are considered equivalent if their sizes are equal,
+   *  and if corresponding elements compare equal.
+  */
+  template<typename _Tp, typename _Alloc>
   inline bool
-  operator>=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
-  { return !(__x < __y); }
-
-/// See std::list::swap().
-template<typename _Tp, typename _Alloc>
-  inline void
-  swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
-  { __x.swap(__y); }
-
+    operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+    {
+      typedef typename list<_Tp,_Alloc>::const_iterator const_iterator;
+      const_iterator __end1 = __x.end();
+      const_iterator __end2 = __y.end();
+  
+      const_iterator __i1 = __x.begin();
+      const_iterator __i2 = __y.begin();
+      while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) {
+        ++__i1;
+        ++__i2;
+      }
+      return __i1 == __end1 && __i2 == __end2;
+    }
+  
+  /**
+   *  @brief  List ordering relation.
+   *  @param  x  A %list.
+   *  @param  y  A %list of the same type as @a x.
+   *  @return  True iff @a x is lexographically less than @a y.
+   *
+   *  This is a total ordering relation.  It is linear in the size of the
+   *  lists.  The elements must be comparable with @c <.
+   *
+   *  See std::lexographical_compare() for how the determination is made.
+  */
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator<(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+    {
+      return lexicographical_compare(__x.begin(), __x.end(),
+                                     __y.begin(), __y.end());
+    }
+  
+  /// Based on operator==
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator!=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+    { return !(__x == __y); }
+  
+  /// Based on operator<
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator>(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+    { return __y < __x; }
+  
+  /// Based on operator<
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator<=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+    { return !(__y < __x); }
+  
+  /// Based on operator<
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator>=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
+    { return !(__x < __y); }
+  
+  /// See std::list::swap().
+  template<typename _Tp, typename _Alloc>
+    inline void
+    swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
+    { __x.swap(__y); }
 } // namespace std
 
 #endif /* __GLIBCPP_INTERNAL_LIST_H */
-
index 26546d3..bf86ece 100644 (file)
 
 #include <bits/concept_check.h>
 
-// Since this entire file is within namespace std, there's no reason to
-// waste two spaces along the left column.  Thus the leading indentation is
-// slightly violated from here on.
 namespace std
 {
-
-/**
- *  @brief A standard container made up of (key,value) pairs, which can be
- *  retrieved based on a key, in logarithmic time.
- *
- *  @ingroup Containers
- *  @ingroup Assoc_containers
- *
- *  Meets the requirements of a <a href="tables.html#65">container</a>, a
- *  <a href="tables.html#66">reversible container</a>, and an
- *  <a href="tables.html#69">associative container</a> (using unique keys).
- *  For a @c map<Key,T> the key_type is Key, the mapped_type is T, and the
- *  value_type is std::pair<const Key,T>.
- *
- *  Maps support bidirectional iterators.
- *
- *  @if maint
- *  The private tree data is declared exactly the same way for map and
- *  multimap; the distinction is made entirely in how the tree functions are
- *  called (*_unique versus *_equal, same as the standard).
- *  @endif
-*/
-template <typename _Key, typename _Tp, typename _Compare = less<_Key>,
-          typename _Alloc = allocator<pair<const _Key, _Tp> > >
-  class map
-{
-  // concept requirements
-  __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
-  __glibcpp_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept)
-
-public:
-  typedef _Key                                          key_type;
-  typedef _Tp                                           mapped_type;
-  typedef pair<const _Key, _Tp>                         value_type;
-  typedef _Compare                                      key_compare;
-
-  class value_compare
-    : public binary_function<value_type, value_type, bool>
-    {
-      friend class map<_Key,_Tp,_Compare,_Alloc>;
-    protected:
-      _Compare comp;
-      value_compare(_Compare __c) : comp(__c) {}
-    public:
-      bool operator()(const value_type& __x, const value_type& __y) const
-        { return comp(__x.first, __y.first); }
-    };
-
-private:
-  /// @if maint  This turns a red-black tree into a [multi]map.  @endif
-  typedef _Rb_tree<key_type, value_type,
-                   _Select1st<value_type>, key_compare, _Alloc> _Rep_type;
-  /// @if maint  The actual tree structure.  @endif
-  _Rep_type _M_t;
-
-public:
-  // many of these are specified differently in ISO, but the following are
-  // "functionally equivalent"
-  typedef typename _Rep_type::allocator_type            allocator_type;
-  typedef typename _Rep_type::reference                 reference;
-  typedef typename _Rep_type::const_reference           const_reference;
-  typedef typename _Rep_type::iterator                  iterator;
-  typedef typename _Rep_type::const_iterator            const_iterator;
-  typedef typename _Rep_type::size_type                 size_type;
-  typedef typename _Rep_type::difference_type           difference_type;
-  typedef typename _Rep_type::pointer                   pointer;
-  typedef typename _Rep_type::const_pointer             const_pointer;
-  typedef typename _Rep_type::reverse_iterator          reverse_iterator;
-  typedef typename _Rep_type::const_reverse_iterator    const_reverse_iterator;
-
-
-  // [23.3.1.1] construct/copy/destroy
-  // (get_allocator() is normally listed in this section, but seems to have
-  // been accidentally omitted in the printed standard)
-  /**
-   *  @brief  Default constructor creates no elements.
-  */
-  map() : _M_t(_Compare(), allocator_type()) { }
-
-  // for some reason this was made a separate function
   /**
-   *  @brief  Default constructor creates no elements.
-  */
-  explicit
-  map(const _Compare& __comp, const allocator_type& __a = allocator_type())
-    : _M_t(__comp, __a) { }
-
-  /**
-   *  @brief  Map copy constructor.
-   *  @param  x  A %map of identical element and allocator types.
+   *  @brief A standard container made up of (key,value) pairs, which can be
+   *  retrieved based on a key, in logarithmic time.
    *
-   *  The newly-created %map uses a copy of the allocation object used
-   *  by @a x.
-  */
-  map(const map& __x)
-    : _M_t(__x._M_t) { }
-
-  /**
-   *  @brief  Builds a %map from a range.
-   *  @param  first  An input iterator.
-   *  @param  last  An input iterator.
-   *
-   *  Create a %map consisting of copies of the elements from [first,last).
-   *  This is linear in N if the range is already sorted, and NlogN
-   *  otherwise (where N is distance(first,last)).
-  */
-  template <typename _InputIterator>
-    map(_InputIterator __first, _InputIterator __last)
-    : _M_t(_Compare(), allocator_type())
-    { _M_t.insert_unique(__first, __last); }
-
-  /**
-   *  @brief  Builds a %map from a range.
-   *  @param  first  An input iterator.
-   *  @param  last  An input iterator.
-   *  @param  comp  A comparison functor.
-   *  @param  a  An allocator object.
-   *
-   *  Create a %map consisting of copies of the elements from [first,last).
-   *  This is linear in N if the range is already sorted, and NlogN
-   *  otherwise (where N is distance(first,last)).
-  */
-  template <typename _InputIterator>
-    map(_InputIterator __first, _InputIterator __last,
-        const _Compare& __comp, const allocator_type& __a = allocator_type())
-    : _M_t(__comp, __a)
-    { _M_t.insert_unique(__first, __last); }
-
-  // FIXME There is no dtor declared, but we should have something generated
-  // by Doxygen.  I don't know what tags to add to this paragraph to make
-  // that happen:
-  /**
-   *  The dtor only erases the elements, and note that if the elements
-   *  themselves are pointers, the pointed-to memory is not touched in any
-   *  way.  Managing the pointer is the user's responsibilty.
-  */
-
-  /**
-   *  @brief  Map assignment operator.
-   *  @param  x  A %map of identical element and allocator types.
+   *  @ingroup Containers
+   *  @ingroup Assoc_containers
    *
-   *  All the elements of @a x are copied, but unlike the copy constructor, the
-   *  allocator object is not copied.
-  */
-  map&
-  operator=(const map& __x)
-  {
-    _M_t = __x._M_t;
-    return *this;
-  }
-
-  /// Get a copy of the memory allocation object.
-  allocator_type
-  get_allocator() const { return _M_t.get_allocator(); }
-
-  // iterators
-  /**
-   *  Returns a read/write iterator that points to the first pair in the %map.
-   *  Iteration is done in ascending order according to the keys.
-  */
-  iterator
-  begin() { return _M_t.begin(); }
-
-  /**
-   *  Returns a read-only (constant) iterator that points to the first pair
-   *  in the %map.  Iteration is done in ascending order according to the keys.
-  */
-  const_iterator
-  begin() const { return _M_t.begin(); }
-
-  /**
-   *  Returns a read/write iterator that points one past the last pair in the
-   *  %map.  Iteration is done in ascending order according to the keys.
-  */
-  iterator
-  end() { return _M_t.end(); }
-
-  /**
-   *  Returns a read-only (constant) iterator that points one past the last
-   *  pair in the %map.  Iteration is done in ascending order according to the
-   *  keys.
-  */
-  const_iterator
-  end() const { return _M_t.end(); }
-
-  /**
-   *  Returns a read/write reverse iterator that points to the last pair in
-   *  the %map.  Iteration is done in descending order according to the keys.
-  */
-  reverse_iterator
-  rbegin() { return _M_t.rbegin(); }
-
-  /**
-   *  Returns a read-only (constant) reverse iterator that points to the last
-   *  pair in the %map.  Iteration is done in descending order according to
-   *  the keys.
-  */
-  const_reverse_iterator
-  rbegin() const { return _M_t.rbegin(); }
-
-  /**
-   *  Returns a read/write reverse iterator that points to one before the
-   *  first pair in the %map.  Iteration is done in descending order according
-   *  to the keys.
-  */
-  reverse_iterator
-  rend() { return _M_t.rend(); }
-
-  /**
-   *  Returns a read-only (constant) reverse iterator that points to one
-   *  before the first pair in the %map.  Iteration is done in descending order
-   *  according to the keys.
-  */
-  const_reverse_iterator
-  rend() const { return _M_t.rend(); }
-
-  // capacity
-  /** Returns true if the %map is empty.  (Thus begin() would equal end().)  */
-  bool
-  empty() const { return _M_t.empty(); }
-
-  /** Returns the size of the %map.  */
-  size_type
-  size() const { return _M_t.size(); }
-
-  /** Returns the maximum size of the %map.  */
-  size_type
-  max_size() const { return _M_t.max_size(); }
-
-  // [23.3.1.2] element access
-  /**
-   *  @brief  Subscript ( @c [] ) access to %map data.
-   *  @param  k  The key for which data should be retrieved.
-   *  @return  A reference to the data of the (key,data) %pair.
+   *  Meets the requirements of a <a href="tables.html#65">container</a>, a
+   *  <a href="tables.html#66">reversible container</a>, and an
+   *  <a href="tables.html#69">associative container</a> (using unique keys).
+   *  For a @c map<Key,T> the key_type is Key, the mapped_type is T, and the
+   *  value_type is std::pair<const Key,T>.
    *
-   *  Allows for easy lookup with the subscript ( @c [] ) operator.  Returns
-   *  data associated with the key specified in subscript.  If the key does
-   *  not exist, a pair with that key is created using default values, which
-   *  is then returned.
+   *  Maps support bidirectional iterators.
    *
-   *  Lookup requires logarithmic time.
-  */
-  mapped_type&
-  operator[](const key_type& __k)
+   *  @if maint
+   *  The private tree data is declared exactly the same way for map and
+   *  multimap; the distinction is made entirely in how the tree functions are
+   *  called (*_unique versus *_equal, same as the standard).
+   *  @endif
+  */
+  template <typename _Key, typename _Tp, typename _Compare = less<_Key>,
+            typename _Alloc = allocator<pair<const _Key, _Tp> > >
+    class map
   {
     // concept requirements
-    __glibcpp_function_requires(_DefaultConstructibleConcept<mapped_type>)
-
-    iterator __i = lower_bound(__k);
-    // __i->first is greater than or equivalent to __k.
-    if (__i == end() || key_comp()(__k, (*__i).first))
-      __i = insert(__i, value_type(__k, mapped_type()));
-    return (*__i).second;
-  }
-
-  // modifiers
-  /**
-   *  @brief Attempts to insert a std::pair into the %map.
-   *  @param  x  Pair to be inserted (see std::make_pair for easy creation of
-   *             pairs).
-   *  @return  A pair, of which the first element is an iterator that points
-   *           to the possibly inserted pair, and the second is a bool that
-   *           is true if the pair was actually inserted.
-   *
-   *  This function attempts to insert a (key, value) %pair into the %map.  A
-   *  %map relies on unique keys and thus a %pair is only inserted if its first
-   *  element (the key) is not already present in the %map.
-   *
-   *  Insertion requires logarithmic time.
-  */
-  pair<iterator,bool>
-  insert(const value_type& __x)
-    { return _M_t.insert_unique(__x); }
-
-  /**
-   *  @brief Attempts to insert a std::pair into the %map.
-   *  @param  position  An iterator that serves as a hint as to where the
-   *                    pair should be inserted.
-   *  @param  x  Pair to be inserted (see std::make_pair for easy creation of
-   *             pairs).
-   *  @return  An iterator that points to the element with key of @a x (may
-   *           or may not be the %pair passed in).
-   *
-   *  This function is not concerned about whether the insertion took place,
-   *  and thus does not return a boolean like the single-argument
-   *  insert() does.  Note that the first parameter is only a hint and can
-   *  potentially improve the performance of the insertion process.  A bad
-   *  hint would cause no gains in efficiency.
-   *
-   *  See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4
-   *  for more on "hinting".
-   *
-   *  Insertion requires logarithmic time (if the hint is not taken).
-  */
-  iterator
-  insert(iterator position, const value_type& __x)
-    { return _M_t.insert_unique(position, __x); }
-
-  /**
-   *  @brief A template function that attemps to insert a range of elements.
-   *  @param  first  Iterator pointing to the start of the range to be inserted.
-   *  @param  last  Iterator pointing to the end of the range.
-   *
-   *  Complexity similar to that of the range constructor.
-  */
-  template <typename _InputIterator>
-    void
-    insert(_InputIterator __first, _InputIterator __last)
+    __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+    __glibcpp_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept)
+  
+  public:
+    typedef _Key                                          key_type;
+    typedef _Tp                                           mapped_type;
+    typedef pair<const _Key, _Tp>                         value_type;
+    typedef _Compare                                      key_compare;
+  
+    class value_compare
+      : public binary_function<value_type, value_type, bool>
+      {
+        friend class map<_Key,_Tp,_Compare,_Alloc>;
+      protected:
+        _Compare comp;
+        value_compare(_Compare __c) : comp(__c) {}
+      public:
+        bool operator()(const value_type& __x, const value_type& __y) const
+          { return comp(__x.first, __y.first); }
+      };
+  
+  private:
+    /// @if maint  This turns a red-black tree into a [multi]map.  @endif
+    typedef _Rb_tree<key_type, value_type,
+                     _Select1st<value_type>, key_compare, _Alloc> _Rep_type;
+    /// @if maint  The actual tree structure.  @endif
+    _Rep_type _M_t;
+  
+  public:
+    // many of these are specified differently in ISO, but the following are
+    // "functionally equivalent"
+    typedef typename _Rep_type::allocator_type            allocator_type;
+    typedef typename _Rep_type::reference                 reference;
+    typedef typename _Rep_type::const_reference           const_reference;
+    typedef typename _Rep_type::iterator                  iterator;
+    typedef typename _Rep_type::const_iterator            const_iterator;
+    typedef typename _Rep_type::size_type                 size_type;
+    typedef typename _Rep_type::difference_type           difference_type;
+    typedef typename _Rep_type::pointer                   pointer;
+    typedef typename _Rep_type::const_pointer             const_pointer;
+    typedef typename _Rep_type::reverse_iterator          reverse_iterator;
+    typedef typename _Rep_type::const_reverse_iterator    const_reverse_iterator;
+  
+  
+    // [23.3.1.1] construct/copy/destroy
+    // (get_allocator() is normally listed in this section, but seems to have
+    // been accidentally omitted in the printed standard)
+    /**
+     *  @brief  Default constructor creates no elements.
+    */
+    map() : _M_t(_Compare(), allocator_type()) { }
+  
+    // for some reason this was made a separate function
+    /**
+     *  @brief  Default constructor creates no elements.
+    */
+    explicit
+    map(const _Compare& __comp, const allocator_type& __a = allocator_type())
+      : _M_t(__comp, __a) { }
+  
+    /**
+     *  @brief  Map copy constructor.
+     *  @param  x  A %map of identical element and allocator types.
+     *
+     *  The newly-created %map uses a copy of the allocation object used
+     *  by @a x.
+    */
+    map(const map& __x)
+      : _M_t(__x._M_t) { }
+  
+    /**
+     *  @brief  Builds a %map from a range.
+     *  @param  first  An input iterator.
+     *  @param  last  An input iterator.
+     *
+     *  Create a %map consisting of copies of the elements from [first,last).
+     *  This is linear in N if the range is already sorted, and NlogN
+     *  otherwise (where N is distance(first,last)).
+    */
+    template <typename _InputIterator>
+      map(_InputIterator __first, _InputIterator __last)
+      : _M_t(_Compare(), allocator_type())
       { _M_t.insert_unique(__first, __last); }
-
-  /**
-   *  @brief Erases an element from a %map.
-   *  @param  position  An iterator pointing to the element to be erased.
-   *
-   *  This function erases an element, pointed to by the given iterator, from
-   *  a %map.  Note that this function only erases the element, and that if
-   *  the element is itself a pointer, the pointed-to memory is not touched
-   *  in any way.  Managing the pointer is the user's responsibilty.
-  */
-  void
-  erase(iterator __position) { _M_t.erase(__position); }
-
-  /**
-   *  @brief Erases elements according to the provided key.
-   *  @param  x  Key of element to be erased.
-   *  @return  The number of elements erased.
-   *
-   *  This function erases all the elements located by the given key from
-   *  a %map.
-   *  Note that this function only erases the element, and that if
-   *  the element is itself a pointer, the pointed-to memory is not touched
-   *  in any way.  Managing the pointer is the user's responsibilty.
-  */
-  size_type
-  erase(const key_type& __x) { return _M_t.erase(__x); }
-
-  /**
-   *  @brief Erases a [first,last) range of elements from a %map.
-   *  @param  first  Iterator pointing to the start of the range to be erased.
-   *  @param  last  Iterator pointing to the end of the range to be erased.
-   *
-   *  This function erases a sequence of elements from a %map.
-   *  Note that this function only erases the element, and that if
-   *  the element is itself a pointer, the pointed-to memory is not touched
-   *  in any way.  Managing the pointer is the user's responsibilty.
-  */
-  void
-  erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); }
-
-  /**
-   *  @brief  Swaps data with another %map.
-   *  @param  x  A %map of the same element and allocator types.
-   *
-   *  This exchanges the elements between two maps in constant time.
-   *  (It is only swapping a pointer, an integer, and an instance of
-   *  the @c Compare type (which itself is often stateless and empty), so it
-   *  should be quite fast.)
-   *  Note that the global std::swap() function is specialized such that
-   *  std::swap(m1,m2) will feed to this function.
-  */
-  void
-  swap(map& __x) { _M_t.swap(__x._M_t); }
-
-  /**
-   *  Erases all elements in a %map.  Note that this function only erases
-   *  the elements, and that if the elements themselves are pointers, the
-   *  pointed-to memory is not touched in any way.  Managing the pointer is
-   *  the user's responsibilty.
-  */
-  void
-  clear() { _M_t.clear(); }
-
-  // observers
-  /**
-   *  Returns the key comparison object out of which the %map was constructed.
-  */
-  key_compare
-  key_comp() const { return _M_t.key_comp(); }
-
-  /**
-   *  Returns a value comparison object, built from the key comparison
-   *  object out of which the %map was constructed.
-  */
-  value_compare
-  value_comp() const { return value_compare(_M_t.key_comp()); }
-
-  // [23.3.1.3] map operations
-  /**
-   *  @brief Tries to locate an element in a %map.
-   *  @param  x  Key of (key, value) %pair to be located.
-   *  @return  Iterator pointing to sought-after element, or end() if not
-   *           found.
-   *
-   *  This function takes a key and tries to locate the element with which
-   *  the key matches.  If successful the function returns an iterator
-   *  pointing to the sought after %pair.  If unsuccessful it returns the
-   *  past-the-end ( @c end() ) iterator.
-  */
-  iterator
-  find(const key_type& __x) { return _M_t.find(__x); }
-
-  /**
-   *  @brief Tries to locate an element in a %map.
-   *  @param  x  Key of (key, value) %pair to be located.
-   *  @return  Read-only (constant) iterator pointing to sought-after
-   *           element, or end() if not found.
-   *
-   *  This function takes a key and tries to locate the element with which
-   *  the key matches.  If successful the function returns a constant iterator
-   *  pointing to the sought after %pair. If unsuccessful it returns the
-   *  past-the-end ( @c end() ) iterator.
-  */
-  const_iterator
-  find(const key_type& __x) const { return _M_t.find(__x); }
-
-  /**
-   *  @brief  Finds the number of elements with given key.
-   *  @param  x  Key of (key, value) pairs to be located.
-   *  @return  Number of elements with specified key.
-   *
-   *  This function only makes sense for multimaps; for map the result will
-   *  either be 0 (not present) or 1 (present).
-  */
-  size_type
-  count(const key_type& __x) const
-    { return _M_t.find(__x) == _M_t.end() ? 0 : 1; }
-
-  /**
-   *  @brief Finds the beginning of a subsequence matching given key.
-   *  @param  x  Key of (key, value) pair to be located.
-   *  @return  Iterator pointing to first element matching given key, or
-   *           end() if not found.
-   *
-   *  This function is useful only with multimaps.  It returns the first
-   *  element of a subsequence of elements that matches the given key.  If
-   *  unsuccessful it returns an iterator pointing to the first element that
-   *  has a greater value than given key or end() if no such element exists.
-  */
-  iterator
-  lower_bound(const key_type& __x) { return _M_t.lower_bound(__x); }
-
-  /**
-   *  @brief Finds the beginning of a subsequence matching given key.
-   *  @param  x  Key of (key, value) pair to be located.
-   *  @return  Read-only (constant) iterator pointing to first element
-   *           matching given key, or end() if not found.
-   *
-   *  This function is useful only with multimaps.  It returns the first
-   *  element of a subsequence of elements that matches the given key.  If
-   *  unsuccessful the iterator will point to the next greatest element or,
-   *  if no such greater element exists, to end().
-  */
-  const_iterator
-  lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); }
-
-  /**
-   *  @brief Finds the end of a subsequence matching given key.
-   *  @param  x  Key of (key, value) pair to be located.
-   *  @return Iterator pointing to last element matching given key.
-   *
-   *  This function only makes sense with multimaps.
-  */
-  iterator
-  upper_bound(const key_type& __x) { return _M_t.upper_bound(__x); }
-
-  /**
-   *  @brief Finds the end of a subsequence matching given key.
-   *  @param  x  Key of (key, value) pair to be located.
-   *  @return  Read-only (constant) iterator pointing to last element matching
-   *           given key.
-   *
-   *  This function only makes sense with multimaps.
-  */
-  const_iterator
-  upper_bound(const key_type& __x) const
-    { return _M_t.upper_bound(__x); }
-
-  /**
-   *  @brief Finds a subsequence matching given key.
-   *  @param  x  Key of (key, value) pairs to be located.
-   *  @return  Pair of iterators that possibly points to the subsequence
-   *           matching given key.
-   *
-   *  This function returns a pair of which the first
-   *  element possibly points to the first element matching the given key
-   *  and the second element possibly points to the last element matching the
-   *  given key.  If unsuccessful the first element of the returned pair will
-   *  contain an iterator pointing to the next greatest element or, if no such
-   *  greater element exists, to end().
+  
+    /**
+     *  @brief  Builds a %map from a range.
+     *  @param  first  An input iterator.
+     *  @param  last  An input iterator.
+     *  @param  comp  A comparison functor.
+     *  @param  a  An allocator object.
+     *
+     *  Create a %map consisting of copies of the elements from [first,last).
+     *  This is linear in N if the range is already sorted, and NlogN
+     *  otherwise (where N is distance(first,last)).
+    */
+    template <typename _InputIterator>
+      map(_InputIterator __first, _InputIterator __last,
+          const _Compare& __comp, const allocator_type& __a = allocator_type())
+      : _M_t(__comp, __a)
+      { _M_t.insert_unique(__first, __last); }
+  
+    // FIXME There is no dtor declared, but we should have something generated
+    // by Doxygen.  I don't know what tags to add to this paragraph to make
+    // that happen:
+    /**
+     *  The dtor only erases the elements, and note that if the elements
+     *  themselves are pointers, the pointed-to memory is not touched in any
+     *  way.  Managing the pointer is the user's responsibilty.
+    */
+  
+    /**
+     *  @brief  Map assignment operator.
+     *  @param  x  A %map of identical element and allocator types.
+     *
+     *  All the elements of @a x are copied, but unlike the copy constructor,
+     *  the allocator object is not copied.
+    */
+    map&
+    operator=(const map& __x)
+    {
+      _M_t = __x._M_t;
+      return *this;
+    }
+  
+    /// Get a copy of the memory allocation object.
+    allocator_type
+    get_allocator() const { return _M_t.get_allocator(); }
+  
+    // iterators
+    /**
+     *  Returns a read/write iterator that points to the first pair in the %map.
+     *  Iteration is done in ascending order according to the keys.
+    */
+    iterator
+    begin() { return _M_t.begin(); }
+  
+    /**
+     *  Returns a read-only (constant) iterator that points to the first pair
+     *  in the %map.  Iteration is done in ascending order according to the
+     *  keys.
+    */
+    const_iterator
+    begin() const { return _M_t.begin(); }
+  
+    /**
+     *  Returns a read/write iterator that points one past the last pair in the
+     *  %map.  Iteration is done in ascending order according to the keys.
+    */
+    iterator
+    end() { return _M_t.end(); }
+  
+    /**
+     *  Returns a read-only (constant) iterator that points one past the last
+     *  pair in the %map.  Iteration is done in ascending order according to the
+     *  keys.
+    */
+    const_iterator
+    end() const { return _M_t.end(); }
+  
+    /**
+     *  Returns a read/write reverse iterator that points to the last pair in
+     *  the %map.  Iteration is done in descending order according to the keys.
+    */
+    reverse_iterator
+    rbegin() { return _M_t.rbegin(); }
+  
+    /**
+     *  Returns a read-only (constant) reverse iterator that points to the last
+     *  pair in the %map.  Iteration is done in descending order according to
+     *  the keys.
+    */
+    const_reverse_iterator
+    rbegin() const { return _M_t.rbegin(); }
+  
+    /**
+     *  Returns a read/write reverse iterator that points to one before the
+     *  first pair in the %map.  Iteration is done in descending order according
+     *  to the keys.
+    */
+    reverse_iterator
+    rend() { return _M_t.rend(); }
+  
+    /**
+     *  Returns a read-only (constant) reverse iterator that points to one
+     *  before the first pair in the %map.  Iteration is done in descending
+     *  order according to the keys.
+    */
+    const_reverse_iterator
+    rend() const { return _M_t.rend(); }
+  
+    // capacity
+    /** Returns true if the %map is empty.  (Thus begin() would equal end().) */
+    bool
+    empty() const { return _M_t.empty(); }
+  
+    /** Returns the size of the %map.  */
+    size_type
+    size() const { return _M_t.size(); }
+  
+    /** Returns the maximum size of the %map.  */
+    size_type
+    max_size() const { return _M_t.max_size(); }
+  
+    // [23.3.1.2] element access
+    /**
+     *  @brief  Subscript ( @c [] ) access to %map data.
+     *  @param  k  The key for which data should be retrieved.
+     *  @return  A reference to the data of the (key,data) %pair.
+     *
+     *  Allows for easy lookup with the subscript ( @c [] ) operator.  Returns
+     *  data associated with the key specified in subscript.  If the key does
+     *  not exist, a pair with that key is created using default values, which
+     *  is then returned.
+     *
+     *  Lookup requires logarithmic time.
+    */
+    mapped_type&
+    operator[](const key_type& __k)
+    {
+      // concept requirements
+      __glibcpp_function_requires(_DefaultConstructibleConcept<mapped_type>)
+  
+      iterator __i = lower_bound(__k);
+      // __i->first is greater than or equivalent to __k.
+      if (__i == end() || key_comp()(__k, (*__i).first))
+        __i = insert(__i, value_type(__k, mapped_type()));
+      return (*__i).second;
+    }
+  
+    // modifiers
+    /**
+     *  @brief Attempts to insert a std::pair into the %map.
+     *  @param  x  Pair to be inserted (see std::make_pair for easy creation of
+     *             pairs).
+     *  @return  A pair, of which the first element is an iterator that points
+     *           to the possibly inserted pair, and the second is a bool that
+     *           is true if the pair was actually inserted.
+     *
+     *  This function attempts to insert a (key, value) %pair into the %map.
+     *  A %map relies on unique keys and thus a %pair is only inserted if its
+     *  first element (the key) is not already present in the %map.
+     *
+     *  Insertion requires logarithmic time.
+    */
+    pair<iterator,bool>
+    insert(const value_type& __x)
+      { return _M_t.insert_unique(__x); }
+  
+    /**
+     *  @brief Attempts to insert a std::pair into the %map.
+     *  @param  position  An iterator that serves as a hint as to where the
+     *                    pair should be inserted.
+     *  @param  x  Pair to be inserted (see std::make_pair for easy creation of
+     *             pairs).
+     *  @return  An iterator that points to the element with key of @a x (may
+     *           or may not be the %pair passed in).
+     *
+     *  This function is not concerned about whether the insertion took place,
+     *  and thus does not return a boolean like the single-argument
+     *  insert() does.  Note that the first parameter is only a hint and can
+     *  potentially improve the performance of the insertion process.  A bad
+     *  hint would cause no gains in efficiency.
+     *
+     *  See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4
+     *  for more on "hinting".
+     *
+     *  Insertion requires logarithmic time (if the hint is not taken).
+    */
+    iterator
+    insert(iterator position, const value_type& __x)
+      { return _M_t.insert_unique(position, __x); }
+  
+    /**
+     *  @brief A template function that attemps to insert a range of elements.
+     *  @param  first  Iterator pointing to the start of the range to be
+     *                 inserted.
+     *  @param  last  Iterator pointing to the end of the range.
+     *
+     *  Complexity similar to that of the range constructor.
+    */
+    template <typename _InputIterator>
+      void
+      insert(_InputIterator __first, _InputIterator __last)
+        { _M_t.insert_unique(__first, __last); }
+  
+    /**
+     *  @brief Erases an element from a %map.
+     *  @param  position  An iterator pointing to the element to be erased.
+     *
+     *  This function erases an element, pointed to by the given iterator, from
+     *  a %map.  Note that this function only erases the element, and that if
+     *  the element is itself a pointer, the pointed-to memory is not touched
+     *  in any way.  Managing the pointer is the user's responsibilty.
+    */
+    void
+    erase(iterator __position) { _M_t.erase(__position); }
+  
+    /**
+     *  @brief Erases elements according to the provided key.
+     *  @param  x  Key of element to be erased.
+     *  @return  The number of elements erased.
+     *
+     *  This function erases all the elements located by the given key from
+     *  a %map.
+     *  Note that this function only erases the element, and that if
+     *  the element is itself a pointer, the pointed-to memory is not touched
+     *  in any way.  Managing the pointer is the user's responsibilty.
+    */
+    size_type
+    erase(const key_type& __x) { return _M_t.erase(__x); }
+  
+    /**
+     *  @brief Erases a [first,last) range of elements from a %map.
+     *  @param  first  Iterator pointing to the start of the range to be erased.
+     *  @param  last  Iterator pointing to the end of the range to be erased.
+     *
+     *  This function erases a sequence of elements from a %map.
+     *  Note that this function only erases the element, and that if
+     *  the element is itself a pointer, the pointed-to memory is not touched
+     *  in any way.  Managing the pointer is the user's responsibilty.
+    */
+    void
+    erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); }
+  
+    /**
+     *  @brief  Swaps data with another %map.
+     *  @param  x  A %map of the same element and allocator types.
+     *
+     *  This exchanges the elements between two maps in constant time.
+     *  (It is only swapping a pointer, an integer, and an instance of
+     *  the @c Compare type (which itself is often stateless and empty), so it
+     *  should be quite fast.)
+     *  Note that the global std::swap() function is specialized such that
+     *  std::swap(m1,m2) will feed to this function.
+    */
+    void
+    swap(map& __x) { _M_t.swap(__x._M_t); }
+  
+    /**
+     *  Erases all elements in a %map.  Note that this function only erases
+     *  the elements, and that if the elements themselves are pointers, the
+     *  pointed-to memory is not touched in any way.  Managing the pointer is
+     *  the user's responsibilty.
+    */
+    void
+    clear() { _M_t.clear(); }
+  
+    // observers
+    /**
+     *  Returns the key comparison object out of which the %map was constructed.
+    */
+    key_compare
+    key_comp() const { return _M_t.key_comp(); }
+  
+    /**
+     *  Returns a value comparison object, built from the key comparison
+     *  object out of which the %map was constructed.
+    */
+    value_compare
+    value_comp() const { return value_compare(_M_t.key_comp()); }
+  
+    // [23.3.1.3] map operations
+    /**
+     *  @brief Tries to locate an element in a %map.
+     *  @param  x  Key of (key, value) %pair to be located.
+     *  @return  Iterator pointing to sought-after element, or end() if not
+     *           found.
+     *
+     *  This function takes a key and tries to locate the element with which
+     *  the key matches.  If successful the function returns an iterator
+     *  pointing to the sought after %pair.  If unsuccessful it returns the
+     *  past-the-end ( @c end() ) iterator.
+    */
+    iterator
+    find(const key_type& __x) { return _M_t.find(__x); }
+  
+    /**
+     *  @brief Tries to locate an element in a %map.
+     *  @param  x  Key of (key, value) %pair to be located.
+     *  @return  Read-only (constant) iterator pointing to sought-after
+     *           element, or end() if not found.
+     *
+     *  This function takes a key and tries to locate the element with which
+     *  the key matches.  If successful the function returns a constant iterator
+     *  pointing to the sought after %pair. If unsuccessful it returns the
+     *  past-the-end ( @c end() ) iterator.
+    */
+    const_iterator
+    find(const key_type& __x) const { return _M_t.find(__x); }
+  
+    /**
+     *  @brief  Finds the number of elements with given key.
+     *  @param  x  Key of (key, value) pairs to be located.
+     *  @return  Number of elements with specified key.
+     *
+     *  This function only makes sense for multimaps; for map the result will
+     *  either be 0 (not present) or 1 (present).
+    */
+    size_type
+    count(const key_type& __x) const
+      { return _M_t.find(__x) == _M_t.end() ? 0 : 1; }
+  
+    /**
+     *  @brief Finds the beginning of a subsequence matching given key.
+     *  @param  x  Key of (key, value) pair to be located.
+     *  @return  Iterator pointing to first element matching given key, or
+     *           end() if not found.
+     *
+     *  This function is useful only with multimaps.  It returns the first
+     *  element of a subsequence of elements that matches the given key.  If
+     *  unsuccessful it returns an iterator pointing to the first element that
+     *  has a greater value than given key or end() if no such element exists.
+    */
+    iterator
+    lower_bound(const key_type& __x) { return _M_t.lower_bound(__x); }
+  
+    /**
+     *  @brief Finds the beginning of a subsequence matching given key.
+     *  @param  x  Key of (key, value) pair to be located.
+     *  @return  Read-only (constant) iterator pointing to first element
+     *           matching given key, or end() if not found.
+     *
+     *  This function is useful only with multimaps.  It returns the first
+     *  element of a subsequence of elements that matches the given key.  If
+     *  unsuccessful the iterator will point to the next greatest element or,
+     *  if no such greater element exists, to end().
+    */
+    const_iterator
+    lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); }
+  
+    /**
+     *  @brief Finds the end of a subsequence matching given key.
+     *  @param  x  Key of (key, value) pair to be located.
+     *  @return Iterator pointing to last element matching given key.
+     *
+     *  This function only makes sense with multimaps.
+    */
+    iterator
+    upper_bound(const key_type& __x) { return _M_t.upper_bound(__x); }
+  
+    /**
+     *  @brief Finds the end of a subsequence matching given key.
+     *  @param  x  Key of (key, value) pair to be located.
+     *  @return  Read-only (constant) iterator pointing to last element matching
+     *           given key.
+     *
+     *  This function only makes sense with multimaps.
+    */
+    const_iterator
+    upper_bound(const key_type& __x) const
+      { return _M_t.upper_bound(__x); }
+  
+    /**
+     *  @brief Finds a subsequence matching given key.
+     *  @param  x  Key of (key, value) pairs to be located.
+     *  @return  Pair of iterators that possibly points to the subsequence
+     *           matching given key.
+     *
+     *  This function returns a pair of which the first
+     *  element possibly points to the first element matching the given key
+     *  and the second element possibly points to the last element matching the
+     *  given key.  If unsuccessful the first element of the returned pair will
+     *  contain an iterator pointing to the next greatest element or, if no such
+     *  greater element exists, to end().
+     *
+     *  This function only makes sense for multimaps.
+    */
+    pair<iterator,iterator>
+    equal_range(const key_type& __x)
+      { return _M_t.equal_range(__x); }
+  
+    /**
+     *  @brief Finds a subsequence matching given key.
+     *  @param  x  Key of (key, value) pairs to be located.
+     *  @return  Pair of read-only (constant) iterators that possibly points to
+     *           the subsequence matching given key.
+     *
+     *  This function returns a pair of which the first
+     *  element possibly points to the first element matching the given key
+     *  and the second element possibly points to the last element matching the
+     *  given key.  If unsuccessful the first element of the returned pair will
+     *  contain an iterator pointing to the next greatest element or, if no such
+     *  a greater element exists, to end().
+     *
+     *  This function only makes sense for multimaps.
+    */
+    pair<const_iterator,const_iterator>
+    equal_range(const key_type& __x) const
+      { return _M_t.equal_range(__x); }
+  
+    template <typename _K1, typename _T1, typename _C1, typename _A1>
+    friend bool operator== (const map<_K1,_T1,_C1,_A1>&,
+                            const map<_K1,_T1,_C1,_A1>&);
+    template <typename _K1, typename _T1, typename _C1, typename _A1>
+    friend bool operator< (const map<_K1,_T1,_C1,_A1>&,
+                           const map<_K1,_T1,_C1,_A1>&);
+  };
+  
+  
+  /**
+   *  @brief  Map equality comparison.
+   *  @param  x  A %map.
+   *  @param  y  A %map of the same type as @a x.
+   *  @return  True iff the size and elements of the maps are equal.
    *
-   *  This function only makes sense for multimaps.
-  */
-  pair<iterator,iterator>
-  equal_range(const key_type& __x)
-    { return _M_t.equal_range(__x); }
-
-  /**
-   *  @brief Finds a subsequence matching given key.
-   *  @param  x  Key of (key, value) pairs to be located.
-   *  @return  Pair of read-only (constant) iterators that possibly points to
-   *           the subsequence matching given key.
+   *  This is an equivalence relation.  It is linear in the size of the
+   *  maps.  Maps are considered equivalent if their sizes are equal,
+   *  and if corresponding elements compare equal.
+  */
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+    inline bool
+    operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x,
+               const map<_Key,_Tp,_Compare,_Alloc>& __y)
+    { return __x._M_t == __y._M_t; }
+  
+  /**
+   *  @brief  Map ordering relation.
+   *  @param  x  A %map.
+   *  @param  y  A %map of the same type as @a x.
+   *  @return  True iff @a x is lexographically less than @a y.
    *
-   *  This function returns a pair of which the first
-   *  element possibly points to the first element matching the given key
-   *  and the second element possibly points to the last element matching the
-   *  given key.  If unsuccessful the first element of the returned pair will
-   *  contain an iterator pointing to the next greatest element or, if no such
-   *  a greater element exists, to end().
+   *  This is a total ordering relation.  It is linear in the size of the
+   *  maps.  The elements must be comparable with @c <.
    *
-   *  This function only makes sense for multimaps.
-  */
-  pair<const_iterator,const_iterator>
-  equal_range(const key_type& __x) const
-    { return _M_t.equal_range(__x); }
-
-  template <typename _K1, typename _T1, typename _C1, typename _A1>
-  friend bool operator== (const map<_K1,_T1,_C1,_A1>&,
-                          const map<_K1,_T1,_C1,_A1>&);
-  template <typename _K1, typename _T1, typename _C1, typename _A1>
-  friend bool operator< (const map<_K1,_T1,_C1,_A1>&,
-                         const map<_K1,_T1,_C1,_A1>&);
-};
-
-
-/**
- *  @brief  Map equality comparison.
- *  @param  x  A %map.
- *  @param  y  A %map of the same type as @a x.
- *  @return  True iff the size and elements of the maps are equal.
- *
- *  This is an equivalence relation.  It is linear in the size of the
- *  maps.  Maps are considered equivalent if their sizes are equal,
- *  and if corresponding elements compare equal.
-*/
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-  inline bool
-  operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x,
-             const map<_Key,_Tp,_Compare,_Alloc>& __y)
-  { return __x._M_t == __y._M_t; }
-
-/**
- *  @brief  Map ordering relation.
- *  @param  x  A %map.
- *  @param  y  A %map of the same type as @a x.
- *  @return  True iff @a x is lexographically less than @a y.
- *
- *  This is a total ordering relation.  It is linear in the size of the
- *  maps.  The elements must be comparable with @c <.
- *
- *  See std::lexographical_compare() for how the determination is made.
-*/
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-  inline bool
-  operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x,
-            const map<_Key,_Tp,_Compare,_Alloc>& __y)
-  { return __x._M_t < __y._M_t; }
-
-/// Based on operator==
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-  inline bool
-  operator!=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
-             const map<_Key,_Tp,_Compare,_Alloc>& __y)
-  { return !(__x == __y); }
-
-/// Based on operator<
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-  inline bool
-  operator>(const map<_Key,_Tp,_Compare,_Alloc>& __x,
-            const map<_Key,_Tp,_Compare,_Alloc>& __y)
-  { return __y < __x; }
-
-/// Based on operator<
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-  inline bool
-  operator<=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
-             const map<_Key,_Tp,_Compare,_Alloc>& __y)
-  { return !(__y < __x); }
-
-/// Based on operator<
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-  inline bool
-  operator>=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
-             const map<_Key,_Tp,_Compare,_Alloc>& __y)
-  { return !(__x < __y); }
-
-/// See std::map::swap().
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-  inline void
-  swap(map<_Key,_Tp,_Compare,_Alloc>& __x, map<_Key,_Tp,_Compare,_Alloc>& __y)
-  { __x.swap(__y); }
-
+   *  See std::lexographical_compare() for how the determination is made.
+  */
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+    inline bool
+    operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x,
+              const map<_Key,_Tp,_Compare,_Alloc>& __y)
+    { return __x._M_t < __y._M_t; }
+  
+  /// Based on operator==
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+    inline bool
+    operator!=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
+               const map<_Key,_Tp,_Compare,_Alloc>& __y)
+    { return !(__x == __y); }
+  
+  /// Based on operator<
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+    inline bool
+    operator>(const map<_Key,_Tp,_Compare,_Alloc>& __x,
+              const map<_Key,_Tp,_Compare,_Alloc>& __y)
+    { return __y < __x; }
+  
+  /// Based on operator<
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+    inline bool
+    operator<=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
+               const map<_Key,_Tp,_Compare,_Alloc>& __y)
+    { return !(__y < __x); }
+  
+  /// Based on operator<
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+    inline bool
+    operator>=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
+               const map<_Key,_Tp,_Compare,_Alloc>& __y)
+    { return !(__x < __y); }
+  
+  /// See std::map::swap().
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+    inline void
+    swap(map<_Key,_Tp,_Compare,_Alloc>& __x, map<_Key,_Tp,_Compare,_Alloc>& __y)
+    { __x.swap(__y); }
 } // namespace std
 
 #endif /* __GLIBCPP_INTERNAL_MAP_H */
-
index d85c4fd..9cf8e0c 100644 (file)
 
 #include <bits/concept_check.h>
 
-// Since this entire file is within namespace std, there's no reason to
-// waste two spaces along the left column.  Thus the leading indentation is
-// slightly violated from here on.
 namespace std
 {
-
-// Forward declaration of operators < and ==, needed for friend declaration.
-
-template <typename _Key, typename _Tp,
-          typename _Compare = less<_Key>,
-          typename _Alloc = allocator<pair<const _Key, _Tp> > >
-class multimap;
-
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
-                       const multimap<_Key,_Tp,_Compare,_Alloc>& __y);
-
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
-                      const multimap<_Key,_Tp,_Compare,_Alloc>& __y);
-
-/**
- *  @brief A standard container made up of (key,value) pairs, which can be
- *  retrieved based on a key, in logarithmic time.
- *
- *  @ingroup Containers
- *  @ingroup Assoc_containers
- *
- *  Meets the requirements of a <a href="tables.html#65">container</a>, a
- *  <a href="tables.html#66">reversible container</a>, and an
- *  <a href="tables.html#69">associative container</a> (using equivalent keys).
- *  For a @c multimap<Key,T> the key_type is Key, the mapped_type is T, and
- *  the value_type is std::pair<const Key,T>.
- *
- *  Multimaps support bidirectional iterators.
- *
- *  @if maint
- *  The private tree data is declared exactly the same way for map and
- *  multimap; the distinction is made entirely in how the tree functions are
- *  called (*_unique versus *_equal, same as the standard).
- *  @endif
-*/
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-  class multimap
-{
-  // concept requirements
-  __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
-  __glibcpp_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept)
-
-public:
-  typedef _Key                                          key_type;
-  typedef _Tp                                           mapped_type;
-  typedef pair<const _Key, _Tp>                         value_type;
-  typedef _Compare                                      key_compare;
-
-  class value_compare
-    : public binary_function<value_type, value_type, bool>
-    {
-      friend class multimap<_Key,_Tp,_Compare,_Alloc>;
-    protected:
-      _Compare comp;
-      value_compare(_Compare __c) : comp(__c) {}
-    public:
-      bool operator()(const value_type& __x, const value_type& __y) const
-        { return comp(__x.first, __y.first); }
-  };
-
-private:
-  /// @if maint  This turns a red-black tree into a [multi]map.  @endif
-  typedef _Rb_tree<key_type, value_type,
-                  _Select1st<value_type>, key_compare, _Alloc> _Rep_type;
-  /// @if maint  The actual tree structure.  @endif
-  _Rep_type _M_t;
-
-public:
-  // many of these are specified differently in ISO, but the following are
-  // "functionally equivalent"
-  typedef typename _Rep_type::allocator_type            allocator_type;
-  typedef typename _Rep_type::reference                 reference;
-  typedef typename _Rep_type::const_reference           const_reference;
-  typedef typename _Rep_type::iterator                  iterator;
-  typedef typename _Rep_type::const_iterator            const_iterator;
-  typedef typename _Rep_type::size_type                 size_type;
-  typedef typename _Rep_type::difference_type           difference_type;
-  typedef typename _Rep_type::pointer                   pointer;
-  typedef typename _Rep_type::const_pointer             const_pointer;
-  typedef typename _Rep_type::reverse_iterator          reverse_iterator;
-  typedef typename _Rep_type::const_reverse_iterator    const_reverse_iterator;
-
-
-  // [23.3.2] construct/copy/destroy
-  // (get_allocator() is also listed in this section)
-  /**
-   *  @brief  Default constructor creates no elements.
-  */
-  multimap() : _M_t(_Compare(), allocator_type()) { }
-
-  // for some reason this was made a separate function
-  /**
-   *  @brief  Default constructor creates no elements.
-  */
-  explicit
-  multimap(const _Compare& __comp, const allocator_type& __a = allocator_type())
-    : _M_t(__comp, __a) { }
-
-  /**
-   *  @brief  %Multimap copy constructor.
-   *  @param  x  A %multimap of identical element and allocator types.
+  // Forward declaration of operators < and ==, needed for friend declaration.
+  
+  template <typename _Key, typename _Tp,
+            typename _Compare = less<_Key>,
+            typename _Alloc = allocator<pair<const _Key, _Tp> > >
+  class multimap;
+  
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+  inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+                         const multimap<_Key,_Tp,_Compare,_Alloc>& __y);
+  
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+  inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+                        const multimap<_Key,_Tp,_Compare,_Alloc>& __y);
+  
+  /**
+   *  @brief A standard container made up of (key,value) pairs, which can be
+   *  retrieved based on a key, in logarithmic time.
    *
-   *  The newly-created %multimap uses a copy of the allocation object used
-   *  by @a x.
-  */
-  multimap(const multimap& __x)
-    : _M_t(__x._M_t) { }
-
-  /**
-   *  @brief  Builds a %multimap from a range.
-   *  @param  first  An input iterator.
-   *  @param  last  An input iterator.
+   *  @ingroup Containers
+   *  @ingroup Assoc_containers
    *
-   *  Create a %multimap consisting of copies of the elements from
-   *  [first,last).  This is linear in N if the range is already sorted,
-   *  and NlogN otherwise (where N is distance(first,last)).
-  */
-  template <typename _InputIterator>
-    multimap(_InputIterator __first, _InputIterator __last)
-      : _M_t(_Compare(), allocator_type())
-      { _M_t.insert_equal(__first, __last); }
-
-  /**
-   *  @brief  Builds a %multimap from a range.
-   *  @param  first  An input iterator.
-   *  @param  last  An input iterator.
-   *  @param  comp  A comparison functor.
-   *  @param  a  An allocator object.
+   *  Meets the requirements of a <a href="tables.html#65">container</a>, a
+   *  <a href="tables.html#66">reversible container</a>, and an
+   *  <a href="tables.html#69">associative container</a> (using equivalent
+   *  keys).  For a @c multimap<Key,T> the key_type is Key, the mapped_type
+   *  is T, and the value_type is std::pair<const Key,T>.
    *
-   *  Create a %multimap consisting of copies of the elements from [first,last).
-   *  This is linear in N if the range is already sorted, and NlogN
-   *  otherwise (where N is distance(first,last)).
-  */
-  template <typename _InputIterator>
-    multimap(_InputIterator __first, _InputIterator __last,
-             const _Compare& __comp,
-             const allocator_type& __a = allocator_type())
-      : _M_t(__comp, __a)
-      { _M_t.insert_equal(__first, __last); }
-
-  // FIXME There is no dtor declared, but we should have something generated
-  // by Doxygen.  I don't know what tags to add to this paragraph to make
-  // that happen:
-  /**
-   *  The dtor only erases the elements, and note that if the elements
-   *  themselves are pointers, the pointed-to memory is not touched in any
-   *  way.  Managing the pointer is the user's responsibilty.
-  */
-
-  /**
-   *  @brief  %Multimap assignment operator.
-   *  @param  x  A %multimap of identical element and allocator types.
+   *  Multimaps support bidirectional iterators.
    *
-   *  All the elements of @a x are copied, but unlike the copy constructor, the
-   *  allocator object is not copied.
-  */
-  multimap&
-  operator=(const multimap& __x)
+   *  @if maint
+   *  The private tree data is declared exactly the same way for map and
+   *  multimap; the distinction is made entirely in how the tree functions are
+   *  called (*_unique versus *_equal, same as the standard).
+   *  @endif
+  */
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+    class multimap
   {
-    _M_t = __x._M_t;
-    return *this;
-  }
-
-  /// Get a copy of the memory allocation object.
-  allocator_type
-  get_allocator() const { return _M_t.get_allocator(); }
-
-  // iterators
-  /**
-   *  Returns a read/write iterator that points to the first pair in the
-   *  %multimap.  Iteration is done in ascending order according to the keys.
-  */
-  iterator
-  begin() { return _M_t.begin(); }
-
-  /**
-   *  Returns a read-only (constant) iterator that points to the first pair
-   *  in the %multimap.  Iteration is done in ascending order according to the
-   *  keys.
-  */
-  const_iterator
-  begin() const { return _M_t.begin(); }
-
-  /**
-   *  Returns a read/write iterator that points one past the last pair in the
-   *  %multimap.  Iteration is done in ascending order according to the keys.
-  */
-  iterator
-  end() { return _M_t.end(); }
-
-  /**
-   *  Returns a read-only (constant) iterator that points one past the last
-   *  pair in the %multimap.  Iteration is done in ascending order according
-   *  to the keys.
-  */
-  const_iterator
-  end() const { return _M_t.end(); }
-
-  /**
-   *  Returns a read/write reverse iterator that points to the last pair in
-   *  the %multimap.  Iteration is done in descending order according to the
-   *  keys.
-  */
-  reverse_iterator
-  rbegin() { return _M_t.rbegin(); }
-
-  /**
-   *  Returns a read-only (constant) reverse iterator that points to the last
-   *  pair in the %multimap.  Iteration is done in descending order according
-   *  to the keys.
-  */
-  const_reverse_iterator
-  rbegin() const { return _M_t.rbegin(); }
-
-  /**
-   *  Returns a read/write reverse iterator that points to one before the
-   *  first pair in the %multimap.  Iteration is done in descending order
-   *  according to the keys.
-  */
-  reverse_iterator
-  rend() { return _M_t.rend(); }
-
-  /**
-   *  Returns a read-only (constant) reverse iterator that points to one
-   *  before the first pair in the %multimap.  Iteration is done in descending
-   *  order according to the keys.
-  */
-  const_reverse_iterator
-  rend() const { return _M_t.rend(); }
-
-  // capacity
-  /** Returns true if the %multimap is empty.  */
-  bool
-  empty() const { return _M_t.empty(); }
-
-  /** Returns the size of the %multimap.  */
-  size_type
-  size() const { return _M_t.size(); }
-
-  /** Returns the maximum size of the %multimap.  */
-  size_type
-  max_size() const { return _M_t.max_size(); }
-
-  // modifiers
-  /**
-   *  @brief Inserts a std::pair into the %multimap.
-   *  @param  x  Pair to be inserted (see std::make_pair for easy creation of
-   *             pairs).
-   *  @return An iterator that points to the inserted (key,value) pair.
-   *
-   *  This function inserts a (key, value) pair into the %multimap.  Contrary
-   *  to a std::map the %multimap does not rely on unique keys and thus
-   *  multiple pairs with the same key can be inserted.
-   *
-   *  Insertion requires logarithmic time.
-  */
-  iterator
-  insert(const value_type& __x) { return _M_t.insert_equal(__x); }
-
-  /**
-   *  @brief Inserts a std::pair into the %multimap.
-   *  @param  position  An iterator that serves as a hint as to where the
-   *                    pair should be inserted.
-   *  @param  x  Pair to be inserted (see std::make_pair for easy creation of
-   *             pairs).
-   *  @return An iterator that points to the inserted (key,value) pair.
-   *
-   *  This function inserts a (key, value) pair into the %multimap.  Contrary
-   *  to a std::map the %multimap does not rely on unique keys and thus
-   *  multiple pairs with the same key can be inserted.
-   *  Note that the first parameter is only a hint and can potentially
-   *  improve the performance of the insertion process.  A bad hint would
-   *  cause no gains in efficiency.
-   *
-   *  See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4
-   *  for more on "hinting".
-   *
-   *  Insertion requires logarithmic time (if the hint is not taken).
-  */
-  iterator
-  insert(iterator __position, const value_type& __x)
-    { return _M_t.insert_equal(__position, __x); }
-
-  /**
-   *  @brief A template function that attemps to insert a range of elements.
-   *  @param  first  Iterator pointing to the start of the range to be inserted.
-   *  @param  last  Iterator pointing to the end of the range.
-   *
-   *  Complexity similar to that of the range constructor.
-  */
-  template <typename _InputIterator>
+    // concept requirements
+    __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+    __glibcpp_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept)
+  
+  public:
+    typedef _Key                                          key_type;
+    typedef _Tp                                           mapped_type;
+    typedef pair<const _Key, _Tp>                         value_type;
+    typedef _Compare                                      key_compare;
+  
+    class value_compare
+      : public binary_function<value_type, value_type, bool>
+      {
+        friend class multimap<_Key,_Tp,_Compare,_Alloc>;
+      protected:
+        _Compare comp;
+        value_compare(_Compare __c) : comp(__c) {}
+      public:
+        bool operator()(const value_type& __x, const value_type& __y) const
+          { return comp(__x.first, __y.first); }
+    };
+  
+  private:
+    /// @if maint  This turns a red-black tree into a [multi]map.  @endif
+    typedef _Rb_tree<key_type, value_type,
+                    _Select1st<value_type>, key_compare, _Alloc> _Rep_type;
+    /// @if maint  The actual tree structure.  @endif
+    _Rep_type _M_t;
+  
+  public:
+    // many of these are specified differently in ISO, but the following are
+    // "functionally equivalent"
+    typedef typename _Rep_type::allocator_type            allocator_type;
+    typedef typename _Rep_type::reference                 reference;
+    typedef typename _Rep_type::const_reference           const_reference;
+    typedef typename _Rep_type::iterator                  iterator;
+    typedef typename _Rep_type::const_iterator            const_iterator;
+    typedef typename _Rep_type::size_type                 size_type;
+    typedef typename _Rep_type::difference_type           difference_type;
+    typedef typename _Rep_type::pointer                   pointer;
+    typedef typename _Rep_type::const_pointer             const_pointer;
+    typedef typename _Rep_type::reverse_iterator          reverse_iterator;
+    typedef typename _Rep_type::const_reverse_iterator    const_reverse_iterator;
+  
+  
+    // [23.3.2] construct/copy/destroy
+    // (get_allocator() is also listed in this section)
+    /**
+     *  @brief  Default constructor creates no elements.
+    */
+    multimap() : _M_t(_Compare(), allocator_type()) { }
+  
+    // for some reason this was made a separate function
+    /**
+     *  @brief  Default constructor creates no elements.
+    */
+    explicit
+    multimap(const _Compare& __comp, const allocator_type& __a = allocator_type())
+      : _M_t(__comp, __a) { }
+  
+    /**
+     *  @brief  %Multimap copy constructor.
+     *  @param  x  A %multimap of identical element and allocator types.
+     *
+     *  The newly-created %multimap uses a copy of the allocation object used
+     *  by @a x.
+    */
+    multimap(const multimap& __x)
+      : _M_t(__x._M_t) { }
+  
+    /**
+     *  @brief  Builds a %multimap from a range.
+     *  @param  first  An input iterator.
+     *  @param  last  An input iterator.
+     *
+     *  Create a %multimap consisting of copies of the elements from
+     *  [first,last).  This is linear in N if the range is already sorted,
+     *  and NlogN otherwise (where N is distance(first,last)).
+    */
+    template <typename _InputIterator>
+      multimap(_InputIterator __first, _InputIterator __last)
+        : _M_t(_Compare(), allocator_type())
+        { _M_t.insert_equal(__first, __last); }
+  
+    /**
+     *  @brief  Builds a %multimap from a range.
+     *  @param  first  An input iterator.
+     *  @param  last  An input iterator.
+     *  @param  comp  A comparison functor.
+     *  @param  a  An allocator object.
+     *
+     *  Create a %multimap consisting of copies of the elements from
+     *  [first,last).  This is linear in N if the range is already sorted,
+     *  and NlogN otherwise (where N is distance(first,last)).
+    */
+    template <typename _InputIterator>
+      multimap(_InputIterator __first, _InputIterator __last,
+               const _Compare& __comp,
+               const allocator_type& __a = allocator_type())
+        : _M_t(__comp, __a)
+        { _M_t.insert_equal(__first, __last); }
+  
+    // FIXME There is no dtor declared, but we should have something generated
+    // by Doxygen.  I don't know what tags to add to this paragraph to make
+    // that happen:
+    /**
+     *  The dtor only erases the elements, and note that if the elements
+     *  themselves are pointers, the pointed-to memory is not touched in any
+     *  way.  Managing the pointer is the user's responsibilty.
+    */
+  
+    /**
+     *  @brief  %Multimap assignment operator.
+     *  @param  x  A %multimap of identical element and allocator types.
+     *
+     *  All the elements of @a x are copied, but unlike the copy constructor,
+     *  the allocator object is not copied.
+    */
+    multimap&
+    operator=(const multimap& __x)
+    {
+      _M_t = __x._M_t;
+      return *this;
+    }
+  
+    /// Get a copy of the memory allocation object.
+    allocator_type
+    get_allocator() const { return _M_t.get_allocator(); }
+  
+    // iterators
+    /**
+     *  Returns a read/write iterator that points to the first pair in the
+     *  %multimap.  Iteration is done in ascending order according to the keys.
+    */
+    iterator
+    begin() { return _M_t.begin(); }
+  
+    /**
+     *  Returns a read-only (constant) iterator that points to the first pair
+     *  in the %multimap.  Iteration is done in ascending order according to the
+     *  keys.
+    */
+    const_iterator
+    begin() const { return _M_t.begin(); }
+  
+    /**
+     *  Returns a read/write iterator that points one past the last pair in the
+     *  %multimap.  Iteration is done in ascending order according to the keys.
+    */
+    iterator
+    end() { return _M_t.end(); }
+  
+    /**
+     *  Returns a read-only (constant) iterator that points one past the last
+     *  pair in the %multimap.  Iteration is done in ascending order according
+     *  to the keys.
+    */
+    const_iterator
+    end() const { return _M_t.end(); }
+  
+    /**
+     *  Returns a read/write reverse iterator that points to the last pair in
+     *  the %multimap.  Iteration is done in descending order according to the
+     *  keys.
+    */
+    reverse_iterator
+    rbegin() { return _M_t.rbegin(); }
+  
+    /**
+     *  Returns a read-only (constant) reverse iterator that points to the last
+     *  pair in the %multimap.  Iteration is done in descending order according
+     *  to the keys.
+    */
+    const_reverse_iterator
+    rbegin() const { return _M_t.rbegin(); }
+  
+    /**
+     *  Returns a read/write reverse iterator that points to one before the
+     *  first pair in the %multimap.  Iteration is done in descending order
+     *  according to the keys.
+    */
+    reverse_iterator
+    rend() { return _M_t.rend(); }
+  
+    /**
+     *  Returns a read-only (constant) reverse iterator that points to one
+     *  before the first pair in the %multimap.  Iteration is done in descending
+     *  order according to the keys.
+    */
+    const_reverse_iterator
+    rend() const { return _M_t.rend(); }
+  
+    // capacity
+    /** Returns true if the %multimap is empty.  */
+    bool
+    empty() const { return _M_t.empty(); }
+  
+    /** Returns the size of the %multimap.  */
+    size_type
+    size() const { return _M_t.size(); }
+  
+    /** Returns the maximum size of the %multimap.  */
+    size_type
+    max_size() const { return _M_t.max_size(); }
+  
+    // modifiers
+    /**
+     *  @brief Inserts a std::pair into the %multimap.
+     *  @param  x  Pair to be inserted (see std::make_pair for easy creation of
+     *             pairs).
+     *  @return An iterator that points to the inserted (key,value) pair.
+     *
+     *  This function inserts a (key, value) pair into the %multimap.  Contrary
+     *  to a std::map the %multimap does not rely on unique keys and thus
+     *  multiple pairs with the same key can be inserted.
+     *
+     *  Insertion requires logarithmic time.
+    */
+    iterator
+    insert(const value_type& __x) { return _M_t.insert_equal(__x); }
+  
+    /**
+     *  @brief Inserts a std::pair into the %multimap.
+     *  @param  position  An iterator that serves as a hint as to where the
+     *                    pair should be inserted.
+     *  @param  x  Pair to be inserted (see std::make_pair for easy creation of
+     *             pairs).
+     *  @return An iterator that points to the inserted (key,value) pair.
+     *
+     *  This function inserts a (key, value) pair into the %multimap.  Contrary
+     *  to a std::map the %multimap does not rely on unique keys and thus
+     *  multiple pairs with the same key can be inserted.
+     *  Note that the first parameter is only a hint and can potentially
+     *  improve the performance of the insertion process.  A bad hint would
+     *  cause no gains in efficiency.
+     *
+     *  See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4
+     *  for more on "hinting".
+     *
+     *  Insertion requires logarithmic time (if the hint is not taken).
+    */
+    iterator
+    insert(iterator __position, const value_type& __x)
+      { return _M_t.insert_equal(__position, __x); }
+  
+    /**
+     *  @brief A template function that attemps to insert a range of elements.
+     *  @param  first  Iterator pointing to the start of the range to be
+     *                 inserted.
+     *  @param  last  Iterator pointing to the end of the range.
+     *
+     *  Complexity similar to that of the range constructor.
+    */
+    template <typename _InputIterator>
+      void
+      insert(_InputIterator __first, _InputIterator __last)
+        { _M_t.insert_equal(__first, __last); }
+  
+    /**
+     *  @brief Erases an element from a %multimap.
+     *  @param  position  An iterator pointing to the element to be erased.
+     *
+     *  This function erases an element, pointed to by the given iterator, from
+     *  a %multimap.  Note that this function only erases the element, and that
+     *  if the element is itself a pointer, the pointed-to memory is not
+     *  touched in any way.  Managing the pointer is the user's responsibilty.
+    */
     void
-    insert(_InputIterator __first, _InputIterator __last)
-      { _M_t.insert_equal(__first, __last); }
-
-  /**
-   *  @brief Erases an element from a %multimap.
-   *  @param  position  An iterator pointing to the element to be erased.
-   *
-   *  This function erases an element, pointed to by the given iterator, from
-   *  a %multimap.  Note that this function only erases the element, and that
-   *  if the element is itself a pointer, the pointed-to memory is not
-   *  touched in any way.  Managing the pointer is the user's responsibilty.
-  */
-  void
-  erase(iterator __position) { _M_t.erase(__position); }
-
-  /**
-   *  @brief Erases elements according to the provided key.
-   *  @param  x  Key of element to be erased.
-   *  @return  The number of elements erased.
-   *
-   *  This function erases all elements located by the given key from a
-   *  %multimap.
-   *  Note that this function only erases the element, and that if
-   *  the element is itself a pointer, the pointed-to memory is not touched
-   *  in any way.  Managing the pointer is the user's responsibilty.
-  */
-  size_type
-  erase(const key_type& __x) { return _M_t.erase(__x); }
-
-  /**
-   *  @brief Erases a [first,last) range of elements from a %multimap.
-   *  @param  first  Iterator pointing to the start of the range to be erased.
-   *  @param  last  Iterator pointing to the end of the range to be erased.
-   *
-   *  This function erases a sequence of elements from a %multimap.
-   *  Note that this function only erases the elements, and that if
-   *  the elements themselves are pointers, the pointed-to memory is not
-   *  touched in any way.  Managing the pointer is the user's responsibilty.
-  */
-  void
-  erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); }
-
-  /**
-   *  @brief  Swaps data with another %multimap.
-   *  @param  x  A %multimap of the same element and allocator types.
-   *
-   *  This exchanges the elements between two multimaps in constant time.
-   *  (It is only swapping a pointer, an integer, and an instance of
-   *  the @c Compare type (which itself is often stateless and empty), so it
-   *  should be quite fast.)
-   *  Note that the global std::swap() function is specialized such that
-   *  std::swap(m1,m2) will feed to this function.
-  */
-  void
-  swap(multimap& __x) { _M_t.swap(__x._M_t); }
-
-  /**
-   *  Erases all elements in a %multimap.  Note that this function only erases
-   *  the elements, and that if the elements themselves are pointers, the
-   *  pointed-to memory is not touched in any way.  Managing the pointer is
-   *  the user's responsibilty.
-  */
-  void
-  clear() { _M_t.clear(); }
-
-  // observers
-  /**
-   *  Returns the key comparison object out of which the %multimap
-   *  was constructed.
-  */
-  key_compare
-  key_comp() const { return _M_t.key_comp(); }
-
-  /**
-   *  Returns a value comparison object, built from the key comparison
-   *  object out of which the %multimap was constructed.
-  */
-  value_compare
-  value_comp() const { return value_compare(_M_t.key_comp()); }
-
-  // multimap operations
-  /**
-   *  @brief Tries to locate an element in a %multimap.
-   *  @param  x  Key of (key, value) pair to be located.
-   *  @return  Iterator pointing to sought-after element,
-   *           or end() if not found.
-   *
-   *  This function takes a key and tries to locate the element with which
-   *  the key matches.  If successful the function returns an iterator
-   *  pointing to the sought after %pair.  If unsuccessful it returns the
-   *  past-the-end ( @c end() ) iterator.
-  */
-  iterator
-  find(const key_type& __x) { return _M_t.find(__x); }
-
-  /**
-   *  @brief Tries to locate an element in a %multimap.
-   *  @param  x  Key of (key, value) pair to be located.
-   *  @return  Read-only (constant) iterator pointing to sought-after
-   *           element, or end() if not found.
-   *
-   *  This function takes a key and tries to locate the element with which
-   *  the key matches.  If successful the function returns a constant iterator
-   *  pointing to the sought after %pair.  If unsuccessful it returns the
-   *  past-the-end ( @c end() ) iterator.
-  */
-  const_iterator
-  find(const key_type& __x) const { return _M_t.find(__x); }
-
-  /**
-   *  @brief Finds the number of elements with given key.
-   *  @param  x  Key of (key, value) pairs to be located.
-   *  @return Number of elements with specified key.
-  */
-  size_type
-  count(const key_type& __x) const { return _M_t.count(__x); }
-
+    erase(iterator __position) { _M_t.erase(__position); }
+  
+    /**
+     *  @brief Erases elements according to the provided key.
+     *  @param  x  Key of element to be erased.
+     *  @return  The number of elements erased.
+     *
+     *  This function erases all elements located by the given key from a
+     *  %multimap.
+     *  Note that this function only erases the element, and that if
+     *  the element is itself a pointer, the pointed-to memory is not touched
+     *  in any way.  Managing the pointer is the user's responsibilty.
+    */
+    size_type
+    erase(const key_type& __x) { return _M_t.erase(__x); }
+  
+    /**
+     *  @brief Erases a [first,last) range of elements from a %multimap.
+     *  @param  first  Iterator pointing to the start of the range to be erased.
+     *  @param  last  Iterator pointing to the end of the range to be erased.
+     *
+     *  This function erases a sequence of elements from a %multimap.
+     *  Note that this function only erases the elements, and that if
+     *  the elements themselves are pointers, the pointed-to memory is not
+     *  touched in any way.  Managing the pointer is the user's responsibilty.
+    */
+    void
+    erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); }
+  
+    /**
+     *  @brief  Swaps data with another %multimap.
+     *  @param  x  A %multimap of the same element and allocator types.
+     *
+     *  This exchanges the elements between two multimaps in constant time.
+     *  (It is only swapping a pointer, an integer, and an instance of
+     *  the @c Compare type (which itself is often stateless and empty), so it
+     *  should be quite fast.)
+     *  Note that the global std::swap() function is specialized such that
+     *  std::swap(m1,m2) will feed to this function.
+    */
+    void
+    swap(multimap& __x) { _M_t.swap(__x._M_t); }
+  
+    /**
+     *  Erases all elements in a %multimap.  Note that this function only erases
+     *  the elements, and that if the elements themselves are pointers, the
+     *  pointed-to memory is not touched in any way.  Managing the pointer is
+     *  the user's responsibilty.
+    */
+    void
+    clear() { _M_t.clear(); }
+  
+    // observers
+    /**
+     *  Returns the key comparison object out of which the %multimap
+     *  was constructed.
+    */
+    key_compare
+    key_comp() const { return _M_t.key_comp(); }
+  
+    /**
+     *  Returns a value comparison object, built from the key comparison
+     *  object out of which the %multimap was constructed.
+    */
+    value_compare
+    value_comp() const { return value_compare(_M_t.key_comp()); }
+  
+    // multimap operations
+    /**
+     *  @brief Tries to locate an element in a %multimap.
+     *  @param  x  Key of (key, value) pair to be located.
+     *  @return  Iterator pointing to sought-after element,
+     *           or end() if not found.
+     *
+     *  This function takes a key and tries to locate the element with which
+     *  the key matches.  If successful the function returns an iterator
+     *  pointing to the sought after %pair.  If unsuccessful it returns the
+     *  past-the-end ( @c end() ) iterator.
+    */
+    iterator
+    find(const key_type& __x) { return _M_t.find(__x); }
+  
+    /**
+     *  @brief Tries to locate an element in a %multimap.
+     *  @param  x  Key of (key, value) pair to be located.
+     *  @return  Read-only (constant) iterator pointing to sought-after
+     *           element, or end() if not found.
+     *
+     *  This function takes a key and tries to locate the element with which
+     *  the key matches.  If successful the function returns a constant iterator
+     *  pointing to the sought after %pair.  If unsuccessful it returns the
+     *  past-the-end ( @c end() ) iterator.
+    */
+    const_iterator
+    find(const key_type& __x) const { return _M_t.find(__x); }
+  
+    /**
+     *  @brief Finds the number of elements with given key.
+     *  @param  x  Key of (key, value) pairs to be located.
+     *  @return Number of elements with specified key.
+    */
+    size_type
+    count(const key_type& __x) const { return _M_t.count(__x); }
+  
+    /**
+     *  @brief Finds the beginning of a subsequence matching given key.
+     *  @param  x  Key of (key, value) pair to be located.
+     *  @return  Iterator pointing to first element matching given key, or
+     *           end() if not found.
+     *
+     *  This function returns the first element of a subsequence of elements
+     *  that matches the given key.  If unsuccessful it returns an iterator
+     *  pointing to the first element that has a greater value than given key
+     *  or end() if no such element exists.
+    */
+    iterator
+    lower_bound(const key_type& __x) { return _M_t.lower_bound(__x); }
+  
+    /**
+     *  @brief Finds the beginning of a subsequence matching given key.
+     *  @param  x  Key of (key, value) pair to be located.
+     *  @return  Read-only (constant) iterator pointing to first element
+     *           matching given key, or end() if not found.
+     *
+     *  This function returns the first element of a subsequence of elements
+     *  that matches the given key.  If unsuccessful the iterator will point
+     *  to the next greatest element or, if no such greater element exists, to
+     *  end().
+    */
+    const_iterator
+    lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); }
+  
+    /**
+     *  @brief Finds the end of a subsequence matching given key.
+     *  @param  x  Key of (key, value) pair to be located.
+     *  @return Iterator pointing to last element matching given key.
+    */
+    iterator
+    upper_bound(const key_type& __x) { return _M_t.upper_bound(__x); }
+  
+    /**
+     *  @brief Finds the end of a subsequence matching given key.
+     *  @param  x  Key of (key, value) pair to be located.
+     *  @return  Read-only (constant) iterator pointing to last element matching
+     *           given key.
+    */
+    const_iterator
+    upper_bound(const key_type& __x) const { return _M_t.upper_bound(__x); }
+  
+    /**
+     *  @brief Finds a subsequence matching given key.
+     *  @param  x  Key of (key, value) pairs to be located.
+     *  @return  Pair of iterators that possibly points to the subsequence
+     *           matching given key.
+     *
+     *  This function returns a pair of which the first
+     *  element possibly points to the first element matching the given key
+     *  and the second element possibly points to the last element matching the
+     *  given key.  If unsuccessful the first element of the returned pair will
+     *  contain an iterator pointing to the next greatest element or, if no such
+     *  greater element exists, to end().
+    */
+    pair<iterator,iterator>
+    equal_range(const key_type& __x) { return _M_t.equal_range(__x); }
+  
+    /**
+     *  @brief Finds a subsequence matching given key.
+     *  @param  x  Key of (key, value) pairs to be located.
+     *  @return  Pair of read-only (constant) iterators that possibly points to
+     *           the subsequence matching given key.
+     *
+     *  This function returns a pair of which the first
+     *  element possibly points to the first element matching the given key
+     *  and the second element possibly points to the last element matching the
+     *  given key.  If unsuccessful the first element of the returned pair will
+     *  contain an iterator pointing to the next greatest element or, if no such
+     *  a greater element exists, to end().
+    */
+    pair<const_iterator,const_iterator>
+    equal_range(const key_type& __x) const { return _M_t.equal_range(__x); }
+  
+    template <typename _K1, typename _T1, typename _C1, typename _A1>
+    friend bool operator== (const multimap<_K1,_T1,_C1,_A1>&,
+                            const multimap<_K1,_T1,_C1,_A1>&);
+    template <typename _K1, typename _T1, typename _C1, typename _A1>
+    friend bool operator< (const multimap<_K1,_T1,_C1,_A1>&,
+                           const multimap<_K1,_T1,_C1,_A1>&);
+  };
+  
+  
   /**
-   *  @brief Finds the beginning of a subsequence matching given key.
-   *  @param  x  Key of (key, value) pair to be located.
-   *  @return  Iterator pointing to first element matching given key, or
-   *           end() if not found.
+   *  @brief  Multimap equality comparison.
+   *  @param  x  A %multimap.
+   *  @param  y  A %multimap of the same type as @a x.
+   *  @return  True iff the size and elements of the maps are equal.
    *
-   *  This function returns the first element of a subsequence of elements
-   *  that matches the given key.  If unsuccessful it returns an iterator
-   *  pointing to the first element that has a greater value than given key
-   *  or end() if no such element exists.
-  */
-  iterator
-  lower_bound(const key_type& __x) { return _M_t.lower_bound(__x); }
-
-  /**
-   *  @brief Finds the beginning of a subsequence matching given key.
-   *  @param  x  Key of (key, value) pair to be located.
-   *  @return  Read-only (constant) iterator pointing to first element
-   *           matching given key, or end() if not found.
+   *  This is an equivalence relation.  It is linear in the size of the
+   *  multimaps.  Multimaps are considered equivalent if their sizes are equal,
+   *  and if corresponding elements compare equal.
+  */
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+    inline bool
+    operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+               const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
+    {
+      return __x._M_t == __y._M_t;
+    }
+  
+  /**
+   *  @brief  Multimap ordering relation.
+   *  @param  x  A %multimap.
+   *  @param  y  A %multimap of the same type as @a x.
+   *  @return  True iff @a x is lexographically less than @a y.
    *
-   *  This function returns the first element of a subsequence of elements
-   *  that matches the given key.  If unsuccessful the iterator will point
-   *  to the next greatest element or, if no such greater element exists, to
-   *  end().
-  */
-  const_iterator
-  lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); }
-
-  /**
-   *  @brief Finds the end of a subsequence matching given key.
-   *  @param  x  Key of (key, value) pair to be located.
-   *  @return Iterator pointing to last element matching given key.
-  */
-  iterator
-  upper_bound(const key_type& __x) { return _M_t.upper_bound(__x); }
-
-  /**
-   *  @brief Finds the end of a subsequence matching given key.
-   *  @param  x  Key of (key, value) pair to be located.
-   *  @return  Read-only (constant) iterator pointing to last element matching
-   *           given key.
-  */
-  const_iterator
-  upper_bound(const key_type& __x) const { return _M_t.upper_bound(__x); }
-
-  /**
-   *  @brief Finds a subsequence matching given key.
-   *  @param  x  Key of (key, value) pairs to be located.
-   *  @return  Pair of iterators that possibly points to the subsequence
-   *           matching given key.
+   *  This is a total ordering relation.  It is linear in the size of the
+   *  multimaps.  The elements must be comparable with @c <.
    *
-   *  This function returns a pair of which the first
-   *  element possibly points to the first element matching the given key
-   *  and the second element possibly points to the last element matching the
-   *  given key.  If unsuccessful the first element of the returned pair will
-   *  contain an iterator pointing to the next greatest element or, if no such
-   *  greater element exists, to end().
-  */
-  pair<iterator,iterator>
-  equal_range(const key_type& __x) { return _M_t.equal_range(__x); }
-
-  /**
-   *  @brief Finds a subsequence matching given key.
-   *  @param  x  Key of (key, value) pairs to be located.
-   *  @return  Pair of read-only (constant) iterators that possibly points to
-   *           the subsequence matching given key.
-   *
-   *  This function returns a pair of which the first
-   *  element possibly points to the first element matching the given key
-   *  and the second element possibly points to the last element matching the
-   *  given key.  If unsuccessful the first element of the returned pair will
-   *  contain an iterator pointing to the next greatest element or, if no such
-   *  a greater element exists, to end().
-  */
-  pair<const_iterator,const_iterator>
-  equal_range(const key_type& __x) const { return _M_t.equal_range(__x); }
-
-  template <typename _K1, typename _T1, typename _C1, typename _A1>
-  friend bool operator== (const multimap<_K1,_T1,_C1,_A1>&,
-                          const multimap<_K1,_T1,_C1,_A1>&);
-  template <typename _K1, typename _T1, typename _C1, typename _A1>
-  friend bool operator< (const multimap<_K1,_T1,_C1,_A1>&,
-                         const multimap<_K1,_T1,_C1,_A1>&);
-};
-
-
-/**
- *  @brief  Multimap equality comparison.
- *  @param  x  A %multimap.
- *  @param  y  A %multimap of the same type as @a x.
- *  @return  True iff the size and elements of the maps are equal.
- *
- *  This is an equivalence relation.  It is linear in the size of the
- *  multimaps.  Multimaps are considered equivalent if their sizes are equal,
- *  and if corresponding elements compare equal.
-*/
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-  inline bool
-  operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
-             const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
-  {
-    return __x._M_t == __y._M_t;
-  }
-
-/**
- *  @brief  Multimap ordering relation.
- *  @param  x  A %multimap.
- *  @param  y  A %multimap of the same type as @a x.
- *  @return  True iff @a x is lexographically less than @a y.
- *
- *  This is a total ordering relation.  It is linear in the size of the
- *  multimaps.  The elements must be comparable with @c <.
- *
- *  See std::lexographical_compare() for how the determination is made.
-*/
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-  inline bool
-  operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
-            const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
-  { return __x._M_t < __y._M_t; }
-
-/// Based on operator==
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-  inline bool
-  operator!=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
-             const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
-  { return !(__x == __y); }
-
-/// Based on operator<
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-  inline bool
-  operator>(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
-            const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
-  { return __y < __x; }
-
-/// Based on operator<
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-  inline bool
-  operator<=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
-             const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
-  { return !(__y < __x); }
-
-/// Based on operator<
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-  inline bool
-  operator>=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
-             const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
-  { return !(__x < __y); }
-
-/// See std::multimap::swap().
-template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
-  inline void
-  swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x,
-       multimap<_Key,_Tp,_Compare,_Alloc>& __y)
-  { __x.swap(__y); }
-
+   *  See std::lexographical_compare() for how the determination is made.
+  */
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+    inline bool
+    operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+              const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
+    { return __x._M_t < __y._M_t; }
+  
+  /// Based on operator==
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+    inline bool
+    operator!=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+               const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
+    { return !(__x == __y); }
+  
+  /// Based on operator<
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+    inline bool
+    operator>(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+              const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
+    { return __y < __x; }
+  
+  /// Based on operator<
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+    inline bool
+    operator<=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+               const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
+    { return !(__y < __x); }
+  
+  /// Based on operator<
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+    inline bool
+    operator>=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+               const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
+    { return !(__x < __y); }
+  
+  /// See std::multimap::swap().
+  template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
+    inline void
+    swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x,
+         multimap<_Key,_Tp,_Compare,_Alloc>& __y)
+    { __x.swap(__y); }
 } // namespace std
 
 #endif /* __GLIBCPP_INTERNAL_MULTIMAP_H */
-
index f8a2714..ff2ba26 100644 (file)
 
 #include <bits/concept_check.h>
 
-// Since this entire file is within namespace std, there's no reason to
-// waste two spaces along the left column.  Thus the leading indentation is
-// slightly violated from here on.
 namespace std
 {
-
-// Forward declarations of operators < and ==, needed for friend declaration.
-
-template <typename _Tp, typename _Sequence = deque<_Tp> >
-class queue;
-
-template <typename _Tp, typename _Seq>
-inline bool operator==(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&);
-
-template <typename _Tp, typename _Seq>
-inline bool operator<(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&);
-
-
-/**
- *  @brief  A standard container giving FIFO behavior.
- *
- *  @ingroup Containers
- *  @ingroup Sequences
- *
- *  Meets many of the requirements of a <a href="tables.html#65">container</a>,
- *  but does not define anything to do with iterators.  Very few of the
- *  other standard container interfaces are defined.
- *
- *  This is not a true container, but an @e adaptor.  It holds another
- *  container, and provides a wrapper interface to that container.  The
- *  wrapper is what enforces strict first-in-first-out %queue behavior.
- *
- *  The second template parameter defines the type of the underlying
- *  sequence/container.  It defaults to std::deque, but it can be any type
- *  that supports @c front, @c back, @c push_back, and @c pop_front,
- *  such as std::list or an appropriate user-defined type.
- *
- *  Members not found in "normal" containers are @c container_type,
- *  which is a typedef for the second Sequence parameter, and @c push and
- *  @c pop, which are standard %queue/FIFO operations.
-*/
-template <typename _Tp, typename _Sequence>
-  class queue
-{
-  // concept requirements
-  typedef typename _Sequence::value_type _Sequence_value_type;
-  __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
-  __glibcpp_class_requires(_Sequence, _FrontInsertionSequenceConcept)
-  __glibcpp_class_requires(_Sequence, _BackInsertionSequenceConcept)
-  __glibcpp_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
-
-  template <typename _Tp1, typename _Seq1>
-  friend bool operator== (const queue<_Tp1, _Seq1>&,
-                          const queue<_Tp1, _Seq1>&);
-  template <typename _Tp1, typename _Seq1>
-  friend bool operator< (const queue<_Tp1, _Seq1>&,
-                         const queue<_Tp1, _Seq1>&);
-
-public:
-  typedef typename _Sequence::value_type                value_type;
-  typedef typename _Sequence::reference                 reference;
-  typedef typename _Sequence::const_reference           const_reference;
-  typedef typename _Sequence::size_type                 size_type;
-  typedef          _Sequence                            container_type;
-
-protected:
-  /**
-   *  'c' is the underlying container.  Maintainers wondering why this isn't
-   *  uglified as per style guidelines should note that this name is
-   *  specified in the standard, [23.2.3.1].  (Why?  Presumably for the same
-   *  reason that it's protected instead of private:  to allow derivation.
-   *  But none of the other containers allow for derivation.  Odd.)
-  */
-  _Sequence c;
-
-public:
-  /**
-   *  @brief  Default constructor creates no elements.
-  */
-  explicit
-  queue(const _Sequence& __c = _Sequence())
-  : c(__c) {}
-
-  /**
-   *  Returns true if the %queue is empty.
-  */
-  bool
-  empty() const { return c.empty(); }
-
-  /**  Returns the number of elements in the %queue.  */
-  size_type
-  size() const { return c.size(); }
-
-  /**
-   *  Returns a read/write reference to the data at the first element of the
-   *  %queue.
-  */
-  reference
-  front() { return c.front(); }
-
-  /**
-   *  Returns a read-only (constant) reference to the data at the first
-   *  element of the %queue.
-  */
-  const_reference
-  front() const { return c.front(); }
-
-  /**
-   *  Returns a read/write reference to the data at the last element of the
-   *  %queue.
-  */
-  reference
-  back() { return c.back(); }
-
+  // Forward declarations of operators < and ==, needed for friend declaration.
+  
+  template <typename _Tp, typename _Sequence = deque<_Tp> >
+  class queue;
+  
+  template <typename _Tp, typename _Seq>
+  inline bool operator==(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&);
+  
+  template <typename _Tp, typename _Seq>
+  inline bool operator<(const queue<_Tp,_Seq>&, const queue<_Tp,_Seq>&);
+  
+  
   /**
-   *  Returns a read-only (constant) reference to the data at the last
-   *  element of the %queue.
-  */
-  const_reference
-  back() const { return c.back(); }
-
-  /**
-   *  @brief  Add data to the end of the %queue.
-   *  @param  x  Data to be added.
+   *  @brief  A standard container giving FIFO behavior.
    *
-   *  This is a typical %queue operation.  The function creates an element at
-   *  the end of the %queue and assigns the given data to it.
-   *  The time complexity of the operation depends on the underlying
-   *  sequence.
-  */
-  void
-  push(const value_type& __x) { c.push_back(__x); }
-
-  /**
-   *  @brief  Removes first element.
+   *  @ingroup Containers
+   *  @ingroup Sequences
    *
-   *  This is a typical %queue operation.  It shrinks the %queue by one.
-   *  The time complexity of the operation depends on the underlying
-   *  sequence.
+   *  Meets many of the requirements of a
+   *  <a href="tables.html#65">container</a>,
+   *  but does not define anything to do with iterators.  Very few of the
+   *  other standard container interfaces are defined.
    *
-   *  Note that no data is returned, and if the first element's data is
-   *  needed, it should be retrieved before pop() is called.
-  */
-  void
-  pop() { c.pop_front(); }
-};
-
-
-/**
- *  @brief  Queue equality comparison.
- *  @param  x  A %queue.
- *  @param  y  A %queue of the same type as @a x.
- *  @return  True iff the size and elements of the queues are equal.
- *
- *  This is an equivalence relation.  Complexity and semantics depend on the
- *  underlying sequence type, but the expected rules are:  this relation is
- *  linear in the size of the sequences, and queues are considered equivalent
- *  if their sequences compare equal.
-*/
-template <typename _Tp, typename _Sequence>
-  inline bool 
-  operator==(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
-  { return __x.c == __y.c; }
-
-/**
- *  @brief  Queue ordering relation.
- *  @param  x  A %queue.
- *  @param  y  A %queue of the same type as @a x.
- *  @return  True iff @a x is lexographically less than @a y.
- *
- *  This is an total ordering relation.  Complexity and semantics depend on the
- *  underlying sequence type, but the expected rules are:  this relation is
- *  linear in the size of the sequences, the elements must be comparable
- *  with @c <, and std::lexographical_compare() is usually used to make the
- *  determination.
-*/
-template <typename _Tp, typename _Sequence>
-  inline bool
-  operator<(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
-  { return __x.c < __y.c; }
-
-/// Based on operator==
-template <typename _Tp, typename _Sequence>
-  inline bool
-  operator!=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
-  { return !(__x == __y); }
-
-/// Based on operator<
-template <typename _Tp, typename _Sequence>
-  inline bool 
-  operator>(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
-  { return __y < __x; }
-
-/// Based on operator<
-template <typename _Tp, typename _Sequence>
-  inline bool 
-  operator<=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
-  { return !(__y < __x); }
-
-/// Based on operator<
-template <typename _Tp, typename _Sequence>
-  inline bool 
-  operator>=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
-  { return !(__x < __y); }
-
-
-/**
- *  @brief  A standard container automatically sorting its contents.
- *
- *  @ingroup Containers
- *  @ingroup Sequences
- *
- *  This is not a true container, but an @e adaptor.  It holds another
- *  container, and provides a wrapper interface to that container.  The
- *  wrapper is what enforces sorting and first-in-first-out %queue behavior.
- *  Very few of the standard container/sequence interface requirements are
- *  met (e.g., iterators).
- *
- *  The second template parameter defines the type of the underlying
- *  sequence/container.  It defaults to std::vector, but it can be any type
- *  that supports @c front(), @c push_back, @c pop_back, and random-access
- *  iterators, such as std::deque or an appropriate user-defined type.
- *
- *  The third template parameter supplies the means of making priority
- *  comparisons.  It defaults to @c less<value_type> but can be anything
- *  defining a strict weak ordering.
- *
- *  Members not found in "normal" containers are @c container_type,
- *  which is a typedef for the second Sequence parameter, and @c push,
- *  @c pop, and @c top, which are standard %queue/FIFO operations.
- *
- *  @note  No equality/comparison operators are provided for %priority_queue.
- *
- *  @note  Sorting of the elements takes place as they are added to, and
- *         removed from, the %priority_queue using the %priority_queue's
- *         member functions.  If you access the elements by other means, and
- *         change their data such that the sorting order would be different,
- *         the %priority_queue will not re-sort the elements for you.  (How
- *         could it know to do so?)
-*/
-template <typename _Tp, typename _Sequence = vector<_Tp>,
-          typename _Compare  = less<typename _Sequence::value_type> >
-  class priority_queue
-{
-  // concept requirements
-  typedef typename _Sequence::value_type _Sequence_value_type;
-  __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
-  __glibcpp_class_requires(_Sequence, _SequenceConcept)
-  __glibcpp_class_requires(_Sequence, _RandomAccessContainerConcept)
-  __glibcpp_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
-  __glibcpp_class_requires4(_Compare, bool, _Tp, _Tp, _BinaryFunctionConcept)
-
-public:
-  typedef typename _Sequence::value_type                value_type;
-  typedef typename _Sequence::reference                 reference;
-  typedef typename _Sequence::const_reference           const_reference;
-  typedef typename _Sequence::size_type                 size_type;
-  typedef          _Sequence                            container_type;
-
-protected:
-  //  See queue::c for notes on these names.
-  _Sequence  c;
-  _Compare   comp;
-
-public:
-  /**
-   *  @brief  Default constructor creates no elements.
-  */
-  explicit
-  priority_queue(const _Compare& __x = _Compare(),
-                 const _Sequence& __s = _Sequence()) 
-  : c(__s), comp(__x) 
-  { make_heap(c.begin(), c.end(), comp); }
-
-  /**
-   *  @brief  Builds a %queue from a range.
-   *  @param  first  An input iterator.
-   *  @param  last  An input iterator.
-   *  @param  x  A comparison functor describing a strict weak ordering.
-   *  @param  s  An initial sequence with which to start.
-   * 
-   *  Begins by copying @a s, inserting a copy of the elements from
-   *  @a [first,last) into the copy of @a s, then ordering the copy
-   *  according to @a x.
+   *  This is not a true container, but an @e adaptor.  It holds another
+   *  container, and provides a wrapper interface to that container.  The
+   *  wrapper is what enforces strict first-in-first-out %queue behavior.
    *
-   *  For more information on function objects, see the documentation on
-   *  @link s20_3_1_base functor base classes@endlink.
-  */
-  template <typename _InputIterator>
-    priority_queue(_InputIterator __first, _InputIterator __last,
-                   const _Compare& __x = _Compare(),
-                   const _Sequence& __s = _Sequence())
-    : c(__s), comp(__x)
-    { 
-      c.insert(c.end(), __first, __last);
-      make_heap(c.begin(), c.end(), comp);
-    }
-
-  /**
-   *  Returns true if the %queue is empty.
+   *  The second template parameter defines the type of the underlying
+   *  sequence/container.  It defaults to std::deque, but it can be any type
+   *  that supports @c front, @c back, @c push_back, and @c pop_front,
+   *  such as std::list or an appropriate user-defined type.
+   *
+   *  Members not found in "normal" containers are @c container_type,
+   *  which is a typedef for the second Sequence parameter, and @c push and
+   *  @c pop, which are standard %queue/FIFO operations.
   */
-  bool
-  empty() const { return c.empty(); }
-
-  /**  Returns the number of elements in the %queue.  */
-  size_type
-  size() const { return c.size(); }
-
+  template <typename _Tp, typename _Sequence>
+    class queue
+  {
+    // concept requirements
+    typedef typename _Sequence::value_type _Sequence_value_type;
+    __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+    __glibcpp_class_requires(_Sequence, _FrontInsertionSequenceConcept)
+    __glibcpp_class_requires(_Sequence, _BackInsertionSequenceConcept)
+    __glibcpp_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
+  
+    template <typename _Tp1, typename _Seq1>
+    friend bool operator== (const queue<_Tp1, _Seq1>&,
+                            const queue<_Tp1, _Seq1>&);
+    template <typename _Tp1, typename _Seq1>
+    friend bool operator< (const queue<_Tp1, _Seq1>&,
+                           const queue<_Tp1, _Seq1>&);
+  
+  public:
+    typedef typename _Sequence::value_type                value_type;
+    typedef typename _Sequence::reference                 reference;
+    typedef typename _Sequence::const_reference           const_reference;
+    typedef typename _Sequence::size_type                 size_type;
+    typedef          _Sequence                            container_type;
+  
+  protected:
+    /**
+     *  'c' is the underlying container.  Maintainers wondering why this isn't
+     *  uglified as per style guidelines should note that this name is
+     *  specified in the standard, [23.2.3.1].  (Why?  Presumably for the same
+     *  reason that it's protected instead of private:  to allow derivation.
+     *  But none of the other containers allow for derivation.  Odd.)
+    */
+    _Sequence c;
+  
+  public:
+    /**
+     *  @brief  Default constructor creates no elements.
+    */
+    explicit
+    queue(const _Sequence& __c = _Sequence())
+    : c(__c) {}
+  
+    /**
+     *  Returns true if the %queue is empty.
+    */
+    bool
+    empty() const { return c.empty(); }
+  
+    /**  Returns the number of elements in the %queue.  */
+    size_type
+    size() const { return c.size(); }
+  
+    /**
+     *  Returns a read/write reference to the data at the first element of the
+     *  %queue.
+    */
+    reference
+    front() { return c.front(); }
+  
+    /**
+     *  Returns a read-only (constant) reference to the data at the first
+     *  element of the %queue.
+    */
+    const_reference
+    front() const { return c.front(); }
+  
+    /**
+     *  Returns a read/write reference to the data at the last element of the
+     *  %queue.
+    */
+    reference
+    back() { return c.back(); }
+  
+    /**
+     *  Returns a read-only (constant) reference to the data at the last
+     *  element of the %queue.
+    */
+    const_reference
+    back() const { return c.back(); }
+  
+    /**
+     *  @brief  Add data to the end of the %queue.
+     *  @param  x  Data to be added.
+     *
+     *  This is a typical %queue operation.  The function creates an element at
+     *  the end of the %queue and assigns the given data to it.
+     *  The time complexity of the operation depends on the underlying
+     *  sequence.
+    */
+    void
+    push(const value_type& __x) { c.push_back(__x); }
+  
+    /**
+     *  @brief  Removes first element.
+     *
+     *  This is a typical %queue operation.  It shrinks the %queue by one.
+     *  The time complexity of the operation depends on the underlying
+     *  sequence.
+     *
+     *  Note that no data is returned, and if the first element's data is
+     *  needed, it should be retrieved before pop() is called.
+    */
+    void
+    pop() { c.pop_front(); }
+  };
+  
+  
   /**
-   *  Returns a read-only (constant) reference to the data at the first
-   *  element of the %queue.
+   *  @brief  Queue equality comparison.
+   *  @param  x  A %queue.
+   *  @param  y  A %queue of the same type as @a x.
+   *  @return  True iff the size and elements of the queues are equal.
+   *
+   *  This is an equivalence relation.  Complexity and semantics depend on the
+   *  underlying sequence type, but the expected rules are:  this relation is
+   *  linear in the size of the sequences, and queues are considered equivalent
+   *  if their sequences compare equal.
   */
-  const_reference
-  top() const { return c.front(); }
-
+  template <typename _Tp, typename _Sequence>
+    inline bool 
+    operator==(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y)
+    { return __x.c == __y.c; }
+  
   /**
-   *  @brief  Add data to the %queue.
-   *  @param  x  Data to be added.
+   *  @brief  Queue ordering relation.
+   *  @param  x  A %queue.
+   *  @param  y  A %queue of the same type as @a x.
+   *  @return  True iff @a x is lexographically less than @a y.
    *
-   *  This is a typical %queue operation.
-   *  The time complexity of the operation depends on the underlying
-   *  sequence.
+   *  This is an total ordering relation.  Complexity and semantics depend on
+   *  the underlying sequence type, but the expected rules are:  this relation
+   *  is linear in the size of the sequences, the elements must be comparable
+   *  with @c <, and std::lexographical_compare() is usually used to make the
+   *  determination.
   */
-  void 
-  push(const value_type& __x) 
-  {
-    try 
-      {
-        c.push_back(__x); 
-        push_heap(c.begin(), c.end(), comp);
-      }
-    catch(...)
-      {
-        c.clear();
-        __throw_exception_again; 
-      }
-  }
-
+  template <typename _Tp, typename _Sequence>
+    inline bool
+    operator<(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y)
+    { return __x.c < __y.c; }
+  
+  /// Based on operator==
+  template <typename _Tp, typename _Sequence>
+    inline bool
+    operator!=(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y)
+    { return !(__x == __y); }
+  
+  /// Based on operator<
+  template <typename _Tp, typename _Sequence>
+    inline bool 
+    operator>(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y)
+    { return __y < __x; }
+  
+  /// Based on operator<
+  template <typename _Tp, typename _Sequence>
+    inline bool 
+    operator<=(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y)
+    { return !(__y < __x); }
+  
+  /// Based on operator<
+  template <typename _Tp, typename _Sequence>
+    inline bool 
+    operator>=(const queue<_Tp,_Sequence>& __x, const queue<_Tp,_Sequence>& __y)
+    { return !(__x < __y); }
+  
+  
   /**
-   *  @brief  Removes first element.
+   *  @brief  A standard container automatically sorting its contents.
    *
-   *  This is a typical %queue operation.  It shrinks the %queue by one.
-   *  The time complexity of the operation depends on the underlying
-   *  sequence.
+   *  @ingroup Containers
+   *  @ingroup Sequences
    *
-   *  Note that no data is returned, and if the first element's data is
-   *  needed, it should be retrieved before pop() is called.
+   *  This is not a true container, but an @e adaptor.  It holds another
+   *  container, and provides a wrapper interface to that container.  The
+   *  wrapper is what enforces sorting and first-in-first-out %queue behavior.
+   *  Very few of the standard container/sequence interface requirements are
+   *  met (e.g., iterators).
+   *
+   *  The second template parameter defines the type of the underlying
+   *  sequence/container.  It defaults to std::vector, but it can be any type
+   *  that supports @c front(), @c push_back, @c pop_back, and random-access
+   *  iterators, such as std::deque or an appropriate user-defined type.
+   *
+   *  The third template parameter supplies the means of making priority
+   *  comparisons.  It defaults to @c less<value_type> but can be anything
+   *  defining a strict weak ordering.
+   *
+   *  Members not found in "normal" containers are @c container_type,
+   *  which is a typedef for the second Sequence parameter, and @c push,
+   *  @c pop, and @c top, which are standard %queue/FIFO operations.
+   *
+   *  @note  No equality/comparison operators are provided for %priority_queue.
+   *
+   *  @note  Sorting of the elements takes place as they are added to, and
+   *         removed from, the %priority_queue using the %priority_queue's
+   *         member functions.  If you access the elements by other means, and
+   *         change their data such that the sorting order would be different,
+   *         the %priority_queue will not re-sort the elements for you.  (How
+   *         could it know to do so?)
   */
-  void 
-  pop() 
+  template <typename _Tp, typename _Sequence = vector<_Tp>,
+            typename _Compare  = less<typename _Sequence::value_type> >
+    class priority_queue
   {
-    try 
-      {
-        pop_heap(c.begin(), c.end(), comp);
-        c.pop_back();
-      }
-    catch(...)
-      {
-        c.clear();
-        __throw_exception_again; 
+    // concept requirements
+    typedef typename _Sequence::value_type _Sequence_value_type;
+    __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+    __glibcpp_class_requires(_Sequence, _SequenceConcept)
+    __glibcpp_class_requires(_Sequence, _RandomAccessContainerConcept)
+    __glibcpp_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
+    __glibcpp_class_requires4(_Compare, bool, _Tp, _Tp, _BinaryFunctionConcept)
+  
+  public:
+    typedef typename _Sequence::value_type                value_type;
+    typedef typename _Sequence::reference                 reference;
+    typedef typename _Sequence::const_reference           const_reference;
+    typedef typename _Sequence::size_type                 size_type;
+    typedef          _Sequence                            container_type;
+  
+  protected:
+    //  See queue::c for notes on these names.
+    _Sequence  c;
+    _Compare   comp;
+  
+  public:
+    /**
+     *  @brief  Default constructor creates no elements.
+    */
+    explicit
+    priority_queue(const _Compare& __x = _Compare(),
+                   const _Sequence& __s = _Sequence()) 
+    : c(__s), comp(__x) 
+    { make_heap(c.begin(), c.end(), comp); }
+  
+    /**
+     *  @brief  Builds a %queue from a range.
+     *  @param  first  An input iterator.
+     *  @param  last  An input iterator.
+     *  @param  x  A comparison functor describing a strict weak ordering.
+     *  @param  s  An initial sequence with which to start.
+     * 
+     *  Begins by copying @a s, inserting a copy of the elements from
+     *  @a [first,last) into the copy of @a s, then ordering the copy
+     *  according to @a x.
+     *
+     *  For more information on function objects, see the documentation on
+     *  @link s20_3_1_base functor base classes@endlink.
+    */
+    template <typename _InputIterator>
+      priority_queue(_InputIterator __first, _InputIterator __last,
+                     const _Compare& __x = _Compare(),
+                     const _Sequence& __s = _Sequence())
+      : c(__s), comp(__x)
+      { 
+        c.insert(c.end(), __first, __last);
+        make_heap(c.begin(), c.end(), comp);
       }
-  }
-};
-
-// No equality/comparison operators are provided for priority_queue.
-
+  
+    /**
+     *  Returns true if the %queue is empty.
+    */
+    bool
+    empty() const { return c.empty(); }
+  
+    /**  Returns the number of elements in the %queue.  */
+    size_type
+    size() const { return c.size(); }
+  
+    /**
+     *  Returns a read-only (constant) reference to the data at the first
+     *  element of the %queue.
+    */
+    const_reference
+    top() const { return c.front(); }
+  
+    /**
+     *  @brief  Add data to the %queue.
+     *  @param  x  Data to be added.
+     *
+     *  This is a typical %queue operation.
+     *  The time complexity of the operation depends on the underlying
+     *  sequence.
+    */
+    void 
+    push(const value_type& __x) 
+    {
+      try 
+        {
+          c.push_back(__x); 
+          push_heap(c.begin(), c.end(), comp);
+        }
+      catch(...)
+        {
+          c.clear();
+          __throw_exception_again; 
+        }
+    }
+  
+    /**
+     *  @brief  Removes first element.
+     *
+     *  This is a typical %queue operation.  It shrinks the %queue by one.
+     *  The time complexity of the operation depends on the underlying
+     *  sequence.
+     *
+     *  Note that no data is returned, and if the first element's data is
+     *  needed, it should be retrieved before pop() is called.
+    */
+    void 
+    pop() 
+    {
+      try 
+        {
+          pop_heap(c.begin(), c.end(), comp);
+          c.pop_back();
+        }
+      catch(...)
+        {
+          c.clear();
+          __throw_exception_again; 
+        }
+    }
+  };
+  
+  // No equality/comparison operators are provided for priority_queue.
 } // namespace std
 
 #endif /* __GLIBCPP_INTERNAL_QUEUE_H */
-
index fb4af76..7f2496c 100644 (file)
 
 #include <bits/concept_check.h>
 
-// Since this entire file is within namespace std, there's no reason to
-// waste two spaces along the left column.  Thus the leading indentation is
-// slightly violated from here on.
 namespace std
 {
-
-// Forward declarations of operators == and <, needed for friend declaration.
-
-template <typename _Tp, typename _Sequence = deque<_Tp> >
-class stack;
-
-template <typename _Tp, typename _Seq>
-inline bool operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y);
-
-template <typename _Tp, typename _Seq>
-inline bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y);
-
-
-/**
- *  @brief  A standard container giving FILO behavior.
- *
- *  @ingroup Containers
- *  @ingroup Sequences
- *
- *  Meets many of the requirements of a <a href="tables.html#65">container</a>,
- *  but does not define anything to do with iterators.  Very few of the
- *  other standard container interfaces are defined.
- *
- *  This is not a true container, but an @e adaptor.  It holds another
- *  container, and provides a wrapper interface to that container.  The
- *  wrapper is what enforces strict first-in-last-out %stack behavior.
- *
- *  The second template parameter defines the type of the underlying
- *  sequence/container.  It defaults to std::deque, but it can be any type
- *  that supports @c back, @c push_back, and @c pop_front, such as
- *  std::list, std::vector, or an appropriate user-defined type.
- *
- *  Members not found in "normal" containers are @c container_type,
- *  which is a typedef for the second Sequence parameter, and @c push,
- *  @c pop, and @c top, which are standard %stack/FILO operations.
-*/
-template <typename _Tp, typename _Sequence>
-  class stack
-{
-  // concept requirements
-  typedef typename _Sequence::value_type _Sequence_value_type;
-  __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
-  __glibcpp_class_requires(_Sequence, _BackInsertionSequenceConcept)
-  __glibcpp_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
-
-  template <typename _Tp1, typename _Seq1>
-  friend bool operator== (const stack<_Tp1, _Seq1>&,
-                          const stack<_Tp1, _Seq1>&);
-  template <typename _Tp1, typename _Seq1>
-  friend bool operator< (const stack<_Tp1, _Seq1>&,
-                         const stack<_Tp1, _Seq1>&);
-
-public:
-  typedef typename _Sequence::value_type                value_type;
-  typedef typename _Sequence::reference                 reference;
-  typedef typename _Sequence::const_reference           const_reference;
-  typedef typename _Sequence::size_type                 size_type;
-  typedef          _Sequence                            container_type;
-
-protected:
-  //  See queue::c for notes on this name.
-  _Sequence c;
-
-public:
-  // XXX removed old def ctor, added def arg to this one to match 14882
-  /**
-   *  @brief  Default constructor creates no elements.
-  */
-  explicit
-  stack(const _Sequence& __c = _Sequence())
-  : c(__c) {}
-
-  /**
-   *  Returns true if the %stack is empty.
-  */
-  bool
-  empty() const { return c.empty(); }
-
-  /**  Returns the number of elements in the %stack.  */
-  size_type
-  size() const { return c.size(); }
-
+  // Forward declarations of operators == and <, needed for friend declaration.
+  
+  template <typename _Tp, typename _Sequence = deque<_Tp> >
+  class stack;
+  
+  template <typename _Tp, typename _Seq>
+  inline bool operator==(const stack<_Tp,_Seq>& __x,
+                        const stack<_Tp,_Seq>& __y);
+  
+  template <typename _Tp, typename _Seq>
+  inline bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y);
+  
+  
   /**
-   *  Returns a read/write reference to the data at the first element of the
-   *  %stack.
-  */
-  reference
-  top() { return c.back(); }
-
-  /**
-   *  Returns a read-only (constant) reference to the data at the first
-   *  element of the %stack.
+   *  @brief  A standard container giving FILO behavior.
+   *
+   *  @ingroup Containers
+   *  @ingroup Sequences
+   *
+   *  Meets many of the requirements of a
+   *  <a href="tables.html#65">container</a>,
+   *  but does not define anything to do with iterators.  Very few of the
+   *  other standard container interfaces are defined.
+   *
+   *  This is not a true container, but an @e adaptor.  It holds another
+   *  container, and provides a wrapper interface to that container.  The
+   *  wrapper is what enforces strict first-in-last-out %stack behavior.
+   *
+   *  The second template parameter defines the type of the underlying
+   *  sequence/container.  It defaults to std::deque, but it can be any type
+   *  that supports @c back, @c push_back, and @c pop_front, such as
+   *  std::list, std::vector, or an appropriate user-defined type.
+   *
+   *  Members not found in "normal" containers are @c container_type,
+   *  which is a typedef for the second Sequence parameter, and @c push,
+   *  @c pop, and @c top, which are standard %stack/FILO operations.
   */
-  const_reference
-  top() const { return c.back(); }
-
+  template <typename _Tp, typename _Sequence>
+    class stack
+  {
+    // concept requirements
+    typedef typename _Sequence::value_type _Sequence_value_type;
+    __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+    __glibcpp_class_requires(_Sequence, _BackInsertionSequenceConcept)
+    __glibcpp_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)
+  
+    template <typename _Tp1, typename _Seq1>
+    friend bool operator== (const stack<_Tp1, _Seq1>&,
+                            const stack<_Tp1, _Seq1>&);
+    template <typename _Tp1, typename _Seq1>
+    friend bool operator< (const stack<_Tp1, _Seq1>&,
+                           const stack<_Tp1, _Seq1>&);
+  
+  public:
+    typedef typename _Sequence::value_type                value_type;
+    typedef typename _Sequence::reference                 reference;
+    typedef typename _Sequence::const_reference           const_reference;
+    typedef typename _Sequence::size_type                 size_type;
+    typedef          _Sequence                            container_type;
+  
+  protected:
+    //  See queue::c for notes on this name.
+    _Sequence c;
+  
+  public:
+    // XXX removed old def ctor, added def arg to this one to match 14882
+    /**
+     *  @brief  Default constructor creates no elements.
+    */
+    explicit
+    stack(const _Sequence& __c = _Sequence())
+    : c(__c) {}
+  
+    /**
+     *  Returns true if the %stack is empty.
+    */
+    bool
+    empty() const { return c.empty(); }
+  
+    /**  Returns the number of elements in the %stack.  */
+    size_type
+    size() const { return c.size(); }
+  
+    /**
+     *  Returns a read/write reference to the data at the first element of the
+     *  %stack.
+    */
+    reference
+    top() { return c.back(); }
+  
+    /**
+     *  Returns a read-only (constant) reference to the data at the first
+     *  element of the %stack.
+    */
+    const_reference
+    top() const { return c.back(); }
+  
+    /**
+     *  @brief  Add data to the top of the %stack.
+     *  @param  x  Data to be added.
+     *
+     *  This is a typical %stack operation.  The function creates an element at
+     *  the top of the %stack and assigns the given data to it.
+     *  The time complexity of the operation depends on the underlying
+     *  sequence.
+    */
+    void
+    push(const value_type& __x) { c.push_back(__x); }
+  
+    /**
+     *  @brief  Removes first element.
+     *
+     *  This is a typical %stack operation.  It shrinks the %stack by one.
+     *  The time complexity of the operation depends on the underlying
+     *  sequence.
+     *
+     *  Note that no data is returned, and if the first element's data is
+     *  needed, it should be retrieved before pop() is called.
+    */
+    void
+    pop() { c.pop_back(); }
+  };
+  
+  
   /**
-   *  @brief  Add data to the top of the %stack.
-   *  @param  x  Data to be added.
+   *  @brief  Stack equality comparison.
+   *  @param  x  A %stack.
+   *  @param  y  A %stack of the same type as @a x.
+   *  @return  True iff the size and elements of the stacks are equal.
    *
-   *  This is a typical %stack operation.  The function creates an element at
-   *  the top of the %stack and assigns the given data to it.
-   *  The time complexity of the operation depends on the underlying
-   *  sequence.
+   *  This is an equivalence relation.  Complexity and semantics depend on the
+   *  underlying sequence type, but the expected rules are:  this relation is
+   *  linear in the size of the sequences, and stacks are considered equivalent
+   *  if their sequences compare equal.
   */
-  void
-  push(const value_type& __x) { c.push_back(__x); }
-
+  template <typename _Tp, typename _Seq>
+    inline bool
+    operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
+    { return __x.c == __y.c; }
+  
   /**
-   *  @brief  Removes first element.
-   *
-   *  This is a typical %stack operation.  It shrinks the %stack by one.
-   *  The time complexity of the operation depends on the underlying
-   *  sequence.
+   *  @brief  Stack ordering relation.
+   *  @param  x  A %stack.
+   *  @param  y  A %stack of the same type as @a x.
+   *  @return  True iff @a x is lexographically less than @a y.
    *
-   *  Note that no data is returned, and if the first element's data is
-   *  needed, it should be retrieved before pop() is called.
+   *  This is an total ordering relation.  Complexity and semantics depend on
+   *  the underlying sequence type, but the expected rules are:  this relation
+   *  is linear in the size of the sequences, the elements must be comparable
+   *  with @c <, and std::lexographical_compare() is usually used to make the
+   *  determination.
   */
-  void
-  pop() { c.pop_back(); }
-};
-
-
-/**
- *  @brief  Stack equality comparison.
- *  @param  x  A %stack.
- *  @param  y  A %stack of the same type as @a x.
- *  @return  True iff the size and elements of the stacks are equal.
- *
- *  This is an equivalence relation.  Complexity and semantics depend on the
- *  underlying sequence type, but the expected rules are:  this relation is
- *  linear in the size of the sequences, and stacks are considered equivalent
- *  if their sequences compare equal.
-*/
-template <typename _Tp, typename _Seq>
-  inline bool
-  operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
-  { return __x.c == __y.c; }
-
-/**
- *  @brief  Stack ordering relation.
- *  @param  x  A %stack.
- *  @param  y  A %stack of the same type as @a x.
- *  @return  True iff @a x is lexographically less than @a y.
- *
- *  This is an total ordering relation.  Complexity and semantics depend on the
- *  underlying sequence type, but the expected rules are:  this relation is
- *  linear in the size of the sequences, the elements must be comparable
- *  with @c <, and std::lexographical_compare() is usually used to make the
- *  determination.
-*/
-template <typename _Tp, typename _Seq>
-  inline bool
-  operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
-  { return __x.c < __y.c; }
-
-/// Based on operator==
-template <typename _Tp, typename _Seq>
-  inline bool
-  operator!=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
-  { return !(__x == __y); }
-
-/// Based on operator<
-template <typename _Tp, typename _Seq>
-  inline bool
-  operator>(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
-  { return __y < __x; }
-
-/// Based on operator<
-template <typename _Tp, typename _Seq>
-  inline bool
-  operator<=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
-  { return !(__y < __x); }
-
-/// Based on operator<
-template <typename _Tp, typename _Seq>
-  inline bool
-  operator>=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
-  { return !(__x < __y); }
-
+  template <typename _Tp, typename _Seq>
+    inline bool
+    operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
+    { return __x.c < __y.c; }
+  
+  /// Based on operator==
+  template <typename _Tp, typename _Seq>
+    inline bool
+    operator!=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
+    { return !(__x == __y); }
+  
+  /// Based on operator<
+  template <typename _Tp, typename _Seq>
+    inline bool
+    operator>(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
+    { return __y < __x; }
+  
+  /// Based on operator<
+  template <typename _Tp, typename _Seq>
+    inline bool
+    operator<=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
+    { return !(__y < __x); }
+  
+  /// Based on operator<
+  template <typename _Tp, typename _Seq>
+    inline bool
+    operator>=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y)
+    { return !(__x < __y); }
 } // namespace std
 
 #endif /* __GLIBCPP_INTERNAL_STACK_H */
-
index 5f82d5d..0e6a2ef 100644 (file)
 #include <bits/functexcept.h>
 #include <bits/concept_check.h>
 
-// Since this entire file is within namespace std, there's no reason to
-// waste two spaces along the left column.  Thus the leading indentation is
-// slightly violated from here on.
 namespace std
 {
-
-/// @if maint Primary default version.  @endif
-/**
- *  @if maint
- *  See bits/stl_deque.h's _Deque_alloc_base for an explanation.
- *  @endif
-*/
-template <typename _Tp, typename _Allocator, bool _IsStatic>
-  class _Vector_alloc_base
-{
-public:
-  typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
-          allocator_type;
-
-  allocator_type
-  get_allocator() const { return _M_data_allocator; }
-
-  _Vector_alloc_base(const allocator_type& __a)
-    : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
-  {}
-
-protected:
-  allocator_type _M_data_allocator;
-  _Tp*           _M_start;
-  _Tp*           _M_finish;
-  _Tp*           _M_end_of_storage;
-
-  _Tp*
-  _M_allocate(size_t __n) { return _M_data_allocator.allocate(__n); }
-
-  void
-  _M_deallocate(_Tp* __p, size_t __n)
-    { if (__p) _M_data_allocator.deallocate(__p, __n); }
-};
-
-/// @if maint Specialization for instanceless allocators.  @endif
-template <typename _Tp, typename _Allocator>
-  class _Vector_alloc_base<_Tp, _Allocator, true>
-{
-public:
-  typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
-          allocator_type;
-
-  allocator_type
-  get_allocator() const { return allocator_type(); }
-
-  _Vector_alloc_base(const allocator_type&)
-    : _M_start(0), _M_finish(0), _M_end_of_storage(0)
-  {}
-
-protected:
-  _Tp* _M_start;
-  _Tp* _M_finish;
-  _Tp* _M_end_of_storage;
-
-  typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
-
-  _Tp*
-  _M_allocate(size_t __n) { return _Alloc_type::allocate(__n); }
-
-  void
-  _M_deallocate(_Tp* __p, size_t __n) { _Alloc_type::deallocate(__p, __n);}
-};
-
-
-/**
- *  @if maint
- *  See bits/stl_deque.h's _Deque_base for an explanation.
- *  @endif
-*/
-template <typename _Tp, typename _Alloc>
-  struct _Vector_base
-  : public _Vector_alloc_base<_Tp, _Alloc,
-                              _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
-{
-public:
-  typedef _Vector_alloc_base<_Tp, _Alloc,
-                             _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
-          _Base;
-  typedef typename _Base::allocator_type allocator_type;
-
-  _Vector_base(const allocator_type& __a)
-    : _Base(__a) {}
-  _Vector_base(size_t __n, const allocator_type& __a)
-    : _Base(__a)
-  {
-    _M_start = _M_allocate(__n);
-    _M_finish = _M_start;
-    _M_end_of_storage = _M_start + __n;
-  }
-
-  ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
-};
-
-
-/**
- *  @brief  A standard container which offers fixed time access to individual
- *  elements in any order.
- *
- *  @ingroup Containers
- *  @ingroup Sequences
- *
- *  Meets the requirements of a <a href="tables.html#65">container</a>, a
- *  <a href="tables.html#66">reversible container</a>, and a
- *  <a href="tables.html#67">sequence</a>, including the
- *  <a href="tables.html#68">optional sequence requirements</a> with the
- *  %exception of @c push_front and @c pop_front.
- *
- *  In some terminology a %vector can be described as a dynamic C-style array,
- *  it offers fast and efficient access to individual elements in any order
- *  and saves the user from worrying about memory and size allocation.
- *  Subscripting ( @c [] ) access is also provided as with C-style arrays.
-*/
-template <typename _Tp, typename _Alloc = allocator<_Tp> >
-  class vector : protected _Vector_base<_Tp, _Alloc>
-{
-  // concept requirements
-  __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
-
-  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 __gnu_cxx::__normal_iterator<pointer, vector_type>   iterator;
-  typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type>
-                                                        const_iterator;
-  typedef reverse_iterator<const_iterator>              const_reverse_iterator;
-  typedef reverse_iterator<iterator>                    reverse_iterator;
-  typedef value_type&                                  reference;
-  typedef const value_type&                            const_reference;
-  typedef size_t                                       size_type;
-  typedef ptrdiff_t                                    difference_type;
-  typedef typename _Base::allocator_type                allocator_type;
-
-protected:
-  /** @if maint
-   *  These two functions and three data members are all from the top-most
-   *  base class, which varies depending on the type of %allocator.  They
-   *  should be pretty self-explanatory, as %vector uses a simple contiguous 
-   *  allocation scheme.
-   *  @endif
-  */
-  using _Base::_M_allocate;
-  using _Base::_M_deallocate;
-  using _Base::_M_start;
-  using _Base::_M_finish;
-  using _Base::_M_end_of_storage;
-
-public:
-  // [23.2.4.1] construct/copy/destroy
-  // (assign() and get_allocator() are also listed in this section)
-  /**
-   *  @brief  Default constructor creates no elements.
-  */
-  explicit
-  vector(const allocator_type& __a = allocator_type())
-    : _Base(__a) {}
-
+  /// @if maint Primary default version.  @endif
   /**
-   *  @brief  Create a %vector with copies of an exemplar element.
-   *  @param  n  The number of elements to initially create.
-   *  @param  value  An element to copy.
-   * 
-   *  This constructor fills the %vector with @a n copies of @a value.
-  */
-  vector(size_type __n, const value_type& __value,
-         const allocator_type& __a = allocator_type())
-    : _Base(__n, __a)
-    { _M_finish = uninitialized_fill_n(_M_start, __n, __value); }
-
-  /**
-   *  @brief  Create a %vector with default elements.
-   *  @param  n  The number of elements to initially create.
-   * 
-   *  This constructor fills the %vector with @a n copies of a
-   *  default-constructed element.
-  */
-  explicit
-  vector(size_type __n)
-    : _Base(__n, allocator_type())
-    { _M_finish = uninitialized_fill_n(_M_start, __n, value_type()); }
-
-  /**
-   *  @brief  %Vector copy constructor.
-   *  @param  x  A %vector of identical element and allocator types.
-   * 
-   *  The newly-created %vector uses a copy of the allocation object used
-   *  by @a x.  All the elements of @a x are copied, but any extra memory in
-   *  @a x (for fast expansion) will not be copied.
-  */
-  vector(const vector& __x)
-    : _Base(__x.size(), __x.get_allocator())
-    { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); }
-
-  /**
-   *  @brief  Builds a %vector from a range.
-   *  @param  first  An input iterator.
-   *  @param  last  An input iterator.
-   * 
-   *  Create a %vector consisting of copies of the elements from [first,last).
-   *
-   *  If the iterators are forward, bidirectional, or random-access, then
-   *  this will call the elements' copy constructor N times (where N is
-   *  distance(first,last)) and do no memory reallocation.  But if only
-   *  input iterators are used, then this will do at most 2N calls to the
-   *  copy constructor, and logN memory reallocations.
-  */
-  template <typename _InputIterator>
-    vector(_InputIterator __first, _InputIterator __last,
-           const allocator_type& __a = allocator_type())
-      : _Base(__a)
-    {
-      // Check whether it's an integral type.  If so, it's not an iterator.
-      typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
-      _M_initialize_dispatch(__first, __last, _Integral());
-    }
-
-  /**
-   *  The dtor only erases the elements, and note that if the elements
-   *  themselves are pointers, the pointed-to memory is not touched in any
-   *  way.  Managing the pointer is the user's responsibilty.
-  */
-  ~vector() { _Destroy(_M_start, _M_finish); }
-
-  /**
-   *  @brief  %Vector assignment operator.
-   *  @param  x  A %vector of identical element and allocator types.
-   * 
-   *  All the elements of @a x are copied, but any extra memory in @a x (for
-   *  fast expansion) will not be copied.  Unlike the copy constructor, the
-   *  allocator object is not copied.
-  */
-  vector&
-  operator=(const vector& __x);
-
-  /**
-   *  @brief  Assigns a given value to a %vector.
-   *  @param  n  Number of elements to be assigned.
-   *  @param  val  Value to be assigned.
-   *
-   *  This function fills a %vector with @a n copies of the given value.
-   *  Note that the assignment completely changes the %vector and that the
-   *  resulting %vector's size is the same as the number of elements assigned.
-   *  Old data may be lost.
-  */
-  void
-  assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); }
-
-  /**
-   *  @brief  Assigns a range to a %vector.
-   *  @param  first  An input iterator.
-   *  @param  last   An input iterator.
-   *
-   *  This function fills a %vector with copies of the elements in the
-   *  range [first,last).
-   *
-   *  Note that the assignment completely changes the %vector and that the
-   *  resulting %vector's size is the same as the number of elements assigned.
-   *  Old data may be lost.
-  */
-  template<typename _InputIterator>
-    void
-    assign(_InputIterator __first, _InputIterator __last)
-    {
-      // Check whether it's an integral type.  If so, it's not an iterator.
-      typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
-      _M_assign_dispatch(__first, __last, _Integral());
-    }
-
-  /// Get a copy of the memory allocation object.
-  allocator_type
-  get_allocator() const { return _Base::get_allocator(); }
-
-  // iterators
-  /**
-   *  Returns a read/write iterator that points to the first element in the
-   *  %vector.  Iteration is done in ordinary element order.
-  */
-  iterator
-  begin() { return iterator (_M_start); }
-
-  /**
-   *  Returns a read-only (constant) iterator that points to the first element
-   *  in the %vector.  Iteration is done in ordinary element order.
-  */
-  const_iterator
-  begin() const { return const_iterator (_M_start); }
-
-  /**
-   *  Returns a read/write iterator that points one past the last element in
-   *  the %vector.  Iteration is done in ordinary element order.
-  */
-  iterator
-  end() { return iterator (_M_finish); }
-
-  /**
-   *  Returns a read-only (constant) iterator that points one past the last
-   *  element in the %vector.  Iteration is done in ordinary element order.
-  */
-  const_iterator
-  end() const { return const_iterator (_M_finish); }
-
-  /**
-   *  Returns a read/write reverse iterator that points to the last element in
-   *  the %vector.  Iteration is done in reverse element order.
-  */
-  reverse_iterator
-  rbegin() { return reverse_iterator(end()); }
-
-  /**
-   *  Returns a read-only (constant) reverse iterator that points to the last
-   *  element in the %vector.  Iteration is done in reverse element order.
-  */
-  const_reverse_iterator
-  rbegin() const { return const_reverse_iterator(end()); }
-
-  /**
-   *  Returns a read/write reverse iterator that points to one before the
-   *  first element in the %vector.  Iteration is done in reverse element
-   *  order.
-  */
-  reverse_iterator
-  rend() { return reverse_iterator(begin()); }
-
-  /**
-   *  Returns a read-only (constant) reverse iterator that points to one
-   *  before the first element in the %vector.  Iteration is done in reverse
-   *  element order.
-  */
-  const_reverse_iterator
-  rend() const { return const_reverse_iterator(begin()); }
-
-  // [23.2.4.2] capacity
-  /**  Returns the number of elements in the %vector.  */
-  size_type
-  size() const { return size_type(end() - begin()); }
-
-  /**  Returns the size() of the largest possible %vector.  */
-  size_type
-  max_size() const { return size_type(-1) / sizeof(value_type); }
-
-  /**
-   *  @brief  Resizes the %vector to the specified number of elements.
-   *  @param  new_size  Number of elements the %vector should contain.
-   *  @param  x  Data with which new elements should be populated.
-   *
-   *  This function will %resize the %vector to the specified number of
-   *  elements.  If the number is smaller than the %vector's current size the
-   *  %vector is truncated, otherwise the %vector is extended and new elements
-   *  are populated with given data.
+   *  @if maint
+   *  See bits/stl_deque.h's _Deque_alloc_base for an explanation.
+   *  @endif
   */
-  void
-  resize(size_type __new_size, const value_type& __x)
+  template <typename _Tp, typename _Allocator, bool _IsStatic>
+    class _Vector_alloc_base
   {
-    if (__new_size < size())
-      erase(begin() + __new_size, end());
-    else
-      insert(end(), __new_size - size(), __x);
-  }
-
-  /**
-   *  @brief  Resizes the %vector to the specified number of elements.
-   *  @param  new_size  Number of elements the %vector should contain.
-   *
-   *  This function will resize the %vector to the specified number of
-   *  elements.  If the number is smaller than the %vector's current size the
-   *  %vector is truncated, otherwise the %vector is extended and new elements
-   *  are default-constructed.
-  */
-  void
-  resize(size_type __new_size) { resize(__new_size, value_type()); }
-
-  /**
-   *  Returns the total number of elements that the %vector can hold before
-   *  needing to allocate more memory.
-  */
-  size_type
-  capacity() const
-    { return size_type(const_iterator(_M_end_of_storage) - begin()); }
-
-  /**
-   *  Returns true if the %vector is empty.  (Thus begin() would equal end().)
-  */
-  bool
-  empty() const { return begin() == end(); }
-
-  /**
-   *  @brief  Attempt to preallocate enough memory for specified number of
-   *          elements.
-   *  @param  n  Number of elements required.
-   *  @throw  std::length_error  If @a n exceeds @c max_size().
-   *
-   *  This function attempts to reserve enough memory for the %vector to hold
-   *  the specified number of elements.  If the number requested is more than
-   *  max_size(), length_error is thrown.
-   *
-   *  The advantage of this function is that if optimal code is a necessity
-   *  and the user can determine the number of elements that will be required,
-   *  the user can reserve the memory in %advance, and thus prevent a possible
-   *  reallocation of memory and copying of %vector data.
-  */
-  void
-  reserve(size_type __n);
-
-  // element access
-  /**
-   *  @brief  Subscript access to the data contained in the %vector.
-   *  @param  n  The index of the element for which data should be accessed.
-   *  @return  Read/write reference to data.
-   *
-   *  This operator allows for easy, array-style, data access.
-   *  Note that data access with this operator is unchecked and out_of_range
-   *  lookups are not defined. (For checked lookups see at().)
-  */
-  reference
-  operator[](size_type __n) { return *(begin() + __n); }
-
-  /**
-   *  @brief  Subscript access to the data contained in the %vector.
-   *  @param  n  The index of the element for which data should be accessed.
-   *  @return  Read-only (constant) reference to data.
-   *
-   *  This operator allows for easy, array-style, data access.
-   *  Note that data access with this operator is unchecked and out_of_range
-   *  lookups are not defined. (For checked lookups see at().)
-  */
-  const_reference
-  operator[](size_type __n) const { return *(begin() + __n); }
-
-protected:
-  /// @if maint Safety check used only from at().  @endif
-  void
-  _M_range_check(size_type __n) const
+  public:
+    typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
+            allocator_type;
+  
+    allocator_type
+    get_allocator() const { return _M_data_allocator; }
+  
+    _Vector_alloc_base(const allocator_type& __a)
+      : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
+    {}
+  
+  protected:
+    allocator_type _M_data_allocator;
+    _Tp*           _M_start;
+    _Tp*           _M_finish;
+    _Tp*           _M_end_of_storage;
+  
+    _Tp*
+    _M_allocate(size_t __n) { return _M_data_allocator.allocate(__n); }
+  
+    void
+    _M_deallocate(_Tp* __p, size_t __n)
+      { if (__p) _M_data_allocator.deallocate(__p, __n); }
+  };
+  
+  /// @if maint Specialization for instanceless allocators.  @endif
+  template <typename _Tp, typename _Allocator>
+    class _Vector_alloc_base<_Tp, _Allocator, true>
   {
-    if (__n >= this->size())
-      __throw_out_of_range("vector [] access out of range");
-  }
-
-public:
-  /**
-   *  @brief  Provides access to the data contained in the %vector.
-   *  @param  n  The index of the element for which data should be accessed.
-   *  @return  Read/write reference to data.
-   *  @throw  std::out_of_range  If @a n is an invalid index.
-   *
-   *  This function provides for safer data access.  The parameter is first
-   *  checked that it is in the range of the vector.  The function throws
-   *  out_of_range if the check fails.
-  */
-  reference
-  at(size_type __n) { _M_range_check(__n); return (*this)[__n]; }
-
-  /**
-   *  @brief  Provides access to the data contained in the %vector.
-   *  @param  n  The index of the element for which data should be accessed.
-   *  @return  Read-only (constant) reference to data.
-   *  @throw  std::out_of_range  If @a n is an invalid index.
-   *
-   *  This function provides for safer data access.  The parameter is first
-   *  checked that it is in the range of the vector.  The function throws
-   *  out_of_range if the check fails.
-  */
-  const_reference
-  at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; }
-
-  /**
-   *  Returns a read/write reference to the data at the first element of the
-   *  %vector.
-  */
-  reference
-  front() { return *begin(); }
-
-  /**
-   *  Returns a read-only (constant) reference to the data at the first
-   *  element of the %vector.
-  */
-  const_reference
-  front() const { return *begin(); }
-
-  /**
-   *  Returns a read/write reference to the data at the last element of the
-   *  %vector.
-  */
-  reference
-  back() { return *(end() - 1); }
-
-  /**
-   *  Returns a read-only (constant) reference to the data at the last
-   *  element of the %vector.
-  */
-  const_reference
-  back() const { return *(end() - 1); }
-
-  // [23.2.4.3] modifiers
+  public:
+    typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
+            allocator_type;
+  
+    allocator_type
+    get_allocator() const { return allocator_type(); }
+  
+    _Vector_alloc_base(const allocator_type&)
+      : _M_start(0), _M_finish(0), _M_end_of_storage(0)
+    {}
+  
+  protected:
+    _Tp* _M_start;
+    _Tp* _M_finish;
+    _Tp* _M_end_of_storage;
+  
+    typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
+  
+    _Tp*
+    _M_allocate(size_t __n) { return _Alloc_type::allocate(__n); }
+  
+    void
+    _M_deallocate(_Tp* __p, size_t __n) { _Alloc_type::deallocate(__p, __n);}
+  };
+  
+  
   /**
-   *  @brief  Add data to the end of the %vector.
-   *  @param  x  Data to be added.
-   *
-   *  This is a typical stack operation.  The function creates an element at
-   *  the end of the %vector and assigns the given data to it.
-   *  Due to the nature of a %vector this operation can be done in constant
-   *  time if the %vector has preallocated space available.
+   *  @if maint
+   *  See bits/stl_deque.h's _Deque_base for an explanation.
+   *  @endif
   */
-  void
-  push_back(const value_type& __x)
+  template <typename _Tp, typename _Alloc>
+    struct _Vector_base
+    : public _Vector_alloc_base<_Tp, _Alloc,
+                                _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
   {
-    if (_M_finish != _M_end_of_storage)
+  public:
+    typedef _Vector_alloc_base<_Tp, _Alloc,
+                               _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
+            _Base;
+    typedef typename _Base::allocator_type allocator_type;
+  
+    _Vector_base(const allocator_type& __a)
+      : _Base(__a) {}
+    _Vector_base(size_t __n, const allocator_type& __a)
+      : _Base(__a)
     {
-      _Construct(_M_finish, __x);
-      ++_M_finish;
+      _M_start = _M_allocate(__n);
+      _M_finish = _M_start;
+      _M_end_of_storage = _M_start + __n;
     }
-    else
-      _M_insert_aux(end(), __x);
-  }
-
-  /**
-   *  @brief  Removes last element.
-   *
-   *  This is a typical stack operation. It shrinks the %vector by one.
-   *
-   *  Note that no data is returned, and if the last element's data is
-   *  needed, it should be retrieved before pop_back() is called.
-  */
-  void
-  pop_back()
-  {
-    --_M_finish;
-    _Destroy(_M_finish);
-  }
-
-  /**
-   *  @brief  Inserts given value into %vector before specified iterator.
-   *  @param  position  An iterator into the %vector.
-   *  @param  x  Data to be inserted.
-   *  @return  An iterator that points to the inserted data.
-   *
-   *  This function will insert a copy of the given value before the specified
-   *  location.
-   *  Note that this kind of operation could be expensive for a %vector and if
-   *  it is frequently used the user should consider using std::list.
-  */
-  iterator
-  insert(iterator __position, const value_type& __x);
-
-#ifdef _GLIBCPP_DEPRECATED
-  /**
-   *  @brief  Inserts an element into the %vector.
-   *  @param  position  An iterator into the %vector.
-   *  @return  An iterator that points to the inserted element.
-   *
-   *  This function will insert a default-constructed element before the
-   *  specified location.  You should consider using
-   *  insert(position,value_type()) instead.
-   *  Note that this kind of operation could be expensive for a vector and if
-   *  it is frequently used the user should consider using std::list.
-   *
-   *  @note This was deprecated in 3.2 and will be removed in 3.4.  You must
-   *        define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see
-   *        c++config.h.
-  */
-  iterator
-  insert(iterator __position)
-    { return insert(__position, value_type()); }
-#endif
-
-  /**
-   *  @brief  Inserts a number of copies of given data into the %vector.
-   *  @param  position  An iterator into the %vector.
-   *  @param  n  Number of elements to be inserted.
-   *  @param  x  Data to be inserted.
+  
+    ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
+  };
+  
+  
+  /**
+   *  @brief  A standard container which offers fixed time access to individual
+   *  elements in any order.
    *
-   *  This function will insert a specified number of copies of the given data
-   *  before the location specified by @a position.
+   *  @ingroup Containers
+   *  @ingroup Sequences
    *
-   *  Note that this kind of operation could be expensive for a %vector and if
-   *  it is frequently used the user should consider using std::list.
-  */
-  void
-  insert (iterator __pos, size_type __n, const value_type& __x)
-    { _M_fill_insert(__pos, __n, __x); }
-
-  /**
-   *  @brief  Inserts a range into the %vector.
-   *  @param  pos  An iterator into the %vector.
-   *  @param  first  An input iterator.
-   *  @param  last   An input iterator.
-   *
-   *  This function will insert copies of the data in the range [first,last)
-   *  into the %vector before the location specified by @a pos.
+   *  Meets the requirements of a <a href="tables.html#65">container</a>, a
+   *  <a href="tables.html#66">reversible container</a>, and a
+   *  <a href="tables.html#67">sequence</a>, including the
+   *  <a href="tables.html#68">optional sequence requirements</a> with the
+   *  %exception of @c push_front and @c pop_front.
    *
-   *  Note that this kind of operation could be expensive for a %vector and if
-   *  it is frequently used the user should consider using std::list.
+   *  In some terminology a %vector can be described as a dynamic C-style array,
+   *  it offers fast and efficient access to individual elements in any order
+   *  and saves the user from worrying about memory and size allocation.
+   *  Subscripting ( @c [] ) access is also provided as with C-style arrays.
   */
-  template<typename _InputIterator>
-    void
-    insert(iterator __pos, _InputIterator __first, _InputIterator __last)
+  template <typename _Tp, typename _Alloc = allocator<_Tp> >
+    class vector : protected _Vector_base<_Tp, _Alloc>
+  {
+    // concept requirements
+    __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
+  
+    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 __gnu_cxx::__normal_iterator<pointer, vector_type>         iterator;
+    typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type>
+                                                          const_iterator;
+    typedef reverse_iterator<const_iterator>              const_reverse_iterator;
+    typedef reverse_iterator<iterator>                    reverse_iterator;
+    typedef value_type&                                        reference;
+    typedef const value_type&                          const_reference;
+    typedef size_t                                     size_type;
+    typedef ptrdiff_t                                  difference_type;
+    typedef typename _Base::allocator_type                allocator_type;
+  
+  protected:
+    /** @if maint
+     *  These two functions and three data members are all from the top-most
+     *  base class, which varies depending on the type of %allocator.  They
+     *  should be pretty self-explanatory, as %vector uses a simple contiguous 
+     *  allocation scheme.
+     *  @endif
+    */
+    using _Base::_M_allocate;
+    using _Base::_M_deallocate;
+    using _Base::_M_start;
+    using _Base::_M_finish;
+    using _Base::_M_end_of_storage;
+  
+  public:
+    // [23.2.4.1] construct/copy/destroy
+    // (assign() and get_allocator() are also listed in this section)
+    /**
+     *  @brief  Default constructor creates no elements.
+    */
+    explicit
+    vector(const allocator_type& __a = allocator_type())
+      : _Base(__a) {}
+  
+    /**
+     *  @brief  Create a %vector with copies of an exemplar element.
+     *  @param  n  The number of elements to initially create.
+     *  @param  value  An element to copy.
+     * 
+     *  This constructor fills the %vector with @a n copies of @a value.
+    */
+    vector(size_type __n, const value_type& __value,
+           const allocator_type& __a = allocator_type())
+      : _Base(__n, __a)
+      { _M_finish = uninitialized_fill_n(_M_start, __n, __value); }
+  
+    /**
+     *  @brief  Create a %vector with default elements.
+     *  @param  n  The number of elements to initially create.
+     * 
+     *  This constructor fills the %vector with @a n copies of a
+     *  default-constructed element.
+    */
+    explicit
+    vector(size_type __n)
+      : _Base(__n, allocator_type())
+      { _M_finish = uninitialized_fill_n(_M_start, __n, value_type()); }
+  
+    /**
+     *  @brief  %Vector copy constructor.
+     *  @param  x  A %vector of identical element and allocator types.
+     * 
+     *  The newly-created %vector uses a copy of the allocation object used
+     *  by @a x.  All the elements of @a x are copied, but any extra memory in
+     *  @a x (for fast expansion) will not be copied.
+    */
+    vector(const vector& __x)
+      : _Base(__x.size(), __x.get_allocator())
+      { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); }
+  
+    /**
+     *  @brief  Builds a %vector from a range.
+     *  @param  first  An input iterator.
+     *  @param  last  An input iterator.
+     * 
+     *  Create a %vector consisting of copies of the elements from [first,last).
+     *
+     *  If the iterators are forward, bidirectional, or random-access, then
+     *  this will call the elements' copy constructor N times (where N is
+     *  distance(first,last)) and do no memory reallocation.  But if only
+     *  input iterators are used, then this will do at most 2N calls to the
+     *  copy constructor, and logN memory reallocations.
+    */
+    template <typename _InputIterator>
+      vector(_InputIterator __first, _InputIterator __last,
+             const allocator_type& __a = allocator_type())
+        : _Base(__a)
       {
         // Check whether it's an integral type.  If so, it's not an iterator.
         typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
-        _M_insert_dispatch(__pos, __first, __last, _Integral());
+        _M_initialize_dispatch(__first, __last, _Integral());
       }
-
-  /**
-   *  @brief  Remove element at given position.
-   *  @param  position  Iterator pointing to element to be erased.
-   *  @return  An iterator pointing to the next element (or end()).
-   *
-   *  This function will erase the element at the given position and thus
-   *  shorten the %vector by one.
-   *
-   *  Note This operation could be expensive and if it is frequently used the
-   *  user should consider using std::list.  The user is also cautioned that
-   *  this function only erases the element, and that if the element is itself
-   *  a pointer, the pointed-to memory is not touched in any way.  Managing
-   *  the pointer is the user's responsibilty.
-  */
-  iterator
-  erase(iterator __position);
-
-  /**
-   *  @brief  Remove a range of elements.
-   *  @param  first  Iterator pointing to the first element to be erased.
-   *  @param  last  Iterator pointing to one past the last element to be erased.
-   *  @return  An iterator pointing to the element pointed to by @a last
-   *           prior to erasing (or end()).
-   *
-   *  This function will erase the elements in the range [first,last) and
-   *  shorten the %vector accordingly.
-   *
-   *  Note This operation could be expensive and if it is frequently used the
-   *  user should consider using std::list.  The user is also cautioned that
-   *  this function only erases the elements, and that if the elements
-   *  themselves are pointers, the pointed-to memory is not touched in any
-   *  way.  Managing the pointer is the user's responsibilty.
-  */
-  iterator
-  erase(iterator __first, iterator __last);
-
-  /**
-   *  @brief  Swaps data with another %vector.
-   *  @param  x  A %vector of the same element and allocator types.
-   *
-   *  This exchanges the elements between two vectors in constant time.
-   *  (Three pointers, so it should be quite fast.)
-   *  Note that the global std::swap() function is specialized such that
-   *  std::swap(v1,v2) will feed to this function.
-  */
-  void
-  swap(vector& __x)
-  {
-    std::swap(_M_start, __x._M_start);
-    std::swap(_M_finish, __x._M_finish);
-    std::swap(_M_end_of_storage, __x._M_end_of_storage);
-  }
-
-  /**
-   *  Erases all the elements.  Note that this function only erases the
-   *  elements, and that if the elements themselves are pointers, the
-   *  pointed-to memory is not touched in any way.  Managing the pointer is
-   *  the user's responsibilty.
-  */
-  void
-  clear() { erase(begin(), end()); }
-
-protected:
-  /**
-   *  @if maint
-   *  Memory expansion handler.  Uses the member allocation function to
-   *  obtain @a n bytes of memory, and then copies [first,last) into it.
-   *  @endif
-  */
-  template <typename _ForwardIterator>
-  pointer
-    _M_allocate_and_copy(size_type __n,
-                         _ForwardIterator __first, _ForwardIterator __last)
-  {
-    pointer __result = _M_allocate(__n);
-    try
-      {
-        uninitialized_copy(__first, __last, __result);
-        return __result;
-      }
-    catch(...)
+  
+    /**
+     *  The dtor only erases the elements, and note that if the elements
+     *  themselves are pointers, the pointed-to memory is not touched in any
+     *  way.  Managing the pointer is the user's responsibilty.
+    */
+    ~vector() { _Destroy(_M_start, _M_finish); }
+  
+    /**
+     *  @brief  %Vector assignment operator.
+     *  @param  x  A %vector of identical element and allocator types.
+     * 
+     *  All the elements of @a x are copied, but any extra memory in @a x (for
+     *  fast expansion) will not be copied.  Unlike the copy constructor, the
+     *  allocator object is not copied.
+    */
+    vector&
+    operator=(const vector& __x);
+  
+    /**
+     *  @brief  Assigns a given value to a %vector.
+     *  @param  n  Number of elements to be assigned.
+     *  @param  val  Value to be assigned.
+     *
+     *  This function fills a %vector with @a n copies of the given value.
+     *  Note that the assignment completely changes the %vector and that the
+     *  resulting %vector's size is the same as the number of elements assigned.
+     *  Old data may be lost.
+    */
+    void
+    assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); }
+  
+    /**
+     *  @brief  Assigns a range to a %vector.
+     *  @param  first  An input iterator.
+     *  @param  last   An input iterator.
+     *
+     *  This function fills a %vector with copies of the elements in the
+     *  range [first,last).
+     *
+     *  Note that the assignment completely changes the %vector and that the
+     *  resulting %vector's size is the same as the number of elements assigned.
+     *  Old data may be lost.
+    */
+    template<typename _InputIterator>
+      void
+      assign(_InputIterator __first, _InputIterator __last)
       {
-       _M_deallocate(__result, __n);
-       __throw_exception_again;
+        // Check whether it's an integral type.  If so, it's not an iterator.
+        typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+        _M_assign_dispatch(__first, __last, _Integral());
       }
-  }
-
-
-  // Internal constructor functions follow.
-
-  // called by the range constructor to implement [23.1.1]/9
-  template<typename _Integer>
+  
+    /// Get a copy of the memory allocation object.
+    allocator_type
+    get_allocator() const { return _Base::get_allocator(); }
+  
+    // iterators
+    /**
+     *  Returns a read/write iterator that points to the first element in the
+     *  %vector.  Iteration is done in ordinary element order.
+    */
+    iterator
+    begin() { return iterator (_M_start); }
+  
+    /**
+     *  Returns a read-only (constant) iterator that points to the first element
+     *  in the %vector.  Iteration is done in ordinary element order.
+    */
+    const_iterator
+    begin() const { return const_iterator (_M_start); }
+  
+    /**
+     *  Returns a read/write iterator that points one past the last element in
+     *  the %vector.  Iteration is done in ordinary element order.
+    */
+    iterator
+    end() { return iterator (_M_finish); }
+  
+    /**
+     *  Returns a read-only (constant) iterator that points one past the last
+     *  element in the %vector.  Iteration is done in ordinary element order.
+    */
+    const_iterator
+    end() const { return const_iterator (_M_finish); }
+  
+    /**
+     *  Returns a read/write reverse iterator that points to the last element in
+     *  the %vector.  Iteration is done in reverse element order.
+    */
+    reverse_iterator
+    rbegin() { return reverse_iterator(end()); }
+  
+    /**
+     *  Returns a read-only (constant) reverse iterator that points to the last
+     *  element in the %vector.  Iteration is done in reverse element order.
+    */
+    const_reverse_iterator
+    rbegin() const { return const_reverse_iterator(end()); }
+  
+    /**
+     *  Returns a read/write reverse iterator that points to one before the
+     *  first element in the %vector.  Iteration is done in reverse element
+     *  order.
+    */
+    reverse_iterator
+    rend() { return reverse_iterator(begin()); }
+  
+    /**
+     *  Returns a read-only (constant) reverse iterator that points to one
+     *  before the first element in the %vector.  Iteration is done in reverse
+     *  element order.
+    */
+    const_reverse_iterator
+    rend() const { return const_reverse_iterator(begin()); }
+  
+    // [23.2.4.2] capacity
+    /**  Returns the number of elements in the %vector.  */
+    size_type
+    size() const { return size_type(end() - begin()); }
+  
+    /**  Returns the size() of the largest possible %vector.  */
+    size_type
+    max_size() const { return size_type(-1) / sizeof(value_type); }
+  
+    /**
+     *  @brief  Resizes the %vector to the specified number of elements.
+     *  @param  new_size  Number of elements the %vector should contain.
+     *  @param  x  Data with which new elements should be populated.
+     *
+     *  This function will %resize the %vector to the specified number of
+     *  elements.  If the number is smaller than the %vector's current size the
+     *  %vector is truncated, otherwise the %vector is extended and new elements
+     *  are populated with given data.
+    */
     void
-    _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type)
+    resize(size_type __new_size, const value_type& __x)
     {
-      _M_start = _M_allocate(__n);
-      _M_end_of_storage = _M_start + __n;
-      _M_finish = uninitialized_fill_n(_M_start, __n, __value);
+      if (__new_size < size())
+        erase(begin() + __new_size, end());
+      else
+        insert(end(), __new_size - size(), __x);
     }
-
-  // called by the range constructor to implement [23.1.1]/9
-  template<typename _InputIter>
+  
+    /**
+     *  @brief  Resizes the %vector to the specified number of elements.
+     *  @param  new_size  Number of elements the %vector should contain.
+     *
+     *  This function will resize the %vector to the specified number of
+     *  elements.  If the number is smaller than the %vector's current size the
+     *  %vector is truncated, otherwise the %vector is extended and new elements
+     *  are default-constructed.
+    */
+    void
+    resize(size_type __new_size) { resize(__new_size, value_type()); }
+  
+    /**
+     *  Returns the total number of elements that the %vector can hold before
+     *  needing to allocate more memory.
+    */
+    size_type
+    capacity() const
+      { return size_type(const_iterator(_M_end_of_storage) - begin()); }
+  
+    /**
+     *  Returns true if the %vector is empty.  (Thus begin() would equal end().)
+    */
+    bool
+    empty() const { return begin() == end(); }
+  
+    /**
+     *  @brief  Attempt to preallocate enough memory for specified number of
+     *          elements.
+     *  @param  n  Number of elements required.
+     *  @throw  std::length_error  If @a n exceeds @c max_size().
+     *
+     *  This function attempts to reserve enough memory for the %vector to hold
+     *  the specified number of elements.  If the number requested is more than
+     *  max_size(), length_error is thrown.
+     *
+     *  The advantage of this function is that if optimal code is a necessity
+     *  and the user can determine the number of elements that will be required,
+     *  the user can reserve the memory in %advance, and thus prevent a possible
+     *  reallocation of memory and copying of %vector data.
+    */
+    void
+    reserve(size_type __n);
+  
+    // element access
+    /**
+     *  @brief  Subscript access to the data contained in the %vector.
+     *  @param  n  The index of the element for which data should be accessed.
+     *  @return  Read/write reference to data.
+     *
+     *  This operator allows for easy, array-style, data access.
+     *  Note that data access with this operator is unchecked and out_of_range
+     *  lookups are not defined. (For checked lookups see at().)
+    */
+    reference
+    operator[](size_type __n) { return *(begin() + __n); }
+  
+    /**
+     *  @brief  Subscript access to the data contained in the %vector.
+     *  @param  n  The index of the element for which data should be accessed.
+     *  @return  Read-only (constant) reference to data.
+     *
+     *  This operator allows for easy, array-style, data access.
+     *  Note that data access with this operator is unchecked and out_of_range
+     *  lookups are not defined. (For checked lookups see at().)
+    */
+    const_reference
+    operator[](size_type __n) const { return *(begin() + __n); }
+  
+  protected:
+    /// @if maint Safety check used only from at().  @endif
     void
-    _M_initialize_dispatch(_InputIter __first, _InputIter __last, __false_type)
+    _M_range_check(size_type __n) const
     {
-      typedef typename iterator_traits<_InputIter>::iterator_category
-                       _IterCategory;
-      _M_range_initialize(__first, __last, _IterCategory());
+      if (__n >= this->size())
+        __throw_out_of_range("vector [] access out of range");
     }
-
-  // called by the second initialize_dispatch above
-  template <typename _InputIterator>
-  void
-    _M_range_initialize(_InputIterator __first,
-                        _InputIterator __last, input_iterator_tag)
-  {
-    for ( ; __first != __last; ++__first)
-      push_back(*__first);
-  }
-
-  // called by the second initialize_dispatch above
-  template <typename _ForwardIterator>
-  void _M_range_initialize(_ForwardIterator __first,
-                           _ForwardIterator __last, forward_iterator_tag)
-  {
-    size_type __n = distance(__first, __last);
-    _M_start = _M_allocate(__n);
-    _M_end_of_storage = _M_start + __n;
-    _M_finish = uninitialized_copy(__first, __last, _M_start);
-  }
-
-
-  // Internal assign functions follow.  The *_aux functions do the actual
-  // assignment work for the range versions.
-
-  // called by the range assign to implement [23.1.1]/9
-  template<typename _Integer>
+  
+  public:
+    /**
+     *  @brief  Provides access to the data contained in the %vector.
+     *  @param  n  The index of the element for which data should be accessed.
+     *  @return  Read/write reference to data.
+     *  @throw  std::out_of_range  If @a n is an invalid index.
+     *
+     *  This function provides for safer data access.  The parameter is first
+     *  checked that it is in the range of the vector.  The function throws
+     *  out_of_range if the check fails.
+    */
+    reference
+    at(size_type __n) { _M_range_check(__n); return (*this)[__n]; }
+  
+    /**
+     *  @brief  Provides access to the data contained in the %vector.
+     *  @param  n  The index of the element for which data should be accessed.
+     *  @return  Read-only (constant) reference to data.
+     *  @throw  std::out_of_range  If @a n is an invalid index.
+     *
+     *  This function provides for safer data access.  The parameter is first
+     *  checked that it is in the range of the vector.  The function throws
+     *  out_of_range if the check fails.
+    */
+    const_reference
+    at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; }
+  
+    /**
+     *  Returns a read/write reference to the data at the first element of the
+     *  %vector.
+    */
+    reference
+    front() { return *begin(); }
+  
+    /**
+     *  Returns a read-only (constant) reference to the data at the first
+     *  element of the %vector.
+    */
+    const_reference
+    front() const { return *begin(); }
+  
+    /**
+     *  Returns a read/write reference to the data at the last element of the
+     *  %vector.
+    */
+    reference
+    back() { return *(end() - 1); }
+  
+    /**
+     *  Returns a read-only (constant) reference to the data at the last
+     *  element of the %vector.
+    */
+    const_reference
+    back() const { return *(end() - 1); }
+  
+    // [23.2.4.3] modifiers
+    /**
+     *  @brief  Add data to the end of the %vector.
+     *  @param  x  Data to be added.
+     *
+     *  This is a typical stack operation.  The function creates an element at
+     *  the end of the %vector and assigns the given data to it.
+     *  Due to the nature of a %vector this operation can be done in constant
+     *  time if the %vector has preallocated space available.
+    */
     void
-     _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
-     {
-       _M_fill_assign(static_cast<size_type>(__n),
-                      static_cast<value_type>(__val));
-     }
-
-  // called by the range assign to implement [23.1.1]/9
-  template<typename _InputIter>
+    push_back(const value_type& __x)
+    {
+      if (_M_finish != _M_end_of_storage)
+      {
+        _Construct(_M_finish, __x);
+        ++_M_finish;
+      }
+      else
+        _M_insert_aux(end(), __x);
+    }
+  
+    /**
+     *  @brief  Removes last element.
+     *
+     *  This is a typical stack operation. It shrinks the %vector by one.
+     *
+     *  Note that no data is returned, and if the last element's data is
+     *  needed, it should be retrieved before pop_back() is called.
+    */
     void
-    _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type)
+    pop_back()
     {
-      typedef typename iterator_traits<_InputIter>::iterator_category
-                       _IterCategory;
-      _M_assign_aux(__first, __last, _IterCategory());
+      --_M_finish;
+      _Destroy(_M_finish);
     }
-
-  // called by the second assign_dispatch above
-  template <typename _InputIterator>
-    void 
-    _M_assign_aux(_InputIterator __first, _InputIterator __last,
-                 input_iterator_tag);
-
-  // called by the second assign_dispatch above
-  template <typename _ForwardIterator>
-    void 
-    _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
-                 forward_iterator_tag);
-
-  // Called by assign(n,t), and the range assign when it turns out to be the
-  // same thing.
-  void
-  _M_fill_assign(size_type __n, const value_type& __val);
-
-
-  // Internal insert functions follow.
-
-  // called by the range insert to implement [23.1.1]/9
-  template<typename _Integer>
+  
+    /**
+     *  @brief  Inserts given value into %vector before specified iterator.
+     *  @param  position  An iterator into the %vector.
+     *  @param  x  Data to be inserted.
+     *  @return  An iterator that points to the inserted data.
+     *
+     *  This function will insert a copy of the given value before the specified
+     *  location.
+     *  Note that this kind of operation could be expensive for a %vector and if
+     *  it is frequently used the user should consider using std::list.
+    */
+    iterator
+    insert(iterator __position, const value_type& __x);
+  
+  #ifdef _GLIBCPP_DEPRECATED
+    /**
+     *  @brief  Inserts an element into the %vector.
+     *  @param  position  An iterator into the %vector.
+     *  @return  An iterator that points to the inserted element.
+     *
+     *  This function will insert a default-constructed element before the
+     *  specified location.  You should consider using
+     *  insert(position,value_type()) instead.
+     *  Note that this kind of operation could be expensive for a vector and if
+     *  it is frequently used the user should consider using std::list.
+     *
+     *  @note This was deprecated in 3.2 and will be removed in 3.4.  You must
+     *        define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see
+     *        c++config.h.
+    */
+    iterator
+    insert(iterator __position)
+      { return insert(__position, value_type()); }
+  #endif
+  
+    /**
+     *  @brief  Inserts a number of copies of given data into the %vector.
+     *  @param  position  An iterator into the %vector.
+     *  @param  n  Number of elements to be inserted.
+     *  @param  x  Data to be inserted.
+     *
+     *  This function will insert a specified number of copies of the given data
+     *  before the location specified by @a position.
+     *
+     *  Note that this kind of operation could be expensive for a %vector and if
+     *  it is frequently used the user should consider using std::list.
+    */
     void
-    _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
-                       __true_type)
+    insert (iterator __pos, size_type __n, const value_type& __x)
+      { _M_fill_insert(__pos, __n, __x); }
+  
+    /**
+     *  @brief  Inserts a range into the %vector.
+     *  @param  pos  An iterator into the %vector.
+     *  @param  first  An input iterator.
+     *  @param  last   An input iterator.
+     *
+     *  This function will insert copies of the data in the range [first,last)
+     *  into the %vector before the location specified by @a pos.
+     *
+     *  Note that this kind of operation could be expensive for a %vector and if
+     *  it is frequently used the user should consider using std::list.
+    */
+    template<typename _InputIterator>
+      void
+      insert(iterator __pos, _InputIterator __first, _InputIterator __last)
+        {
+          // Check whether it's an integral type.  If so, it's not an iterator.
+          typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
+          _M_insert_dispatch(__pos, __first, __last, _Integral());
+        }
+  
+    /**
+     *  @brief  Remove element at given position.
+     *  @param  position  Iterator pointing to element to be erased.
+     *  @return  An iterator pointing to the next element (or end()).
+     *
+     *  This function will erase the element at the given position and thus
+     *  shorten the %vector by one.
+     *
+     *  Note This operation could be expensive and if it is frequently used the
+     *  user should consider using std::list.  The user is also cautioned that
+     *  this function only erases the element, and that if the element is itself
+     *  a pointer, the pointed-to memory is not touched in any way.  Managing
+     *  the pointer is the user's responsibilty.
+    */
+    iterator
+    erase(iterator __position);
+  
+    /**
+     *  @brief  Remove a range of elements.
+     *  @param  first  Iterator pointing to the first element to be erased.
+     *  @param  last  Iterator pointing to one past the last element to be
+     *                erased.
+     *  @return  An iterator pointing to the element pointed to by @a last
+     *           prior to erasing (or end()).
+     *
+     *  This function will erase the elements in the range [first,last) and
+     *  shorten the %vector accordingly.
+     *
+     *  Note This operation could be expensive and if it is frequently used the
+     *  user should consider using std::list.  The user is also cautioned that
+     *  this function only erases the elements, and that if the elements
+     *  themselves are pointers, the pointed-to memory is not touched in any
+     *  way.  Managing the pointer is the user's responsibilty.
+    */
+    iterator
+    erase(iterator __first, iterator __last);
+  
+    /**
+     *  @brief  Swaps data with another %vector.
+     *  @param  x  A %vector of the same element and allocator types.
+     *
+     *  This exchanges the elements between two vectors in constant time.
+     *  (Three pointers, so it should be quite fast.)
+     *  Note that the global std::swap() function is specialized such that
+     *  std::swap(v1,v2) will feed to this function.
+    */
+    void
+    swap(vector& __x)
     {
-      _M_fill_insert(__pos, static_cast<size_type>(__n),
-                            static_cast<value_type>(__val));
+      std::swap(_M_start, __x._M_start);
+      std::swap(_M_finish, __x._M_finish);
+      std::swap(_M_end_of_storage, __x._M_end_of_storage);
     }
-
-  // called by the range insert to implement [23.1.1]/9
-  template<typename _InputIterator>
+  
+    /**
+     *  Erases all the elements.  Note that this function only erases the
+     *  elements, and that if the elements themselves are pointers, the
+     *  pointed-to memory is not touched in any way.  Managing the pointer is
+     *  the user's responsibilty.
+    */
     void
-    _M_insert_dispatch(iterator __pos, _InputIterator __first,
-                       _InputIterator __last, __false_type)
+    clear() { erase(begin(), end()); }
+  
+  protected:
+    /**
+     *  @if maint
+     *  Memory expansion handler.  Uses the member allocation function to
+     *  obtain @a n bytes of memory, and then copies [first,last) into it.
+     *  @endif
+    */
+    template <typename _ForwardIterator>
+    pointer
+      _M_allocate_and_copy(size_type __n,
+                           _ForwardIterator __first, _ForwardIterator __last)
     {
-      typedef typename iterator_traits<_InputIterator>::iterator_category
-                       _IterCategory;
-      _M_range_insert(__pos, __first, __last, _IterCategory());
+      pointer __result = _M_allocate(__n);
+      try
+        {
+          uninitialized_copy(__first, __last, __result);
+          return __result;
+        }
+      catch(...)
+        {
+       _M_deallocate(__result, __n);
+       __throw_exception_again;
+        }
     }
-
-  // called by the second insert_dispatch above
-  template <typename _InputIterator>
+  
+  
+    // Internal constructor functions follow.
+  
+    // called by the range constructor to implement [23.1.1]/9
+    template<typename _Integer>
+      void
+      _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type)
+      {
+        _M_start = _M_allocate(__n);
+        _M_end_of_storage = _M_start + __n;
+        _M_finish = uninitialized_fill_n(_M_start, __n, __value);
+      }
+  
+    // called by the range constructor to implement [23.1.1]/9
+    template<typename _InputIter>
+      void
+      _M_initialize_dispatch(_InputIter __first, _InputIter __last,
+                            __false_type)
+      {
+        typedef typename iterator_traits<_InputIter>::iterator_category
+                         _IterCategory;
+        _M_range_initialize(__first, __last, _IterCategory());
+      }
+  
+    // called by the second initialize_dispatch above
+    template <typename _InputIterator>
     void
-    _M_range_insert(iterator __pos,
-                    _InputIterator __first, _InputIterator __last,
-                    input_iterator_tag);
-
-  // called by the second insert_dispatch above
-  template <typename _ForwardIterator>
+      _M_range_initialize(_InputIterator __first,
+                          _InputIterator __last, input_iterator_tag)
+    {
+      for ( ; __first != __last; ++__first)
+        push_back(*__first);
+    }
+  
+    // called by the second initialize_dispatch above
+    template <typename _ForwardIterator>
+    void _M_range_initialize(_ForwardIterator __first,
+                             _ForwardIterator __last, forward_iterator_tag)
+    {
+      size_type __n = distance(__first, __last);
+      _M_start = _M_allocate(__n);
+      _M_end_of_storage = _M_start + __n;
+      _M_finish = uninitialized_copy(__first, __last, _M_start);
+    }
+  
+  
+    // Internal assign functions follow.  The *_aux functions do the actual
+    // assignment work for the range versions.
+  
+    // called by the range assign to implement [23.1.1]/9
+    template<typename _Integer>
+      void
+       _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
+       {
+         _M_fill_assign(static_cast<size_type>(__n),
+                        static_cast<value_type>(__val));
+       }
+  
+    // called by the range assign to implement [23.1.1]/9
+    template<typename _InputIter>
+      void
+      _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type)
+      {
+        typedef typename iterator_traits<_InputIter>::iterator_category
+                         _IterCategory;
+        _M_assign_aux(__first, __last, _IterCategory());
+      }
+  
+    // called by the second assign_dispatch above
+    template <typename _InputIterator>
+      void 
+      _M_assign_aux(_InputIterator __first, _InputIterator __last,
+                 input_iterator_tag);
+  
+    // called by the second assign_dispatch above
+    template <typename _ForwardIterator>
+      void 
+      _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
+                 forward_iterator_tag);
+  
+    // Called by assign(n,t), and the range assign when it turns out to be the
+    // same thing.
     void
-    _M_range_insert(iterator __pos,
-                    _ForwardIterator __first, _ForwardIterator __last,
-                    forward_iterator_tag);
-
-  // Called by insert(p,n,x), and the range insert when it turns out to be
-  // the same thing.
-  void
-  _M_fill_insert (iterator __pos, size_type __n, const value_type& __x);
-
-  // called by insert(p,x)
-  void
-  _M_insert_aux(iterator __position, const value_type& __x);
-
-#ifdef _GLIBCPP_DEPRECATED
-  // unused now (same situation as in deque)
-  void _M_insert_aux(iterator __position);
-#endif
-};
-
-
-/**
- *  @brief  Vector equality comparison.
- *  @param  x  A %vector.
- *  @param  y  A %vector of the same type as @a x.
- *  @return  True iff the size and elements of the vectors are equal.
- *
- *  This is an equivalence relation.  It is linear in the size of the
- *  vectors.  Vectors are considered equivalent if their sizes are equal,
- *  and if corresponding elements compare equal.
-*/
-template <typename _Tp, typename _Alloc>
-  inline bool
-  operator==(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
-  {
-    return __x.size() == __y.size() &&
-           equal(__x.begin(), __x.end(), __y.begin());
-  }
-
-/**
- *  @brief  Vector ordering relation.
- *  @param  x  A %vector.
- *  @param  y  A %vector of the same type as @a x.
- *  @return  True iff @a x is lexographically less than @a y.
- *
- *  This is a total ordering relation.  It is linear in the size of the
- *  vectors.  The elements must be comparable with @c <.
- *
- *  See std::lexographical_compare() for how the determination is made.
-*/
-template <typename _Tp, typename _Alloc>
-  inline bool
-  operator<(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
-  {
-    return lexicographical_compare(__x.begin(), __x.end(),
-                                   __y.begin(), __y.end());
-  }
-
-/// Based on operator==
-template <typename _Tp, typename _Alloc>
-  inline bool
-  operator!=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
-  { return !(__x == __y); }
-
-/// Based on operator<
-template <typename _Tp, typename _Alloc>
-  inline bool
-  operator>(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
-  { return __y < __x; }
-
-/// Based on operator<
-template <typename _Tp, typename _Alloc>
-  inline bool
-  operator<=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
-  { return !(__y < __x); }
-
-/// Based on operator<
-template <typename _Tp, typename _Alloc>
-  inline bool
-  operator>=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
-  { return !(__x < __y); }
-
-/// See std::vector::swap().
-template <typename _Tp, typename _Alloc>
-  inline void
-  swap(vector<_Tp,_Alloc>& __x, vector<_Tp,_Alloc>& __y)
-  { __x.swap(__y); }
-
+    _M_fill_assign(size_type __n, const value_type& __val);
+  
+  
+    // Internal insert functions follow.
+  
+    // called by the range insert to implement [23.1.1]/9
+    template<typename _Integer>
+      void
+      _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
+                         __true_type)
+      {
+        _M_fill_insert(__pos, static_cast<size_type>(__n),
+                              static_cast<value_type>(__val));
+      }
+  
+    // called by the range insert to implement [23.1.1]/9
+    template<typename _InputIterator>
+      void
+      _M_insert_dispatch(iterator __pos, _InputIterator __first,
+                         _InputIterator __last, __false_type)
+      {
+        typedef typename iterator_traits<_InputIterator>::iterator_category
+                         _IterCategory;
+        _M_range_insert(__pos, __first, __last, _IterCategory());
+      }
+  
+    // called by the second insert_dispatch above
+    template <typename _InputIterator>
+      void
+      _M_range_insert(iterator __pos,
+                      _InputIterator __first, _InputIterator __last,
+                      input_iterator_tag);
+  
+    // called by the second insert_dispatch above
+    template <typename _ForwardIterator>
+      void
+      _M_range_insert(iterator __pos,
+                      _ForwardIterator __first, _ForwardIterator __last,
+                      forward_iterator_tag);
+  
+    // Called by insert(p,n,x), and the range insert when it turns out to be
+    // the same thing.
+    void
+    _M_fill_insert (iterator __pos, size_type __n, const value_type& __x);
+  
+    // called by insert(p,x)
+    void
+    _M_insert_aux(iterator __position, const value_type& __x);
+  
+  #ifdef _GLIBCPP_DEPRECATED
+    // unused now (same situation as in deque)
+    void _M_insert_aux(iterator __position);
+  #endif
+  };
+  
+  
+  /**
+   *  @brief  Vector equality comparison.
+   *  @param  x  A %vector.
+   *  @param  y  A %vector of the same type as @a x.
+   *  @return  True iff the size and elements of the vectors are equal.
+   *
+   *  This is an equivalence relation.  It is linear in the size of the
+   *  vectors.  Vectors are considered equivalent if their sizes are equal,
+   *  and if corresponding elements compare equal.
+  */
+  template <typename _Tp, typename _Alloc>
+    inline bool
+    operator==(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
+    {
+      return __x.size() == __y.size() &&
+             equal(__x.begin(), __x.end(), __y.begin());
+    }
+  
+  /**
+   *  @brief  Vector ordering relation.
+   *  @param  x  A %vector.
+   *  @param  y  A %vector of the same type as @a x.
+   *  @return  True iff @a x is lexographically less than @a y.
+   *
+   *  This is a total ordering relation.  It is linear in the size of the
+   *  vectors.  The elements must be comparable with @c <.
+   *
+   *  See std::lexographical_compare() for how the determination is made.
+  */
+  template <typename _Tp, typename _Alloc>
+    inline bool
+    operator<(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
+    {
+      return lexicographical_compare(__x.begin(), __x.end(),
+                                     __y.begin(), __y.end());
+    }
+  
+  /// Based on operator==
+  template <typename _Tp, typename _Alloc>
+    inline bool
+    operator!=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
+    { return !(__x == __y); }
+  
+  /// Based on operator<
+  template <typename _Tp, typename _Alloc>
+    inline bool
+    operator>(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
+    { return __y < __x; }
+  
+  /// Based on operator<
+  template <typename _Tp, typename _Alloc>
+    inline bool
+    operator<=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
+    { return !(__y < __x); }
+  
+  /// Based on operator<
+  template <typename _Tp, typename _Alloc>
+    inline bool
+    operator>=(const vector<_Tp,_Alloc>& __x, const vector<_Tp,_Alloc>& __y)
+    { return !(__x < __y); }
+  
+  /// See std::vector::swap().
+  template <typename _Tp, typename _Alloc>
+    inline void
+    swap(vector<_Tp,_Alloc>& __x, vector<_Tp,_Alloc>& __y)
+    { __x.swap(__y); }
 } // namespace std
 
 #endif /* __GLIBCPP_INTERNAL_VECTOR_H */
index d63742f..9b21d0d 100644 (file)
 #ifndef __GLIBCPP_INTERNAL_VECTOR_TCC
 #define __GLIBCPP_INTERNAL_VECTOR_TCC
 
-// Since this entire file is within namespace std, there's no reason to
-// waste two spaces along the left column.  Thus the leading indentation is
-// slightly violated from here on.
 namespace std
 {
-
-template <typename _Tp, typename _Alloc>
-  void
-  vector<_Tp,_Alloc>::
-  reserve(size_type __n)
-  {
-    if (capacity() < __n)
-    {
-      const size_type __old_size = size();
-      pointer __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;
-      _M_finish = __tmp + __old_size;
-      _M_end_of_storage = _M_start + __n;
-    }
-  }
-
-template <typename _Tp, typename _Alloc>
-  typename vector<_Tp,_Alloc>::iterator
-  vector<_Tp,_Alloc>::
-  insert(iterator __position, const value_type& __x)
-  {
-    size_type __n = __position - begin();
-    if (_M_finish != _M_end_of_storage && __position == end())
+  template <typename _Tp, typename _Alloc>
+    void
+    vector<_Tp,_Alloc>::
+    reserve(size_type __n)
     {
-      _Construct(_M_finish, __x);
-      ++_M_finish;
-    }
-    else
-      _M_insert_aux(__position, __x);
-    return begin() + __n;
-  }
-
-template <typename _Tp, typename _Alloc>
-  typename vector<_Tp,_Alloc>::iterator
-  vector<_Tp,_Alloc>::
-  erase(iterator __position)
-  {
-    if (__position + 1 != end())
-      copy(__position + 1, end(), __position);
-    --_M_finish;
-    _Destroy(_M_finish);
-    return __position;
-  }
-
-template <typename _Tp, typename _Alloc>
-  typename vector<_Tp,_Alloc>::iterator
-  vector<_Tp,_Alloc>::
-  erase(iterator __first, iterator __last)
-  {
-    iterator __i(copy(__last, end(), __first));
-    _Destroy(__i, end());
-    _M_finish = _M_finish - (__last - __first);
-    return __first;
-  }
-
-template <typename _Tp, typename _Alloc>
-  vector<_Tp,_Alloc>&
-  vector<_Tp,_Alloc>::
-  operator=(const vector<_Tp,_Alloc>& __x)
-  {
-    if (&__x != this)
-    {
-      const size_type __xlen = __x.size();
-      if (__xlen > capacity())
+      if (capacity() < __n)
       {
-        pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end());
+        const size_type __old_size = size();
+        pointer __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;
-        _M_end_of_storage = _M_start + __xlen;
+        _M_finish = __tmp + __old_size;
+        _M_end_of_storage = _M_start + __n;
       }
-      else if (size() >= __xlen)
+    }
+  
+  template <typename _Tp, typename _Alloc>
+    typename vector<_Tp,_Alloc>::iterator
+    vector<_Tp,_Alloc>::
+    insert(iterator __position, const value_type& __x)
+    {
+      size_type __n = __position - begin();
+      if (_M_finish != _M_end_of_storage && __position == end())
       {
-        iterator __i(copy(__x.begin(), __x.end(), begin()));
-        _Destroy(__i, end());
+        _Construct(_M_finish, __x);
+        ++_M_finish;
       }
       else
-      {
-        copy(__x.begin(), __x.begin() + size(), _M_start);
-        uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish);
-      }
-      _M_finish = _M_start + __xlen;
+        _M_insert_aux(__position, __x);
+      return begin() + __n;
     }
-    return *this;
-  }
-
-template <typename _Tp, typename _Alloc>
-  void
-  vector<_Tp,_Alloc>::
-  _M_fill_assign(size_t __n, const value_type& __val)
-  {
-    if (__n > capacity())
+  
+  template <typename _Tp, typename _Alloc>
+    typename vector<_Tp,_Alloc>::iterator
+    vector<_Tp,_Alloc>::
+    erase(iterator __position)
     {
-      vector __tmp(__n, __val, get_allocator());
-      __tmp.swap(*this);
+      if (__position + 1 != end())
+        copy(__position + 1, end(), __position);
+      --_M_finish;
+      _Destroy(_M_finish);
+      return __position;
     }
-    else if (__n > size())
+  
+  template <typename _Tp, typename _Alloc>
+    typename vector<_Tp,_Alloc>::iterator
+    vector<_Tp,_Alloc>::
+    erase(iterator __first, iterator __last)
     {
-      fill(begin(), end(), __val);
-      _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val);
+      iterator __i(copy(__last, end(), __first));
+      _Destroy(__i, end());
+      _M_finish = _M_finish - (__last - __first);
+      return __first;
     }
-    else
-      erase(fill_n(begin(), __n, __val), end());
-  }
-
-template <typename _Tp, typename _Alloc> template <typename _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)
-      erase(__cur, end());
-    else
-      insert(end(), __first, __last);
-  }
-
-template <typename _Tp, typename _Alloc> template <typename _ForwardIter>
-  void
-  vector<_Tp,_Alloc>::
-  _M_assign_aux(_ForwardIter __first, _ForwardIter __last, forward_iterator_tag)
-  {
-    size_type __len = distance(__first, __last);
-
-    if (__len > capacity())
-    {
-      pointer __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, end());
-      _M_finish = __new_finish.base();
-    }
-    else
+  
+  template <typename _Tp, typename _Alloc>
+    vector<_Tp,_Alloc>&
+    vector<_Tp,_Alloc>::
+    operator=(const vector<_Tp,_Alloc>& __x)
     {
-      _ForwardIter __mid = __first;
-      advance(__mid, size());
-      copy(__first, __mid, _M_start);
-      _M_finish = uninitialized_copy(__mid, __last, _M_finish);
-    }
-  }
-
-template <typename _Tp, typename _Alloc>
-  void
-  vector<_Tp,_Alloc>::
-  _M_insert_aux(iterator __position, const _Tp& __x)
-  {
-    if (_M_finish != _M_end_of_storage)
-    {
-      _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);
-      try
+      if (&__x != this)
+      {
+        const size_type __xlen = __x.size();
+        if (__xlen > capacity())
         {
-          __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);
+          pointer __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;
         }
-      catch(...)
+        else if (size() >= __xlen)
         {
-          _Destroy(__new_start,__new_finish);
-          _M_deallocate(__new_start.base(),__len);
-          __throw_exception_again;
+          iterator __i(copy(__x.begin(), __x.end(), begin()));
+          _Destroy(__i, end());
         }
-      _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;
+        else
+        {
+          copy(__x.begin(), __x.begin() + size(), _M_start);
+          uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish);
+        }
+        _M_finish = _M_start + __xlen;
+      }
+      return *this;
     }
-  }
-
-#ifdef _GLIBCPP_DEPRECATED
-template <typename _Tp, typename _Alloc>
-  void
-  vector<_Tp,_Alloc>::
-  _M_insert_aux(iterator __position)
-  {
-    if (_M_finish != _M_end_of_storage)
+  
+  template <typename _Tp, typename _Alloc>
+    void
+    vector<_Tp,_Alloc>::
+    _M_fill_assign(size_t __n, const value_type& __val)
     {
-      _Construct(_M_finish, *(_M_finish - 1));
-      ++_M_finish;
-      copy_backward(__position, iterator(_M_finish - 2),
-                    iterator(_M_finish - 1));
-      *__position = value_type();
+      if (__n > capacity())
+      {
+        vector __tmp(__n, __val, get_allocator());
+        __tmp.swap(*this);
+      }
+      else if (__n > size())
+      {
+        fill(begin(), end(), __val);
+        _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val);
+      }
+      else
+        erase(fill_n(begin(), __n, __val), end());
     }
-    else
+  
+  template <typename _Tp, typename _Alloc> template <typename _InputIter>
+    void
+    vector<_Tp,_Alloc>::
+    _M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag)
     {
-      const size_type __old_size = size();
-      const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
-      pointer __new_start = _M_allocate(__len);
-      pointer __new_finish = __new_start;
-      try
-        {
-          __new_finish = uninitialized_copy(iterator(_M_start), __position,
-                                            __new_start);
-          _Construct(__new_finish);
-          ++__new_finish;
-          __new_finish = uninitialized_copy(__position, iterator(_M_finish),
-                                            __new_finish);
-        }
-      catch(...)
-        {
-          _Destroy(__new_start,__new_finish);
-          _M_deallocate(__new_start,__len);
-          __throw_exception_again;
-        }
-      _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;
+      iterator __cur(begin());
+      for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
+        *__cur = *__first;
+      if (__first == __last)
+        erase(__cur, end());
+      else
+        insert(end(), __first, __last);
     }
-  }
-#endif
-
-template <typename _Tp, typename _Alloc>
-  void
-  vector<_Tp,_Alloc>::
-  _M_fill_insert(iterator __position, size_type __n, const value_type& __x)
-  {
-    if (__n != 0)
+  
+  template <typename _Tp, typename _Alloc> template <typename _ForwardIter>
+    void
+    vector<_Tp,_Alloc>::
+    _M_assign_aux(_ForwardIter __first, _ForwardIter __last,
+                  forward_iterator_tag)
     {
-      if (size_type(_M_end_of_storage - _M_finish) >= __n) {
-        value_type __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;
-          copy_backward(__position, __old_finish - __n, __old_finish);
-          fill(__position, __position + __n, __x_copy);
-        }
-        else
-        {
-          uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy);
-          _M_finish += __n - __elems_after;
-          uninitialized_copy(__position, __old_finish, _M_finish);
-          _M_finish += __elems_after;
-          fill(__position, __old_finish, __x_copy);
-        }
+      size_type __len = distance(__first, __last);
+  
+      if (__len > capacity())
+      {
+        pointer __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, end());
+        _M_finish = __new_finish.base();
+      }
+      else
+      {
+        _ForwardIter __mid = __first;
+        advance(__mid, size());
+        copy(__first, __mid, _M_start);
+        _M_finish = uninitialized_copy(__mid, __last, _M_finish);
+      }
+    }
+  
+  template <typename _Tp, typename _Alloc>
+    void
+    vector<_Tp,_Alloc>::
+    _M_insert_aux(iterator __position, const _Tp& __x)
+    {
+      if (_M_finish != _M_end_of_storage)
+      {
+        _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 + max(__old_size, __n);
+        const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
         iterator __new_start(_M_allocate(__len));
         iterator __new_finish(__new_start);
         try
           {
-            __new_finish = uninitialized_copy(begin(), __position, __new_start);
-            __new_finish = uninitialized_fill_n(__new_finish, __n, __x);
-            __new_finish
-              = uninitialized_copy(__position, end(), __new_finish);
+            __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);
           }
         catch(...)
           {
@@ -349,91 +248,188 @@ template <typename _Tp, typename _Alloc>
             _M_deallocate(__new_start.base(),__len);
             __throw_exception_again;
           }
-        _Destroy(_M_start, _M_finish);
+        _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;
       }
     }
-  }
-
-template <typename _Tp, typename _Alloc> template <typename _InputIterator>
-  void
-  vector<_Tp,_Alloc>::
-  _M_range_insert(iterator __pos,
-                  _InputIterator __first, _InputIterator __last,
-                  input_iterator_tag)
-  {
-    for ( ; __first != __last; ++__first)
-    {
-      __pos = insert(__pos, *__first);
-      ++__pos;
-    }
-  }
-
-template <typename _Tp, typename _Alloc> template <typename _ForwardIterator>
-  void
-  vector<_Tp,_Alloc>::
-  _M_range_insert(iterator __position,
-                  _ForwardIterator __first, _ForwardIterator __last,
-                  forward_iterator_tag)
-  {
-    if (__first != __last)
+  
+  #ifdef _GLIBCPP_DEPRECATED
+  template <typename _Tp, typename _Alloc>
+    void
+    vector<_Tp,_Alloc>::
+    _M_insert_aux(iterator __position)
     {
-      size_type __n = distance(__first, __last);
-      if (size_type(_M_end_of_storage - _M_finish) >= __n)
+      if (_M_finish != _M_end_of_storage)
       {
-        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;
-          copy_backward(__position, __old_finish - __n, __old_finish);
-          copy(__first, __last, __position);
-        }
-        else
-        {
-          _ForwardIterator __mid = __first;
-          advance(__mid, __elems_after);
-          uninitialized_copy(__mid, __last, _M_finish);
-          _M_finish += __n - __elems_after;
-          uninitialized_copy(__position, __old_finish, _M_finish);
-          _M_finish += __elems_after;
-          copy(__first, __mid, __position);
-        }
+        _Construct(_M_finish, *(_M_finish - 1));
+        ++_M_finish;
+        copy_backward(__position, iterator(_M_finish - 2),
+                      iterator(_M_finish - 1));
+        *__position = value_type();
       }
       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);
+        const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
+        pointer __new_start = _M_allocate(__len);
+        pointer __new_finish = __new_start;
         try
           {
-            __new_finish = uninitialized_copy(iterator(_M_start),
-                                              __position, __new_start);
-            __new_finish = uninitialized_copy(__first, __last, __new_finish);
+            __new_finish = uninitialized_copy(iterator(_M_start), __position,
+                                              __new_start);
+            _Construct(__new_finish);
+            ++__new_finish;
             __new_finish = uninitialized_copy(__position, iterator(_M_finish),
                                               __new_finish);
           }
         catch(...)
           {
             _Destroy(__new_start,__new_finish);
-            _M_deallocate(__new_start.base(), __len);
+            _M_deallocate(__new_start,__len);
             __throw_exception_again;
           }
-        _Destroy(_M_start, _M_finish);
+        _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;
+        _M_start = __new_start;
+        _M_finish = __new_finish;
+        _M_end_of_storage = __new_start + __len;
+      }
+    }
+  #endif
+  
+  template <typename _Tp, typename _Alloc>
+    void
+    vector<_Tp,_Alloc>::
+    _M_fill_insert(iterator __position, size_type __n, const value_type& __x)
+    {
+      if (__n != 0)
+      {
+        if (size_type(_M_end_of_storage - _M_finish) >= __n) {
+          value_type __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;
+            copy_backward(__position, __old_finish - __n, __old_finish);
+            fill(__position, __position + __n, __x_copy);
+          }
+          else
+          {
+            uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy);
+            _M_finish += __n - __elems_after;
+            uninitialized_copy(__position, __old_finish, _M_finish);
+            _M_finish += __elems_after;
+            fill(__position, __old_finish, __x_copy);
+          }
+        }
+        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);
+          try
+            {
+              __new_finish = uninitialized_copy(begin(), __position,
+                                                __new_start);
+              __new_finish = uninitialized_fill_n(__new_finish, __n, __x);
+              __new_finish
+                = uninitialized_copy(__position, end(), __new_finish);
+            }
+          catch(...)
+            {
+              _Destroy(__new_start,__new_finish);
+              _M_deallocate(__new_start.base(),__len);
+              __throw_exception_again;
+            }
+          _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;
+        }
+      }
+    }
+  
+  template <typename _Tp, typename _Alloc> template <typename _InputIterator>
+    void
+    vector<_Tp,_Alloc>::
+    _M_range_insert(iterator __pos,
+                    _InputIterator __first, _InputIterator __last,
+                    input_iterator_tag)
+    {
+      for ( ; __first != __last; ++__first)
+      {
+        __pos = insert(__pos, *__first);
+        ++__pos;
+      }
+    }
+  
+  template <typename _Tp, typename _Alloc> template <typename _ForwardIterator>
+    void
+    vector<_Tp,_Alloc>::
+    _M_range_insert(iterator __position,
+                    _ForwardIterator __first, _ForwardIterator __last,
+                    forward_iterator_tag)
+    {
+      if (__first != __last)
+      {
+        size_type __n = distance(__first, __last);
+        if (size_type(_M_end_of_storage - _M_finish) >= __n)
+        {
+          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;
+            copy_backward(__position, __old_finish - __n, __old_finish);
+            copy(__first, __last, __position);
+          }
+          else
+          {
+            _ForwardIterator __mid = __first;
+            advance(__mid, __elems_after);
+            uninitialized_copy(__mid, __last, _M_finish);
+            _M_finish += __n - __elems_after;
+            uninitialized_copy(__position, __old_finish, _M_finish);
+            _M_finish += __elems_after;
+            copy(__first, __mid, __position);
+          }
+        }
+        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);
+          try
+            {
+              __new_finish = uninitialized_copy(iterator(_M_start),
+                                                __position, __new_start);
+              __new_finish = uninitialized_copy(__first, __last, __new_finish);
+              __new_finish = uninitialized_copy(__position, iterator(_M_finish),
+                                                __new_finish);
+            }
+          catch(...)
+            {
+              _Destroy(__new_start,__new_finish);
+              _M_deallocate(__new_start.base(), __len);
+              __throw_exception_again;
+            }
+          _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;
+        }
       }
     }
-  }
-
 } // namespace std
 
 #endif /* __GLIBCPP_INTERNAL_VECTOR_TCC */
-