Makefile.in (install): Some of HEADERS come from the stl dir now.
authorJason Merrill <jason@yorick.cygnus.com>
Sun, 2 Nov 1997 20:28:22 +0000 (20:28 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 2 Nov 1997 20:28:22 +0000 (15:28 -0500)
* Makefile.in (install): Some of HEADERS come from the stl dir now.
* algorithm, deque, functional, iterator, list, map, memory, numeric,
  queue, set, stack, utility, vector: Now in stl dir.

stl/:
* algo.h, algobase.h, alloc.h, bvector.h, defalloc.h, deque.h,
  function.h, hash_map.h, hash_set.h, hashtable.h, heap.h, iterator.h,
  list.h, map.h, multimap.h, multiset.h, pair.h, pthread_alloc.h,
  rope.h, ropeimpl.h, set.h, slist.h, stack.h, stl_config.h, tempbuf.h,
  tree.h, type_traits.h, vector.h: Update to October 27 SGI snapshot.
* algorithm, deque, functional, hash_map, hash_set, iterator, list,
  map, memory, numeric, pthread_alloc, queue, rope, set, slist, stack,
  stl_algo.h, stl_algobase.h, stl_alloc.h, stl_bvector.h,
  stl_construct.h, stl_deque.h, stl_function.h, stl_hash_fun.h,
  stl_hash_map.h, stl_hash_set.h, stl_hashtable.h, stl_heap.h,
  stl_iterator.h, stl_list.h, stl_map.h, stl_multimap.h, stl_multiset.h,
  stl_numeric.h, stl_pair.h, stl_queue.h, stl_raw_storage_iter.h,
  stl_relops.h, stl_rope.h, stl_set.h, stl_slist.h, stl_stack.h,
  stl_tempbuf.h, stl_tree.h, stl_uninitialized.h, stl_vector.h,
  utility, vector: New files in October 27 SGI snapshot.

From-SVN: r16277

92 files changed:
libstdc++/ChangeLog
libstdc++/Makefile.in
libstdc++/algorithm [deleted file]
libstdc++/deque [deleted file]
libstdc++/functional [deleted file]
libstdc++/iterator [deleted file]
libstdc++/list [deleted file]
libstdc++/map [deleted file]
libstdc++/memory [deleted file]
libstdc++/numeric [deleted file]
libstdc++/queue [deleted file]
libstdc++/set [deleted file]
libstdc++/stack [deleted file]
libstdc++/stl/ChangeLog
libstdc++/stl/algo.h
libstdc++/stl/algobase.h
libstdc++/stl/algorithm [new file with mode: 0644]
libstdc++/stl/alloc.h
libstdc++/stl/bvector.h
libstdc++/stl/defalloc.h
libstdc++/stl/deque [new file with mode: 0644]
libstdc++/stl/deque.h
libstdc++/stl/function.h
libstdc++/stl/functional [new file with mode: 0644]
libstdc++/stl/hash_map [new file with mode: 0644]
libstdc++/stl/hash_map.h
libstdc++/stl/hash_set [new file with mode: 0644]
libstdc++/stl/hash_set.h
libstdc++/stl/hashtable.h
libstdc++/stl/heap.h
libstdc++/stl/iterator [new file with mode: 0644]
libstdc++/stl/iterator.h
libstdc++/stl/list [new file with mode: 0644]
libstdc++/stl/list.h
libstdc++/stl/map [new file with mode: 0644]
libstdc++/stl/map.h
libstdc++/stl/memory [new file with mode: 0644]
libstdc++/stl/multimap.h
libstdc++/stl/multiset.h
libstdc++/stl/numeric [new file with mode: 0644]
libstdc++/stl/pair.h
libstdc++/stl/pthread_alloc [new file with mode: 0644]
libstdc++/stl/pthread_alloc.h
libstdc++/stl/queue [new file with mode: 0644]
libstdc++/stl/rope [new file with mode: 0644]
libstdc++/stl/rope.h
libstdc++/stl/ropeimpl.h
libstdc++/stl/set [new file with mode: 0644]
libstdc++/stl/set.h
libstdc++/stl/slist [new file with mode: 0644]
libstdc++/stl/slist.h
libstdc++/stl/stack [new file with mode: 0644]
libstdc++/stl/stack.h
libstdc++/stl/stl_algo.h [new file with mode: 0644]
libstdc++/stl/stl_algobase.h [new file with mode: 0644]
libstdc++/stl/stl_alloc.h [new file with mode: 0644]
libstdc++/stl/stl_bvector.h [new file with mode: 0644]
libstdc++/stl/stl_config.h
libstdc++/stl/stl_construct.h [new file with mode: 0644]
libstdc++/stl/stl_deque.h [new file with mode: 0644]
libstdc++/stl/stl_function.h [new file with mode: 0644]
libstdc++/stl/stl_hash_fun.h [new file with mode: 0644]
libstdc++/stl/stl_hash_map.h [new file with mode: 0644]
libstdc++/stl/stl_hash_set.h [new file with mode: 0644]
libstdc++/stl/stl_hashtable.h [new file with mode: 0644]
libstdc++/stl/stl_heap.h [new file with mode: 0644]
libstdc++/stl/stl_iterator.h [new file with mode: 0644]
libstdc++/stl/stl_list.h [new file with mode: 0644]
libstdc++/stl/stl_map.h [new file with mode: 0644]
libstdc++/stl/stl_multimap.h [new file with mode: 0644]
libstdc++/stl/stl_multiset.h [new file with mode: 0644]
libstdc++/stl/stl_numeric.h [new file with mode: 0644]
libstdc++/stl/stl_pair.h [new file with mode: 0644]
libstdc++/stl/stl_queue.h [new file with mode: 0644]
libstdc++/stl/stl_raw_storage_iter.h [new file with mode: 0644]
libstdc++/stl/stl_relops.h [new file with mode: 0644]
libstdc++/stl/stl_rope.h [new file with mode: 0644]
libstdc++/stl/stl_set.h [new file with mode: 0644]
libstdc++/stl/stl_slist.h [new file with mode: 0644]
libstdc++/stl/stl_stack.h [new file with mode: 0644]
libstdc++/stl/stl_tempbuf.h [new file with mode: 0644]
libstdc++/stl/stl_tree.h [new file with mode: 0644]
libstdc++/stl/stl_uninitialized.h [new file with mode: 0644]
libstdc++/stl/stl_vector.h [new file with mode: 0644]
libstdc++/stl/tempbuf.h
libstdc++/stl/tree.h
libstdc++/stl/type_traits.h
libstdc++/stl/utility [new file with mode: 0644]
libstdc++/stl/vector [new file with mode: 0644]
libstdc++/stl/vector.h
libstdc++/utility [deleted file]
libstdc++/vector [deleted file]

index a1bf0a4..cf4d2eb 100644 (file)
@@ -1,7 +1,13 @@
+Sun Nov  2 12:14:37 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * Makefile.in (install): Some of HEADERS come from the stl dir now.
+       * algorithm, deque, functional, iterator, list, map, memory, numeric,
+       queue, set, stack, utility, vector: Now in stl dir.
+
 Fri Oct 10 00:40:00 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
        * std/bastring.h: Use ibegin internally.  Return passed iterator
-       instead of recalculating it were appropriate.
+       instead of recalculating it where appropriate.
        * std/bastring.cc: Adjust for erase.
 
        From Yotam Medini:
index c8f7b14..1cd2a6f 100644 (file)
@@ -248,7 +248,16 @@ install:
        rootme=`pwd`/ ; export rootme ; \
        if [ -z "$(MULTISUBDIR)" ]; then \
          cd $(srcdir); \
-         for FILE in $(HEADERS) *.h std/*.*; do \
+         for FILE in $(HEADERS); do \
+           rm -f $(gxx_includedir)/$$FILE ; \
+           if [ -f stl/$$FILE ]; then \
+             $(INSTALL_DATA) stl/$$FILE $(gxx_includedir)/$$FILE ; \
+           else \
+             $(INSTALL_DATA) $$FILE $(gxx_includedir)/$$FILE ; \
+           fi ; \
+           chmod a-x $(gxx_includedir)/$$FILE ; \
+         done ; \
+         for FILE in *.h std/*.*; do \
            rm -f $(gxx_includedir)/$$FILE ; \
            $(INSTALL_DATA) $$FILE $(gxx_includedir)/$$FILE ; \
            chmod a-x $(gxx_includedir)/$$FILE ; \
diff --git a/libstdc++/algorithm b/libstdc++/algorithm
deleted file mode 100644 (file)
index 472d241..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// -*- C++ -*- forwarding header.
-// This file is part of the GNU ANSI C++ Library.
-
-#ifndef __ALGORITHM__
-#define __ALGORITHM__
-#include <algo.h>
-#endif
diff --git a/libstdc++/deque b/libstdc++/deque
deleted file mode 100644 (file)
index bdc1429..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// -*- C++ -*- forwarding header.
-// This file is part of the GNU ANSI C++ Library.
-
-#ifndef __DEQUE__
-#define __DEQUE__
-#include <deque.h>
-#endif
diff --git a/libstdc++/functional b/libstdc++/functional
deleted file mode 100644 (file)
index ee8b7f2..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// -*- C++ -*- forwarding header.
-// This file is part of the GNU ANSI C++ Library.
-
-#ifndef __FUNCTIONAL__
-#define __FUNCTIONAL__
-#include <function.h>
-#endif
diff --git a/libstdc++/iterator b/libstdc++/iterator
deleted file mode 100644 (file)
index a0fa054..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// -*- C++ -*- forwarding header.
-// This file is part of the GNU ANSI C++ Library.
-
-#ifndef __ITERATOR__
-#define __ITERATOR__
-#include <iterator.h>
-#endif
diff --git a/libstdc++/list b/libstdc++/list
deleted file mode 100644 (file)
index 475d844..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// -*- C++ -*- forwarding header.
-// This file is part of the GNU ANSI C++ Library.
-
-#ifndef __LIST__
-#define __LIST__
-#include <list.h>
-#endif
diff --git a/libstdc++/map b/libstdc++/map
deleted file mode 100644 (file)
index 0127b9d..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// -*- C++ -*- forwarding header.
-// This file is part of the GNU ANSI C++ Library.
-
-#ifndef __MAP__
-#define __MAP__
-#include <map.h>
-#endif
diff --git a/libstdc++/memory b/libstdc++/memory
deleted file mode 100644 (file)
index 8328720..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// -*- C++ -*- forwarding header.
-// This file is part of the GNU ANSI C++ Library.
-
-#ifndef __MEMORY__
-#define __MEMORY__
-#include <defalloc.h>
-#endif
diff --git a/libstdc++/numeric b/libstdc++/numeric
deleted file mode 100644 (file)
index dcb8873..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// -*- C++ -*- forwarding header.
-// This file is part of the GNU ANSI C++ Library.
-
-#ifndef __NUMERIC__
-#define __NUMERIC__
-#include <algo.h>
-#endif
diff --git a/libstdc++/queue b/libstdc++/queue
deleted file mode 100644 (file)
index e71ce34..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// -*- C++ -*- forwarding header.
-// This file is part of the GNU ANSI C++ Library.
-
-#ifndef __QUEUE__
-#define __QUEUE__
-#include <stack.h>
-#endif
diff --git a/libstdc++/set b/libstdc++/set
deleted file mode 100644 (file)
index 0353285..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// -*- C++ -*- forwarding header.
-// This file is part of the GNU ANSI C++ Library.
-
-#ifndef __SET__
-#define __SET__
-#include <set.h>
-#endif
diff --git a/libstdc++/stack b/libstdc++/stack
deleted file mode 100644 (file)
index dfe0c51..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// -*- C++ -*- forwarding header.
-// This file is part of the GNU ANSI C++ Library.
-
-#ifndef __STACK__
-#define __STACK__
-#include <stack.h>
-#endif
index ca1c01a..7d0c62a 100644 (file)
@@ -1,3 +1,21 @@
+Sun Nov  2 12:14:56 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * algo.h, algobase.h, alloc.h, bvector.h, defalloc.h, deque.h,
+       function.h, hash_map.h, hash_set.h, hashtable.h, heap.h, iterator.h,
+       list.h, map.h, multimap.h, multiset.h, pair.h, pthread_alloc.h,
+       rope.h, ropeimpl.h, set.h, slist.h, stack.h, stl_config.h, tempbuf.h,
+       tree.h, type_traits.h, vector.h: Update to October 27 SGI snapshot.
+       * algorithm, deque, functional, hash_map, hash_set, iterator, list,
+       map, memory, numeric, pthread_alloc, queue, rope, set, slist, stack,
+       stl_algo.h, stl_algobase.h, stl_alloc.h, stl_bvector.h,
+       stl_construct.h, stl_deque.h, stl_function.h, stl_hash_fun.h,
+       stl_hash_map.h, stl_hash_set.h, stl_hashtable.h, stl_heap.h,
+       stl_iterator.h, stl_list.h, stl_map.h, stl_multimap.h, stl_multiset.h,
+       stl_numeric.h, stl_pair.h, stl_queue.h, stl_raw_storage_iter.h,
+       stl_relops.h, stl_rope.h, stl_set.h, stl_slist.h, stl_stack.h,
+       stl_tempbuf.h, stl_tree.h, stl_uninitialized.h, stl_vector.h,
+       utility, vector: New files in October 27 SGI snapshot.
+
 Fri Oct 17 19:07:42 1997  Jason Merrill  <jason@yorick.cygnus.com>
 
        * tree.h, vector.h: Fix accidental divergence from SGI release.
index 2f14289..1707868 100644 (file)
@@ -12,7 +12,7 @@
  * purpose.  It is provided "as is" without express or implied warranty.
  *
  *
- * Copyright (c) 1996
+ * Copyright (c) 1996,1997
  * Silicon Graphics Computer Systems, Inc.
  *
  * Permission to use, copy, modify, distribute and sell this software
 #ifndef __SGI_STL_ALGO_H
 #define __SGI_STL_ALGO_H
 
-#include <stdlib.h>
-#include <limits.h>
 #include <algobase.h>
-#include <heap.h>
 #include <tempbuf.h>
-
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-#pragma set woff 1209
-#endif
-
-template <class T>
-inline const T& __median(const T& a, const T& b, const T& c) {
-    if (a < b)
-       if (b < c)
-           return b;
-       else if (a < c)
-           return c;
-       else
-           return a;
-    else if (a < c)
-       return a;
-    else if (b < c)
-       return c;
-    else
-       return b;
-}
-
-template <class T, class Compare>
-inline const T& __median(const T& a, const T& b, const T& c, Compare comp) {
-    if (comp(a, b))
-       if (comp(b, c))
-           return b;
-       else if (comp(a, c))
-           return c;
-       else
-           return a;
-    else if (comp(a, c))
-       return a;
-    else if (comp(b, c))
-       return c;
-    else
-       return b;
-}
-
-template <class InputIterator, class Function>
-Function for_each(InputIterator first, InputIterator last, Function f) {
-  for ( ; first != last; ++first)
-    f(*first);
-  return f;
-}
-
-template <class InputIterator, class T>
-InputIterator find(InputIterator first, InputIterator last, const T& value) {
-    while (first != last && *first != value) ++first;
-    return first;
-}
-
-template <class InputIterator, class Predicate>
-InputIterator find_if(InputIterator first, InputIterator last,
-                     Predicate pred) {
-    while (first != last && !pred(*first)) ++first;
-    return first;
-}
-
-template <class ForwardIterator>
-ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last) {
-    if (first == last) return last;
-    ForwardIterator next = first;
-    while(++next != last) {
-       if (*first == *next) return first;
-       first = next;
-    }
-    return last;
-}
-
-template <class ForwardIterator, class BinaryPredicate>
-ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last,
-                             BinaryPredicate binary_pred) {
-    if (first == last) return last;
-    ForwardIterator next = first;
-    while(++next != last) {
-       if (binary_pred(*first, *next)) return first;
-       first = next;
-    }
-    return last;
-}
-
-template <class InputIterator, class T, class Size>
-void count(InputIterator first, InputIterator last, const T& value,
-          Size& n) {
-  for ( ; first != last; ++first)
-    if (*first == value)
-      ++n;
-}
-
-template <class InputIterator, class Predicate, class Size>
-void count_if(InputIterator first, InputIterator last, Predicate pred,
-             Size& n) {
-  for ( ; first != last; ++first)
-    if (pred(*first))
-      ++n;
-}
-
-#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-template <class InputIterator, class T>
-iterator_traits<InputIterator>::difference_type
-count(InputIterator first, InputIterator last, const T& value) {
-  iterator_traits<InputIterator>::difference_type n = 0;
-  for ( ; first != last; ++first)
-    if (*first == value)
-      ++n;
-  return n;
-}
-
-template <class InputIterator, class Predicate>
-iterator_traits<InputIterator>::difference_type
-count_if(InputIterator first, InputIterator last, Predicate pred) {
-  iterator_traits<InputIterator>::difference_type n = 0;
-  for ( ; first != last; ++first)
-    if (pred(*first))
-      ++n;
-  return n;
-}
-
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-template <class ForwardIterator1, class ForwardIterator2, class Distance1,
-          class Distance2>
-ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1,
-                          ForwardIterator2 first2, ForwardIterator2 last2,
-                          Distance1*, Distance2*) {
-  Distance1 d1 = 0;
-  distance(first1, last1, d1);
-  Distance2 d2 = 0;
-  distance(first2, last2, d2);
-
-  if (d1 < d2) return last1;
-
-  ForwardIterator1 current1 = first1;
-  ForwardIterator2 current2 = first2;
-
-  while (current2 != last2) 
-    if (*current1 == *current2) {
-      ++current1;
-      ++current2;
-    }
-    else {
-      if (d1 == d2)
-        return last1;
-      else {
-        current1 = ++first1;
-        current2 = first2;
-        --d1;
-      }
-    }
-  return first1;
-}
-
-template <class ForwardIterator1, class ForwardIterator2>
-inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
-                              ForwardIterator2 first2, ForwardIterator2 last2)
-{
-    return __search(first1, last1, first2, last2, distance_type(first1),
-                   distance_type(first2));
-}
-
-template <class ForwardIterator1, class ForwardIterator2,
-          class BinaryPredicate, class Distance1, class Distance2>
-ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1,
-                          ForwardIterator2 first2, ForwardIterator2 last2,
-                          BinaryPredicate binary_pred, Distance1*, Distance2*) {
-  Distance1 d1 = 0;
-  distance(first1, last1, d1);
-  Distance2 d2 = 0;
-  distance(first2, last2, d2);
-
-  if (d1 < d2) return last1;
-
-  ForwardIterator1 current1 = first1;
-  ForwardIterator2 current2 = first2;
-
-  while (current2 != last2)
-    if (binary_pred(*current1, *current2)) {
-      ++current1;
-      ++current2;
-    }
-    else {
-      if (d1 == d2)
-        return last1;
-      else {
-        current1 = ++first1;
-        current2 = first2;
-        --d1;
-      }
-    }
-  return first1;
-}
-
-template <class ForwardIterator1, class ForwardIterator2,
-         class BinaryPredicate>
-inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
-                              ForwardIterator2 first2, ForwardIterator2 last2,
-                              BinaryPredicate binary_pred) {
-    return __search(first1, last1, first2, last2, binary_pred,
-                   distance_type(first1), distance_type(first2));
-}
-
-template <class ForwardIterator, class Integer, class T>
-ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
-                         Integer count, const T& value) {
-  if (count <= 0)
-    return first;
-  else {
-    first = find(first, last, value);
-    while (first != last) {
-      Integer n = count - 1;
-      ForwardIterator i = first;
-      ++i;
-      while (i != last && n != 0 && *i == value) {
-        ++i;
-        --n;
-      }
-      if (n == 0)
-        return first;
-      else
-        first = find(i, last, value);
-    }
-    return last;
-  }
-}
-
-template <class ForwardIterator, class Integer, class T, class BinaryPredicate>
-ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
-                         Integer count, const T& value,
-                         BinaryPredicate binary_pred) {
-  if (count <= 0)
-    return first;
-  else {
-    while (first != last) {
-      if (binary_pred(*first, value)) break;
-      ++first;
-    }
-    while (first != last) {
-      Integer n = count - 1;
-      ForwardIterator i = first;
-      ++i;
-      while (i != last && n != 0 && binary_pred(*i, value)) {
-        ++i;
-        --n;
-      }
-      if (n == 0)
-        return first;
-      else {
-        while (i != last) {
-          if (binary_pred(*i, value)) break;
-          ++i;
-        }
-        first = i;
-      }
-    }
-    return last;
-  }
-} 
-
-template <class ForwardIterator1, class ForwardIterator2>
-ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1,
-                            ForwardIterator2 first2) {
-  for ( ; first1 != last1; ++first1, ++first2)
-    iter_swap(first1, first2);
-  return first2;
-}
-
-template <class InputIterator, class OutputIterator, class UnaryOperation>
-OutputIterator transform(InputIterator first, InputIterator last,
-                        OutputIterator result, UnaryOperation op) {
-  for ( ; first != last; ++first, ++result)
-    *result = op(*first);
-  return result;
-}
-
-template <class InputIterator1, class InputIterator2, class OutputIterator,
-         class BinaryOperation>
-OutputIterator transform(InputIterator1 first1, InputIterator1 last1,
-                        InputIterator2 first2, OutputIterator result,
-                        BinaryOperation binary_op) {
-  for ( ; first1 != last1; ++first1, ++first2, ++result)
-    *result = binary_op(*first1, *first2);
-  return result;
-}
-
-template <class ForwardIterator, class T>
-void replace(ForwardIterator first, ForwardIterator last, const T& old_value,
-            const T& new_value) {
-  for ( ; first != last; ++first)
-    if (*first == old_value) *first = new_value;
-}
-
-template <class ForwardIterator, class Predicate, class T>
-void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred,
-               const T& new_value) {
-  for ( ; first != last; ++first)
-    if (pred(*first)) *first = new_value;
-}
-
-template <class InputIterator, class OutputIterator, class T>
-OutputIterator replace_copy(InputIterator first, InputIterator last,
-                           OutputIterator result, const T& old_value,
-                           const T& new_value) {
-  for ( ; first != last; ++first, ++result)
-    *result = *first == old_value ? new_value : *first;
-  return result;
-}
-
-template <class Iterator, class OutputIterator, class Predicate, class T>
-OutputIterator replace_copy_if(Iterator first, Iterator last,
-                              OutputIterator result, Predicate pred,
-                              const T& new_value) {
-  for ( ; first != last; ++first, ++result)
-    *result = pred(*first) ? new_value : *first;
-  return result;
-}
-
-template <class ForwardIterator, class Generator>
-void generate(ForwardIterator first, ForwardIterator last, Generator gen) {
-  for ( ; first != last; ++first)
-    *first = gen();
-}
-
-template <class OutputIterator, class Size, class Generator>
-OutputIterator generate_n(OutputIterator first, Size n, Generator gen) {
-  for ( ; n > 0; --n, ++first)
-    *first = gen();
-  return first;
-}
-
-template <class InputIterator, class OutputIterator, class T>
-OutputIterator remove_copy(InputIterator first, InputIterator last,
-                           OutputIterator result, const T& value) {
-  for ( ; first != last; ++first)
-    if (*first != value) {
-      *result = *first;
-      ++result;
-    }
-  return result;
-}
-
-template <class InputIterator, class OutputIterator, class Predicate>
-OutputIterator remove_copy_if(InputIterator first, InputIterator last,
-                              OutputIterator result, Predicate pred) {
-  for ( ; first != last; ++first)
-    if (!pred(*first)) {
-      *result = *first;
-      ++result;
-    }
-  return result;
-}
-
-template <class ForwardIterator, class T>
-ForwardIterator remove(ForwardIterator first, ForwardIterator last,
-                      const T& value) {
-    first = find(first, last, value);
-    ForwardIterator next = first;
-    return first == last ? first : remove_copy(++next, last, first, value);
-}
-
-template <class ForwardIterator, class Predicate>
-ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
-                         Predicate pred) {
-    first = find_if(first, last, pred);
-    ForwardIterator next = first;
-    return first == last ? first : remove_copy_if(++next, last, first, pred);
-}
-
-template <class InputIterator, class ForwardIterator>
-ForwardIterator __unique_copy(InputIterator first, InputIterator last,
-                             ForwardIterator result, forward_iterator_tag) {
-    *result = *first;
-    while (++first != last)
-        if (*result != *first) *++result = *first;
-    return ++result;
-}
-
-template <class InputIterator, class BidirectionalIterator>
-inline BidirectionalIterator __unique_copy(InputIterator first, 
-                                          InputIterator last,
-                                          BidirectionalIterator result, 
-                                          bidirectional_iterator_tag) {
-    return __unique_copy(first, last, result, forward_iterator_tag());
-}
-
-template <class InputIterator, class RandomAccessIterator>
-inline RandomAccessIterator __unique_copy(InputIterator first, 
-                                         InputIterator last,
-                                         RandomAccessIterator result, 
-                                         random_access_iterator_tag) {
-    return __unique_copy(first, last, result, forward_iterator_tag());
-}
-
-template <class InputIterator, class OutputIterator, class T>
-OutputIterator __unique_copy(InputIterator first, InputIterator last,
-                            OutputIterator result, T*) {
-    T value = *first;
-    *result = value;
-    while (++first != last)
-       if (value != *first) {
-           value = *first;
-           *++result = value;
-       }
-    return ++result;
-}
-
-template <class InputIterator, class OutputIterator>
-inline OutputIterator __unique_copy(InputIterator first, InputIterator last,
-                                   OutputIterator result, 
-                                   output_iterator_tag) {
-    return __unique_copy(first, last, result, value_type(first));
-}
-
-template <class InputIterator, class OutputIterator>
-inline OutputIterator unique_copy(InputIterator first, InputIterator last,
-                                 OutputIterator result) {
-    if (first == last) return result;
-    return __unique_copy(first, last, result, iterator_category(result));
-}
-template <class InputIterator, class ForwardIterator, class BinaryPredicate>
-ForwardIterator __unique_copy(InputIterator first, InputIterator last,
-                             ForwardIterator result, 
-                             BinaryPredicate binary_pred,
-                             forward_iterator_tag) {
-    *result = *first;
-    while (++first != last)
-        if (!binary_pred(*result, *first)) *++result = *first;
-    return ++result;
-}
-
-template <class InputIterator, class BidirectionalIterator,
-          class BinaryPredicate>
-inline BidirectionalIterator __unique_copy(InputIterator first, 
-                                          InputIterator last,
-                                          BidirectionalIterator result, 
-                                          BinaryPredicate binary_pred,
-                                          bidirectional_iterator_tag) {
-    return __unique_copy(first, last, result, binary_pred,
-                        forward_iterator_tag());
-}
-
-template <class InputIterator, class RandomAccessIterator,
-          class BinaryPredicate>
-inline RandomAccessIterator __unique_copy(InputIterator first, 
-                                         InputIterator last,
-                                         RandomAccessIterator result, 
-                                         BinaryPredicate binary_pred,
-                                         random_access_iterator_tag) {
-    return __unique_copy(first, last, result, binary_pred, 
-                        forward_iterator_tag());
-}
-
-template <class InputIterator, class OutputIterator, class BinaryPredicate,
-          class T>
-OutputIterator __unique_copy(InputIterator first, InputIterator last,
-                            OutputIterator result,
-                            BinaryPredicate binary_pred, T*) {
-    T value = *first;
-    *result = value;
-    while (++first != last)
-       if (!binary_pred(value, *first)) {
-           value = *first;
-           *++result = value;
-       }
-    return ++result;
-}
-
-template <class InputIterator, class OutputIterator, class BinaryPredicate>
-inline OutputIterator __unique_copy(InputIterator first, InputIterator last,
-                                   OutputIterator result,
-                                   BinaryPredicate binary_pred,
-                                   output_iterator_tag) {
-    return __unique_copy(first, last, result, binary_pred, value_type(first));
-}
-
-template <class InputIterator, class OutputIterator, class BinaryPredicate>
-inline OutputIterator unique_copy(InputIterator first, InputIterator last,
-                                 OutputIterator result,
-                                 BinaryPredicate binary_pred) {
-    if (first == last) return result;
-    return __unique_copy(first, last, result, binary_pred,
-                        iterator_category(result));
-}
-
-template <class ForwardIterator>
-ForwardIterator unique(ForwardIterator first, ForwardIterator last) {
-    first = adjacent_find(first, last);
-    return unique_copy(first, last, first);
-}
-
-template <class ForwardIterator, class BinaryPredicate>
-ForwardIterator unique(ForwardIterator first, ForwardIterator last,
-                      BinaryPredicate binary_pred) {
-    first = adjacent_find(first, last, binary_pred);
-    return unique_copy(first, last, first, binary_pred);
-}
-
-template <class BidirectionalIterator>
-void __reverse(BidirectionalIterator first, BidirectionalIterator last, 
-              bidirectional_iterator_tag) {
-    while (true)
-        if (first == last || first == --last)
-           return;
-        else
-           iter_swap(first++, last);
-}
-
-template <class RandomAccessIterator>
-void __reverse(RandomAccessIterator first, RandomAccessIterator last,
-              random_access_iterator_tag) {
-    while (first < last) iter_swap(first++, --last);
-}
-
-template <class BidirectionalIterator>
-inline void reverse(BidirectionalIterator first, BidirectionalIterator last) {
-    __reverse(first, last, iterator_category(first));
-}
-
-template <class BidirectionalIterator, class OutputIterator>
-OutputIterator reverse_copy(BidirectionalIterator first,
-                            BidirectionalIterator last,
-                            OutputIterator result) {
-  while (first != last) {
-    --last;
-    *result = *last;
-    ++result;
-  }
-  return result;
-}
-
-template <class ForwardIterator, class Distance>
-void __rotate(ForwardIterator first, ForwardIterator middle,
-              ForwardIterator last, Distance*, forward_iterator_tag) {
-  for (ForwardIterator i = middle; ;) {
-    iter_swap(first, i);
-    ++first;
-    ++i;
-    if (first == middle) {
-      if (i == last) return;
-      middle = i;
-    }
-    else if (i == last)
-      i = middle;
-  }
-}
-
-template <class BidirectionalIterator, class Distance>
-void __rotate(BidirectionalIterator first, BidirectionalIterator middle,
-             BidirectionalIterator last, Distance*,
-             bidirectional_iterator_tag) {
-    reverse(first, middle);
-    reverse(middle, last);
-    reverse(first, last);
-}
-
-template <class EuclideanRingElement>
-EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n)
-{
-    while (n != 0) {
-       EuclideanRingElement t = m % n;
-       m = n;
-       n = t;
-    }
-    return m;
-}
-
-template <class RandomAccessIterator, class Distance, class T>
-void __rotate_cycle(RandomAccessIterator first, RandomAccessIterator last,
-                   RandomAccessIterator initial, Distance shift, T*) {
-    T value = *initial;
-    RandomAccessIterator ptr1 = initial;
-    RandomAccessIterator ptr2 = ptr1 + shift;
-    while (ptr2 != initial) {
-       *ptr1 = *ptr2;
-       ptr1 = ptr2;
-       if (last - ptr2 > shift)
-           ptr2 += shift;
-       else
-           ptr2 = first + (shift - (last - ptr2));
-    }
-    *ptr1 = value;
-}
-
-template <class RandomAccessIterator, class Distance>
-void __rotate(RandomAccessIterator first, RandomAccessIterator middle,
-             RandomAccessIterator last, Distance*,
-             random_access_iterator_tag) {
-    Distance n = __gcd(last - first, middle - first);
-    while (n--)
-       __rotate_cycle(first, last, first + n, middle - first,
-                      value_type(first));
-}
-
-template <class ForwardIterator>
-inline void rotate(ForwardIterator first, ForwardIterator middle,
-                  ForwardIterator last) {
-    if (first == middle || middle == last) return;
-    __rotate(first, middle, last, distance_type(first),
-            iterator_category(first));
-}
-
-template <class ForwardIterator, class OutputIterator>
-OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle,
-                          ForwardIterator last, OutputIterator result) {
-    return copy(first, middle, copy(middle, last, result));
-}
-
-template <class RandomAccessIterator, class Distance>
-void __random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
-                     Distance*) {
-    if (first == last) return;
-    for (RandomAccessIterator i = first + 1; i != last; ++i) 
-#ifdef __STL_NO_DRAND48
-      iter_swap(i, first + Distance(rand() % ((i - first) + 1)));
-#else
-      iter_swap(i, first + Distance(lrand48() % ((i - first) + 1)));
-#endif
-}
-
-template <class RandomAccessIterator>
-inline void random_shuffle(RandomAccessIterator first,
-                          RandomAccessIterator last) {
-    __random_shuffle(first, last, distance_type(first));
-}
-
-template <class RandomAccessIterator, class RandomNumberGenerator>
-void random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
-                   RandomNumberGenerator& rand) {
-    if (first == last) return;
-    for (RandomAccessIterator i = first + 1; i != last; ++i)
-       iter_swap(i, first + rand((i - first) + 1));
-}
-
-template <class ForwardIterator, class OutputIterator, class Distance>
-OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last,
-                               OutputIterator out, const Distance n)
-{
-  Distance remaining = 0;
-  distance(first, last, remaining);
-  Distance m = min(n, remaining);
-
-  while (m > 0) {
-#ifdef __STL_NO_DRAND48
-    if (rand() % remaining < m) {
-#else
-    if (lrand48() % remaining < m) {
-#endif
-      *out = *first;
-      ++out;
-      --m;
-    }
-
-    --remaining;
-    ++first;
-  }
-  return out;
-}
-
-template <class ForwardIterator, class OutputIterator, class Distance,
-          class RandomNumberGenerator>
-OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last,
-                               OutputIterator out, const Distance n,
-                               RandomNumberGenerator& rand)
-{
-  Distance remaining = 0;
-  distance(first, last, remaining);
-  Distance m = min(n, remaining);
-
-  while (m > 0) {
-    if (rand(remaining) < m) {
-      *out = *first;
-      ++out;
-      --m;
-    }
-
-    --remaining;
-    ++first;
-  }
-  return out;
-}
-
-template <class InputIterator, class RandomAccessIterator, class Distance>
-RandomAccessIterator __random_sample(InputIterator first, InputIterator last,
-                                     RandomAccessIterator out,
-                                     const Distance n)
-{
-  Distance m = 0;
-  Distance t = n;
-  for ( ; first != last && m < n; ++m, ++first) 
-    out[m] = *first;
-
-  while (first != last) {
-    ++t;
-#ifdef __STL_NO_DRAND48
-    Distance M = rand() % t;
-#else
-    Distance M = lrand48() % t;
-#endif
-    if (M < n)
-      out[M] = *first;
-    ++first;
-  }
-
-  return out + m;
-}
-
-template <class InputIterator, class RandomAccessIterator,
-          class RandomNumberGenerator, class Distance>
-RandomAccessIterator __random_sample(InputIterator first, InputIterator last,
-                                     RandomAccessIterator out,
-                                     RandomNumberGenerator& rand,
-                                     const Distance n)
-{
-  Distance m = 0;
-  Distance t = n;
-  for ( ; first != last && m < n; ++m, ++first)
-    out[m] = *first;
-
-  while (first != last) {
-    ++t;
-    Distance M = rand(t);
-    if (M < n)
-      out[M] = *first;
-    ++first;
-  }
-
-  return out + m;
-}
-
-template <class InputIterator, class RandomAccessIterator>
-inline RandomAccessIterator
-random_sample(InputIterator first, InputIterator last,
-              RandomAccessIterator out_first, RandomAccessIterator out_last) 
-{
-  return __random_sample(first, last, out_first, out_last - out_first);
-}
-
-template <class InputIterator, class RandomAccessIterator, 
-          class RandomNumberGenerator>
-inline RandomAccessIterator
-random_sample(InputIterator first, InputIterator last,
-              RandomAccessIterator out_first, RandomAccessIterator out_last,
-              RandomNumberGenerator& rand) 
-{
-  return __random_sample(first, last, out_first, rand, out_last - out_first);
-}
-
-
-
-template <class BidirectionalIterator, class Predicate>
-BidirectionalIterator partition(BidirectionalIterator first,
-                               BidirectionalIterator last, Predicate pred) {
-    while (true) {
-       while (true)
-           if (first == last)
-               return first;
-           else if (pred(*first))
-               ++first;
-           else
-               break;
-       --last;
-       while (true)
-           if (first == last)
-               return first;
-           else if (!pred(*last))
-               --last;
-           else
-               break;
-       iter_swap(first, last);
-       ++first;
-    }
-}
-
-template <class ForwardIterator, class Predicate, class Distance>
-ForwardIterator __inplace_stable_partition(ForwardIterator first,
-                                          ForwardIterator last,
-                                          Predicate pred, Distance len) {
-    if (len == 1) return pred(*first) ? last : first;
-    ForwardIterator middle = first;
-    advance(middle, len / 2);
-    ForwardIterator 
-       first_cut = __inplace_stable_partition(first, middle, pred, len / 2);
-    ForwardIterator 
-       second_cut = __inplace_stable_partition(middle, last, pred,
-                                               len - len / 2);
-    rotate(first_cut, middle, second_cut);
-    len = 0;
-    distance(middle, second_cut, len);
-    advance(first_cut, len);
-    return first_cut;
-}
-
-template <class ForwardIterator, class Pointer, class Predicate, 
-          class Distance>
-ForwardIterator __stable_partition_adaptive(ForwardIterator first,
-                                            ForwardIterator last,
-                                            Predicate pred, Distance len,
-                                            Pointer buffer,
-                                            Distance buffer_size) {
-  if (len <= buffer_size) {
-    ForwardIterator result1 = first;
-    Pointer result2 = buffer;
-    for ( ; first != last ; ++first)
-      if (pred(*first)) {
-        *result1 = *first;
-        ++result1;
-      }
-      else {
-        *result2 = *first;
-        ++result2;
-      }
-    copy(buffer, result2, result1);
-    return result1;
-  }
-  else {
-    ForwardIterator middle = first;
-    advance(middle, len / 2);
-    ForwardIterator first_cut =
-      __stable_partition_adaptive(first, middle, pred, len / 2,
-                                  buffer, buffer_size);
-    ForwardIterator second_cut =
-      __stable_partition_adaptive(middle, last, pred, len - len / 2,
-                                  buffer, buffer_size);
-
-    rotate(first_cut, middle, second_cut);
-    len = 0;
-    distance(middle, second_cut, len);
-    advance(first_cut, len);
-    return first_cut;
-  }
-}
-
-template <class ForwardIterator, class Predicate, class T, class Distance>
-inline ForwardIterator __stable_partition_aux(ForwardIterator first,
-                                              ForwardIterator last, 
-                                              Predicate pred, T*, Distance*) {
-  temporary_buffer<ForwardIterator, T> buf(first, last);
-  if (buf.size() > 0)
-    return __stable_partition_adaptive(first, last, pred,
-                                       Distance(buf.requested_size()),
-                                       buf.begin(), buf.size());
-  else
-    return __inplace_stable_partition(first, last, pred, 
-                                      Distance(buf.requested_size()));
-}
-
-template <class ForwardIterator, class Predicate>
-inline ForwardIterator stable_partition(ForwardIterator first,
-                                        ForwardIterator last, 
-                                        Predicate pred) {
-  if (first == last)
-    return first;
-  else
-    return __stable_partition_aux(first, last, pred,
-                                  value_type(first), distance_type(first));
-}
-
-template <class RandomAccessIterator, class T>
-RandomAccessIterator __unguarded_partition(RandomAccessIterator first, 
-                                          RandomAccessIterator last, 
-                                          T pivot) {
-    while (1) {
-       while (*first < pivot) ++first;
-       --last;
-       while (pivot < *last) --last;
-       if (!(first < last)) return first;
-       iter_swap(first, last);
-       ++first;
-    }
-}    
-
-template <class RandomAccessIterator, class T, class Compare>
-RandomAccessIterator __unguarded_partition(RandomAccessIterator first, 
-                                          RandomAccessIterator last, 
-                                          T pivot, Compare comp) {
-    while (1) {
-       while (comp(*first, pivot)) ++first;
-       --last;
-       while (comp(pivot, *last)) --last;
-       if (!(first < last)) return first;
-       iter_swap(first, last);
-       ++first;
-    }
-}
-
-const int __stl_threshold = 16;
-
-
-template <class RandomAccessIterator, class T>
-void __unguarded_linear_insert(RandomAccessIterator last, T value) {
-    RandomAccessIterator next = last;
-    --next;
-    while (value < *next) {
-       *last = *next;
-       last = next;
-        --next;
-    }
-    *last = value;
-}
-
-template <class RandomAccessIterator, class T, class Compare>
-void __unguarded_linear_insert(RandomAccessIterator last, T value, 
-                              Compare comp) {
-    RandomAccessIterator next = last;
-    --next;  
-    while (comp(value , *next)) {
-       *last = *next;
-       last = next;
-        --next;
-    }
-    *last = value;
-}
-
-template <class RandomAccessIterator, class T>
-inline void __linear_insert(RandomAccessIterator first, 
-                           RandomAccessIterator last, T*) {
-    T value = *last;
-    if (value < *first) {
-       copy_backward(first, last, last + 1);
-       *first = value;
-    } else
-       __unguarded_linear_insert(last, value);
-}
-
-template <class RandomAccessIterator, class T, class Compare>
-inline void __linear_insert(RandomAccessIterator first, 
-                           RandomAccessIterator last, T*, Compare comp) {
-    T value = *last;
-    if (comp(value, *first)) {
-       copy_backward(first, last, last + 1);
-       *first = value;
-    } else
-       __unguarded_linear_insert(last, value, comp);
-}
-
-template <class RandomAccessIterator>
-void __insertion_sort(RandomAccessIterator first, RandomAccessIterator last) {
-    if (first == last) return; 
-    for (RandomAccessIterator i = first + 1; i != last; ++i)
-       __linear_insert(first, i, value_type(first));
-}
-
-template <class RandomAccessIterator, class Compare>
-void __insertion_sort(RandomAccessIterator first,
-                     RandomAccessIterator last, Compare comp) {
-    if (first == last) return;
-    for (RandomAccessIterator i = first + 1; i != last; ++i)
-       __linear_insert(first, i, value_type(first), comp);
-}
-
-template <class RandomAccessIterator, class T>
-void __unguarded_insertion_sort_aux(RandomAccessIterator first, 
-                                   RandomAccessIterator last, T*) {
-    for (RandomAccessIterator i = first; i != last; ++i)
-       __unguarded_linear_insert(i, T(*i));
-}
-
-template <class RandomAccessIterator>
-inline void __unguarded_insertion_sort(RandomAccessIterator first, 
-                               RandomAccessIterator last) {
-    __unguarded_insertion_sort_aux(first, last, value_type(first));
-}
-
-template <class RandomAccessIterator, class T, class Compare>
-void __unguarded_insertion_sort_aux(RandomAccessIterator first, 
-                                   RandomAccessIterator last,
-                                   T*, Compare comp) {
-    for (RandomAccessIterator i = first; i != last; ++i)
-       __unguarded_linear_insert(i, T(*i), comp);
-}
-
-template <class RandomAccessIterator, class Compare>
-inline void __unguarded_insertion_sort(RandomAccessIterator first, 
-                                      RandomAccessIterator last,
-                                      Compare comp) {
-    __unguarded_insertion_sort_aux(first, last, value_type(first), comp);
-}
-
-template <class RandomAccessIterator>
-void __final_insertion_sort(RandomAccessIterator first, 
-                           RandomAccessIterator last) {
-    if (last - first > __stl_threshold) {
-       __insertion_sort(first, first + __stl_threshold);
-       __unguarded_insertion_sort(first + __stl_threshold, last);
-    } else
-       __insertion_sort(first, last);
-}
-
-template <class RandomAccessIterator, class Compare>
-void __final_insertion_sort(RandomAccessIterator first, 
-                           RandomAccessIterator last, Compare comp) {
-    if (last - first > __stl_threshold) {
-       __insertion_sort(first, first + __stl_threshold, comp);
-       __unguarded_insertion_sort(first + __stl_threshold, last, comp);
-    } else
-       __insertion_sort(first, last, comp);
-}
-
-template <class Size>
-Size __lg(Size n) {
-    Size k;
-    for (k = 0; n != 1; n = n / 2) ++k;
-    return k;
-}
-
-template <class RandomAccessIterator, class T, class Size>
-void __introsort_loop(RandomAccessIterator first,
-                      RandomAccessIterator last, T*,
-                      Size depth_limit) {
-    while (last - first > __stl_threshold) {
-      if (depth_limit == 0) {
-       partial_sort(first, last, last);
-       return;
-      }
-      --depth_limit;
-      RandomAccessIterator cut = __unguarded_partition
-       (first, last, T(__median(*first, *(first + (last - first)/2),
-                                *(last - 1))));
-     __introsort_loop(cut, last, value_type(first), depth_limit);
-     last = cut;
-    }
-}
-
-template <class RandomAccessIterator, class T, class Size, class Compare>
-void __introsort_loop(RandomAccessIterator first,
-                     RandomAccessIterator last, T*,
-                     Size depth_limit, Compare comp) {
-  while (last - first > __stl_threshold) {
-    if (depth_limit == 0) {
-      partial_sort(first, last, last, comp);
-      return;
-    }
-    --depth_limit;
-    RandomAccessIterator cut = __unguarded_partition
-      (first, last, T(__median(*first, *(first + (last - first)/2),
-                              *(last - 1), comp)), comp);
-    __introsort_loop(cut, last, value_type(first), depth_limit, comp);
-    last = cut;
-  }
-}
-
-template <class RandomAccessIterator>
-inline void sort(RandomAccessIterator first, RandomAccessIterator last) {
-  if (first != last) {
-    __introsort_loop(first, last, value_type(first), __lg(last - first) * 2);
-    __final_insertion_sort(first, last);
-  }
-}
-
-template <class RandomAccessIterator, class Compare>
-inline void sort(RandomAccessIterator first, RandomAccessIterator last,
-                 Compare comp) {
-  if (first != last) {
-    __introsort_loop(first, last, value_type(first), __lg(last - first) * 2,
-                     comp);
-    __final_insertion_sort(first, last, comp);
-  }
-}
-
-
-template <class RandomAccessIterator>
-void __inplace_stable_sort(RandomAccessIterator first,
-                          RandomAccessIterator last) {
-    if (last - first < 15) {
-       __insertion_sort(first, last);
-       return;
-    }
-    RandomAccessIterator middle = first + (last - first) / 2;
-    __inplace_stable_sort(first, middle);
-    __inplace_stable_sort(middle, last);
-    __merge_without_buffer(first, middle, last, middle - first, last - middle);
-}
-
-template <class RandomAccessIterator, class Compare>
-void __inplace_stable_sort(RandomAccessIterator first,
-                          RandomAccessIterator last, Compare comp) {
-    if (last - first < 15) {
-       __insertion_sort(first, last, comp);
-       return;
-    }
-    RandomAccessIterator middle = first + (last - first) / 2;
-    __inplace_stable_sort(first, middle, comp);
-    __inplace_stable_sort(middle, last, comp);
-    __merge_without_buffer(first, middle, last, middle - first,
-                          last - middle, comp);
-}
-
-template <class RandomAccessIterator1, class RandomAccessIterator2,
-         class Distance>
-void __merge_sort_loop(RandomAccessIterator1 first,
-                      RandomAccessIterator1 last, 
-                      RandomAccessIterator2 result, Distance step_size) {
-    Distance two_step = 2 * step_size;
-
-    while (last - first >= two_step) {
-       result = merge(first, first + step_size,
-                      first + step_size, first + two_step, result);
-       first += two_step;
-    }
-
-    step_size = min(Distance(last - first), step_size);
-    merge(first, first + step_size, first + step_size, last, result);
-}
-
-template <class RandomAccessIterator1, class RandomAccessIterator2,
-         class Distance, class Compare>
-void __merge_sort_loop(RandomAccessIterator1 first,
-                      RandomAccessIterator1 last, 
-                      RandomAccessIterator2 result, Distance step_size,
-                      Compare comp) {
-    Distance two_step = 2 * step_size;
-
-    while (last - first >= two_step) {
-       result = merge(first, first + step_size,
-                      first + step_size, first + two_step, result, comp);
-       first += two_step;
-    }
-    step_size = min(Distance(last - first), step_size);
-
-    merge(first, first + step_size, first + step_size, last, result, comp);
-}
-
-const int __stl_chunk_size = 7;
-        
-template <class RandomAccessIterator, class Distance>
-void __chunk_insertion_sort(RandomAccessIterator first, 
-                            RandomAccessIterator last, Distance chunk_size) {
-  while (last - first >= chunk_size) {
-    __insertion_sort(first, first + chunk_size);
-    first += chunk_size;
-  }
-  __insertion_sort(first, last);
-}
-
-template <class RandomAccessIterator, class Distance, class Compare>
-void __chunk_insertion_sort(RandomAccessIterator first, 
-                            RandomAccessIterator last,
-                            Distance chunk_size, Compare comp) {
-  while (last - first >= chunk_size) {
-    __insertion_sort(first, first + chunk_size, comp);
-    first += chunk_size;
-  }
-  __insertion_sort(first, last, comp);
-}
-
-template <class RandomAccessIterator, class Pointer, class Distance>
-void __merge_sort_with_buffer(RandomAccessIterator first, 
-                              RandomAccessIterator last,
-                              Pointer buffer, Distance*) {
-    Distance len = last - first;
-    Pointer buffer_last = buffer + len;
-
-    Distance step_size = __stl_chunk_size;
-    __chunk_insertion_sort(first, last, step_size);
-
-    while (step_size < len) {
-       __merge_sort_loop(first, last, buffer, step_size);
-       step_size *= 2;
-       __merge_sort_loop(buffer, buffer_last, first, step_size);
-       step_size *= 2;
-    }
-}
-
-template <class RandomAccessIterator, class Pointer, class Distance,
-          class Compare>
-void __merge_sort_with_buffer(RandomAccessIterator first, 
-                              RandomAccessIterator last, Pointer buffer,
-                              Distance*, Compare comp) {
-    Distance len = last - first;
-    Pointer buffer_last = buffer + len;
-
-    Distance step_size = __stl_chunk_size;
-    __chunk_insertion_sort(first, last, step_size, comp);
-
-    while (step_size < len) {
-       __merge_sort_loop(first, last, buffer, step_size, comp);
-       step_size *= 2;
-       __merge_sort_loop(buffer, buffer_last, first, step_size, comp);
-       step_size *= 2;
-    }
-}
-
-template <class RandomAccessIterator, class Pointer, class Distance>
-void __stable_sort_adaptive(RandomAccessIterator first, 
-                           RandomAccessIterator last, Pointer buffer,
-                           Distance buffer_size) {
-    Distance len = (last - first + 1) / 2;
-    RandomAccessIterator middle = first + len;
-    if (len > buffer_size) {
-       __stable_sort_adaptive(first, middle, buffer, buffer_size);
-       __stable_sort_adaptive(middle, last, buffer, buffer_size);
-    } else {
-       __merge_sort_with_buffer(first, middle, buffer, (Distance*)0);
-       __merge_sort_with_buffer(middle, last, buffer, (Distance*)0);
-    }
-    __merge_adaptive(first, middle, last, Distance(middle - first), 
-                    Distance(last - middle), buffer, buffer_size);
-}
-
-template <class RandomAccessIterator, class Pointer, class Distance, 
-          class Compare>
-void __stable_sort_adaptive(RandomAccessIterator first, 
-                            RandomAccessIterator last, Pointer buffer,
-                            Distance buffer_size, Compare comp) {
-    Distance len = (last - first + 1) / 2;
-    RandomAccessIterator middle = first + len;
-    if (len > buffer_size) {
-        __stable_sort_adaptive(first, middle, buffer, buffer_size, 
-                               comp);
-        __stable_sort_adaptive(middle, last, buffer, buffer_size, 
-                               comp);
-    } else {
-        __merge_sort_with_buffer(first, middle, buffer, (Distance*)0, comp);
-        __merge_sort_with_buffer(middle, last, buffer, (Distance*)0, comp);
-    }
-    __merge_adaptive(first, middle, last, Distance(middle - first), 
-                     Distance(last - middle), buffer, buffer_size,
-                     comp);
-}
-
-template <class RandomAccessIterator, class T, class Distance>
-inline void __stable_sort_aux(RandomAccessIterator first,
-                             RandomAccessIterator last, T*, Distance*) {
-  temporary_buffer<RandomAccessIterator, T> buf(first, last);
-  if (buf.begin() == 0)
-    __inplace_stable_sort(first, last);
-  else 
-    __stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size()));
-}
-
-template <class RandomAccessIterator, class T, class Distance, class Compare>
-inline void __stable_sort_aux(RandomAccessIterator first,
-                             RandomAccessIterator last, T*, Distance*,
-                             Compare comp) {
-  temporary_buffer<RandomAccessIterator, T> buf(first, last);
-  if (buf.begin() == 0)
-    __inplace_stable_sort(first, last, comp);
-  else 
-    __stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size()),
-                           comp);
-}
-
-template <class RandomAccessIterator>
-inline void stable_sort(RandomAccessIterator first,
-                       RandomAccessIterator last) {
-    __stable_sort_aux(first, last, value_type(first), distance_type(first));
-}
-
-template <class RandomAccessIterator, class Compare>
-inline void stable_sort(RandomAccessIterator first,
-                       RandomAccessIterator last, Compare comp) {
-    __stable_sort_aux(first, last, value_type(first), distance_type(first), 
-                     comp);
-}
-
-template <class RandomAccessIterator, class T>
-void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,
-                   RandomAccessIterator last, T*) {
-    make_heap(first, middle);
-    for (RandomAccessIterator i = middle; i < last; ++i)
-       if (*i < *first) 
-         __pop_heap(first, middle, i, T(*i), distance_type(first));
-    sort_heap(first, middle);
-}
-
-template <class RandomAccessIterator>
-inline void partial_sort(RandomAccessIterator first,
-                        RandomAccessIterator middle,
-                        RandomAccessIterator last) {
-    __partial_sort(first, middle, last, value_type(first));
-}
-
-template <class RandomAccessIterator, class T, class Compare>
-void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,
-                   RandomAccessIterator last, T*, Compare comp) {
-    make_heap(first, middle, comp);
-    for (RandomAccessIterator i = middle; i < last; ++i)
-       if (comp(*i, *first))
-         __pop_heap(first, middle, i, T(*i), comp, distance_type(first));
-    sort_heap(first, middle, comp);
-}
-
-template <class RandomAccessIterator, class Compare>
-inline void partial_sort(RandomAccessIterator first,
-                        RandomAccessIterator middle,
-                        RandomAccessIterator last, Compare comp) {
-    __partial_sort(first, middle, last, value_type(first), comp);
-}
-
-template <class InputIterator, class RandomAccessIterator, class Distance,
-          class T>
-RandomAccessIterator __partial_sort_copy(InputIterator first,
-                                        InputIterator last,
-                                        RandomAccessIterator result_first,
-                                        RandomAccessIterator result_last, 
-                                        Distance*, T*) {
-    if (result_first == result_last) return result_last;
-    RandomAccessIterator result_real_last = result_first;
-    while(first != last && result_real_last != result_last) {
-       *result_real_last = *first;
-        ++result_real_last;
-        ++first;
-    }
-    make_heap(result_first, result_real_last);
-    while (first != last) {
-       if (*first < *result_first) 
-           __adjust_heap(result_first, Distance(0),
-                         Distance(result_real_last - result_first), T(*first));
-       ++first;
-    }
-    sort_heap(result_first, result_real_last);
-    return result_real_last;
-}
-
-template <class InputIterator, class RandomAccessIterator>
-inline RandomAccessIterator
-partial_sort_copy(InputIterator first, InputIterator last,
-                 RandomAccessIterator result_first,
-                 RandomAccessIterator result_last) {
-    return __partial_sort_copy(first, last, result_first, result_last, 
-                              distance_type(result_first), value_type(first));
-}
-
-template <class InputIterator, class RandomAccessIterator, class Compare,
-          class Distance, class T>
-RandomAccessIterator __partial_sort_copy(InputIterator first,
-                                        InputIterator last,
-                                        RandomAccessIterator result_first,
-                                        RandomAccessIterator result_last,
-                                        Compare comp, Distance*, T*) {
-    if (result_first == result_last) return result_last;
-    RandomAccessIterator result_real_last = result_first;
-    while(first != last && result_real_last != result_last) {
-       *result_real_last = *first;
-        ++result_real_last;
-        ++first;
-    }
-    make_heap(result_first, result_real_last, comp);
-    while (first != last) {
-       if (comp(*first, *result_first))
-           __adjust_heap(result_first, Distance(0),
-                         Distance(result_real_last - result_first), T(*first),
-                         comp);
-       ++first;
-    }
-    sort_heap(result_first, result_real_last, comp);
-    return result_real_last;
-}
-
-template <class InputIterator, class RandomAccessIterator, class Compare>
-inline RandomAccessIterator
-partial_sort_copy(InputIterator first, InputIterator last,
-                 RandomAccessIterator result_first,
-                 RandomAccessIterator result_last, Compare comp) {
-    return __partial_sort_copy(first, last, result_first, result_last, comp,
-                              distance_type(result_first), value_type(first));
-}
-
-template <class RandomAccessIterator, class T>
-void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,
-                  RandomAccessIterator last, T*) {
-    while (last - first > 3) {
-       RandomAccessIterator cut = __unguarded_partition
-           (first, last, T(__median(*first, *(first + (last - first)/2),
-                                    *(last - 1))));
-       if (cut <= nth)
-           first = cut;
-       else 
-           last = cut;
-    }
-    __insertion_sort(first, last);
-}
-
-template <class RandomAccessIterator>
-inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
-                       RandomAccessIterator last) {
-    __nth_element(first, nth, last, value_type(first));
-}
-
-template <class RandomAccessIterator, class T, class Compare>
-void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,
-                  RandomAccessIterator last, T*, Compare comp) {
-    while (last - first > 3) {
-       RandomAccessIterator cut = __unguarded_partition
-           (first, last, T(__median(*first, *(first + (last - first)/2), 
-                                    *(last - 1), comp)), comp);
-       if (cut <= nth)
-           first = cut;
-       else 
-           last = cut;
-    }
-    __insertion_sort(first, last, comp);
-}
-
-template <class RandomAccessIterator, class Compare>
-inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
-                RandomAccessIterator last, Compare comp) {
-    __nth_element(first, nth, last, value_type(first), comp);
-}
-
-template <class ForwardIterator, class T, class Distance>
-ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,
-                             const T& value, Distance*,
-                             forward_iterator_tag) {
-    Distance len = 0;
-    distance(first, last, len);
-    Distance half;
-    ForwardIterator middle;
-
-    while (len > 0) {
-       half = len / 2;
-       middle = first;
-       advance(middle, half);
-       if (*middle < value) {
-           first = middle;
-           ++first;
-           len = len - half - 1;
-       } else
-           len = half;
-    }
-    return first;
-}
-
-template <class RandomAccessIterator, class T, class Distance>
-RandomAccessIterator __lower_bound(RandomAccessIterator first,
-                                  RandomAccessIterator last, const T& value,
-                                  Distance*, random_access_iterator_tag) {
-    Distance len = last - first;
-    Distance half;
-    RandomAccessIterator middle;
-
-    while (len > 0) {
-       half = len / 2;
-       middle = first + half;
-       if (*middle < value) {
-           first = middle + 1;
-           len = len - half - 1;
-       } else
-           len = half;
-    }
-    return first;
-}
-
-template <class ForwardIterator, class T>
-inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
-                                  const T& value) {
-    return __lower_bound(first, last, value, distance_type(first),
-                        iterator_category(first));
-}
-
-template <class ForwardIterator, class T, class Compare, class Distance>
-ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,
-                             const T& value, Compare comp, Distance*,
-                             forward_iterator_tag) {
-    Distance len = 0;
-    distance(first, last, len);
-    Distance half;
-    ForwardIterator middle;
-
-    while (len > 0) {
-       half = len / 2;
-       middle = first;
-       advance(middle, half);
-       if (comp(*middle, value)) {
-           first = middle;
-           ++first;
-           len = len - half - 1;
-       } else
-           len = half;
-    }
-    return first;
-}
-
-template <class RandomAccessIterator, class T, class Compare, class Distance>
-RandomAccessIterator __lower_bound(RandomAccessIterator first,
-                                  RandomAccessIterator last,
-                                  const T& value, Compare comp, Distance*,
-                                  random_access_iterator_tag) {
-    Distance len = last - first;
-    Distance half;
-    RandomAccessIterator middle;
-
-    while (len > 0) {
-       half = len / 2;
-       middle = first + half;
-       if (comp(*middle, value)) {
-           first = middle + 1;
-           len = len - half - 1;
-       } else
-           len = half;
-    }
-    return first;
-}
-
-template <class ForwardIterator, class T, class Compare>
-inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
-                                  const T& value, Compare comp) {
-    return __lower_bound(first, last, value, comp, distance_type(first),
-                        iterator_category(first));
-}
-
-template <class ForwardIterator, class T, class Distance>
-ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
-                             const T& value, Distance*,
-                             forward_iterator_tag) {
-    Distance len = 0;
-    distance(first, last, len);
-    Distance half;
-    ForwardIterator middle;
-
-    while (len > 0) {
-       half = len / 2;
-       middle = first;
-       advance(middle, half);
-       if (value < *middle)
-           len = half;
-       else {
-           first = middle;
-           ++first;
-           len = len - half - 1;
-       }
-    }
-    return first;
-}
-
-template <class RandomAccessIterator, class T, class Distance>
-RandomAccessIterator __upper_bound(RandomAccessIterator first,
-                                  RandomAccessIterator last, const T& value,
-                                  Distance*, random_access_iterator_tag) {
-    Distance len = last - first;
-    Distance half;
-    RandomAccessIterator middle;
-
-    while (len > 0) {
-       half = len / 2;
-       middle = first + half;
-       if (value < *middle)
-           len = half;
-       else {
-           first = middle + 1;
-           len = len - half - 1;
-       }
-    }
-    return first;
-}
-
-template <class ForwardIterator, class T>
-inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
-                                  const T& value) {
-    return __upper_bound(first, last, value, distance_type(first),
-                        iterator_category(first));
-}
-
-template <class ForwardIterator, class T, class Compare, class Distance>
-ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
-                             const T& value, Compare comp, Distance*,
-                             forward_iterator_tag) {
-    Distance len = 0;
-    distance(first, last, len);
-    Distance half;
-    ForwardIterator middle;
-
-    while (len > 0) {
-       half = len / 2;
-       middle = first;
-       advance(middle, half);
-       if (comp(value, *middle))
-           len = half;
-       else {
-           first = middle;
-           ++first;
-           len = len - half - 1;
-       }
-    }
-    return first;
-}
-
-template <class RandomAccessIterator, class T, class Compare, class Distance>
-RandomAccessIterator __upper_bound(RandomAccessIterator first,
-                                  RandomAccessIterator last,
-                                  const T& value, Compare comp, Distance*,
-                                  random_access_iterator_tag) {
-    Distance len = last - first;
-    Distance half;
-    RandomAccessIterator middle;
-
-    while (len > 0) {
-       half = len / 2;
-       middle = first + half;
-       if (comp(value, *middle))
-           len = half;
-       else {
-           first = middle + 1;
-           len = len - half - 1;
-       }
-    }
-    return first;
-}
-
-template <class ForwardIterator, class T, class Compare>
-inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
-                                  const T& value, Compare comp) {
-    return __upper_bound(first, last, value, comp, distance_type(first),
-                        iterator_category(first));
-}
-
-template <class ForwardIterator, class T, class Distance>
-pair<ForwardIterator, ForwardIterator>
-__equal_range(ForwardIterator first, ForwardIterator last, const T& value,
-             Distance*, forward_iterator_tag) {
-    Distance len = 0;
-    distance(first, last, len);
-    Distance half;
-    ForwardIterator middle, left, right;
-
-    while (len > 0) {
-       half = len / 2;
-       middle = first;
-       advance(middle, half);
-       if (*middle < value) {
-           first = middle;
-           ++first;
-           len = len - half - 1;
-       } else if (value < *middle)
-           len = half;
-       else {
-           left = lower_bound(first, middle, value);
-           advance(first, len);
-           right = upper_bound(++middle, first, value);
-           return pair<ForwardIterator, ForwardIterator>(left, right);
-       }
-    }
-    return pair<ForwardIterator, ForwardIterator>(first, first);
-}
-
-template <class RandomAccessIterator, class T, class Distance>
-pair<RandomAccessIterator, RandomAccessIterator>
-__equal_range(RandomAccessIterator first, RandomAccessIterator last,
-             const T& value, Distance*, random_access_iterator_tag) {
-    Distance len = last - first;
-    Distance half;
-    RandomAccessIterator middle, left, right;
-
-    while (len > 0) {
-       half = len / 2;
-       middle = first + half;
-       if (*middle < value) {
-           first = middle + 1;
-           len = len - half - 1;
-       } else if (value < *middle)
-           len = half;
-       else {
-           left = lower_bound(first, middle, value);
-           right = upper_bound(++middle, first + len, value);
-           return pair<RandomAccessIterator, RandomAccessIterator>(left,
-                                                                   right);
-       }
-    }
-    return pair<RandomAccessIterator, RandomAccessIterator>(first, first);
-}
-
-template <class ForwardIterator, class T>
-inline pair<ForwardIterator, ForwardIterator>
-equal_range(ForwardIterator first, ForwardIterator last, const T& value) {
-    return __equal_range(first, last, value, distance_type(first),
-                        iterator_category(first));
-}
-
-template <class ForwardIterator, class T, class Compare, class Distance>
-pair<ForwardIterator, ForwardIterator>
-__equal_range(ForwardIterator first, ForwardIterator last, const T& value,
-             Compare comp, Distance*, forward_iterator_tag) {
-    Distance len = 0;
-    distance(first, last, len);
-    Distance half;
-    ForwardIterator middle, left, right;
-
-    while (len > 0) {
-       half = len / 2;
-       middle = first;
-       advance(middle, half);
-       if (comp(*middle, value)) {
-           first = middle;
-           ++first;
-           len = len - half - 1;
-       } else if (comp(value, *middle))
-           len = half;
-       else {
-           left = lower_bound(first, middle, value, comp);
-           advance(first, len);
-           right = upper_bound(++middle, first, value, comp);
-           return pair<ForwardIterator, ForwardIterator>(left, right);
-       }
-    }
-    return pair<ForwardIterator, ForwardIterator>(first, first);
-}           
-
-template <class RandomAccessIterator, class T, class Compare, class Distance>
-pair<RandomAccessIterator, RandomAccessIterator>
-__equal_range(RandomAccessIterator first, RandomAccessIterator last,
-             const T& value, Compare comp, Distance*,
-             random_access_iterator_tag) {
-    Distance len = last - first;
-    Distance half;
-    RandomAccessIterator middle, left, right;
-
-    while (len > 0) {
-       half = len / 2;
-       middle = first + half;
-       if (comp(*middle, value)) {
-           first = middle + 1;
-           len = len - half - 1;
-       } else if (comp(value, *middle))
-           len = half;
-       else {
-           left = lower_bound(first, middle, value, comp);
-           right = upper_bound(++middle, first + len, value, comp);
-           return pair<RandomAccessIterator, RandomAccessIterator>(left,
-                                                                   right);
-       }
-    }
-    return pair<RandomAccessIterator, RandomAccessIterator>(first, first);
-}           
-
-template <class ForwardIterator, class T, class Compare>
-inline pair<ForwardIterator, ForwardIterator>
-equal_range(ForwardIterator first, ForwardIterator last, const T& value,
-           Compare comp) {
-    return __equal_range(first, last, value, comp, distance_type(first),
-                        iterator_category(first));
-}    
-
-template <class ForwardIterator, class T>
-bool binary_search(ForwardIterator first, ForwardIterator last,
-                  const T& value) {
-    ForwardIterator i = lower_bound(first, last, value);
-    return i != last && !(value < *i);
-}
-
-template <class ForwardIterator, class T, class Compare>
-bool binary_search(ForwardIterator first, ForwardIterator last, const T& value,
-                  Compare comp) {
-    ForwardIterator i = lower_bound(first, last, value, comp);
-    return i != last && !comp(value, *i);
-}
-
-template <class InputIterator1, class InputIterator2, class OutputIterator>
-OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
-                     InputIterator2 first2, InputIterator2 last2,
-                     OutputIterator result) {
-  while (first1 != last1 && first2 != last2) {
-    if (*first2 < *first1) {
-      *result = *first2;
-      ++first2;
-    }
-    else {
-      *result = *first1;
-      ++first1;
-    }
-    ++result;
-  }
-  return copy(first2, last2, copy(first1, last1, result));
-}
-
-template <class InputIterator1, class InputIterator2, class OutputIterator,
-          class Compare>
-OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
-                     InputIterator2 first2, InputIterator2 last2,
-                     OutputIterator result, Compare comp) {
-  while (first1 != last1 && first2 != last2) {
-    if (comp(*first2, *first1)) {
-      *result = *first2;
-      ++first2;
-    }
-    else {
-      *result = *first1;
-      ++first1;
-    }
-    ++result;
-  }
-  return copy(first2, last2, copy(first1, last1, result));
-}
-
-template <class BidirectionalIterator, class Distance>
-void __merge_without_buffer(BidirectionalIterator first,
-                           BidirectionalIterator middle,
-                           BidirectionalIterator last,
-                           Distance len1, Distance len2) {
-    if (len1 == 0 || len2 == 0) return;
-    if (len1 + len2 == 2) {
-       if (*middle < *first) iter_swap(first, middle);
-       return;
-    }
-    BidirectionalIterator first_cut = first;
-    BidirectionalIterator second_cut = middle;
-    Distance len11 = 0;
-    Distance len22 = 0;
-    if (len1 > len2) {
-       len11 = len1 / 2;
-       advance(first_cut, len11);
-       second_cut = lower_bound(middle, last, *first_cut);
-       distance(middle, second_cut, len22);
-    } else {
-       len22 = len2 / 2;
-       advance(second_cut, len22);
-       first_cut = upper_bound(first, middle, *second_cut);
-       distance(first, first_cut, len11);
-    }
-    rotate(first_cut, middle, second_cut);
-    BidirectionalIterator new_middle = first_cut;
-    advance(new_middle, len22);
-    __merge_without_buffer(first, first_cut, new_middle, len11, len22);
-    __merge_without_buffer(new_middle, second_cut, last, len1 - len11,
-                          len2 - len22);
-}
-
-template <class BidirectionalIterator, class Distance, class Compare>
-void __merge_without_buffer(BidirectionalIterator first,
-                           BidirectionalIterator middle,
-                           BidirectionalIterator last,
-                           Distance len1, Distance len2, Compare comp) {
-    if (len1 == 0 || len2 == 0) return;
-    if (len1 + len2 == 2) {
-       if (comp(*middle, *first)) iter_swap(first, middle);
-       return;
-    }
-    BidirectionalIterator first_cut = first;
-    BidirectionalIterator second_cut = middle;
-    Distance len11 = 0;
-    Distance len22 = 0;
-    if (len1 > len2) {
-       len11 = len1 / 2;
-       advance(first_cut, len11);
-       second_cut = lower_bound(middle, last, *first_cut, comp);
-       distance(middle, second_cut, len22);
-    } else {
-       len22 = len2 / 2;
-       advance(second_cut, len22);
-       first_cut = upper_bound(first, middle, *second_cut, comp);
-       distance(first, first_cut, len11);
-    }
-    rotate(first_cut, middle, second_cut);
-    BidirectionalIterator new_middle = first_cut;
-    advance(new_middle, len22);
-    __merge_without_buffer(first, first_cut, new_middle, len11, len22, comp);
-    __merge_without_buffer(new_middle, second_cut, last, len1 - len11,
-                          len2 - len22, comp);
-}
-
-template <class BidirectionalIterator1, class BidirectionalIterator2,
-         class Distance>
-BidirectionalIterator1 __rotate_adaptive(BidirectionalIterator1 first,
-                                        BidirectionalIterator1 middle,
-                                        BidirectionalIterator1 last,
-                                        Distance len1, Distance len2,
-                                        BidirectionalIterator2 buffer,
-                                        Distance buffer_size) {
-    BidirectionalIterator2 buffer_end;
-    if (len1 > len2 && len2 <= buffer_size) {
-       buffer_end = copy(middle, last, buffer);
-       copy_backward(first, middle, last);
-       return copy(buffer, buffer_end, first);
-    } else if (len1 <= buffer_size) {
-       buffer_end = copy(first, middle, buffer);
-       copy(middle, last, first);
-       return copy_backward(buffer, buffer_end, last);
-    } else  {
-       rotate(first, middle, last);
-       advance(first, len2);
-       return first;
-    }
-}
-
-template <class BidirectionalIterator1, class BidirectionalIterator2,
-         class BidirectionalIterator3>
-BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,
-                                       BidirectionalIterator1 last1,
-                                       BidirectionalIterator2 first2,
-                                       BidirectionalIterator2 last2,
-                                       BidirectionalIterator3 result) {
-    if (first1 == last1) return copy_backward(first2, last2, result);
-    if (first2 == last2) return copy_backward(first1, last1, result);
-    --last1;
-    --last2;
-    while (true) {
-       if (*last2 < *last1) {
-           *--result = *last1;
-           if (first1 == last1) return copy_backward(first2, ++last2, result);
-           --last1;
-       } else {
-           *--result = *last2;
-           if (first2 == last2) return copy_backward(first1, ++last1, result);
-           --last2;
-       }
-    }
-}
-
-template <class BidirectionalIterator1, class BidirectionalIterator2,
-         class BidirectionalIterator3, class Compare>
-BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,
-                                       BidirectionalIterator1 last1,
-                                       BidirectionalIterator2 first2,
-                                       BidirectionalIterator2 last2,
-                                       BidirectionalIterator3 result,
-                                       Compare comp) {
-    if (first1 == last1) return copy_backward(first2, last2, result);
-    if (first2 == last2) return copy_backward(first1, last1, result);
-    --last1;
-    --last2;
-    while (true) {
-       if (comp(*last2, *last1)) {
-           *--result = *last1;
-           if (first1 == last1) return copy_backward(first2, ++last2, result);
-           --last1;
-       } else {
-           *--result = *last2;
-           if (first2 == last2) return copy_backward(first1, ++last1, result);
-           --last2;
-       }
-    }
-}
-
-template <class BidirectionalIterator, class Distance, class Pointer>
-void __merge_adaptive(BidirectionalIterator first, 
-                     BidirectionalIterator middle, 
-                     BidirectionalIterator last, Distance len1, Distance len2,
-                     Pointer buffer, Distance buffer_size) {
-    if (len1 <= len2 && len1 <= buffer_size) {
-        Pointer end_buffer = copy(first, middle, buffer);
-        merge(buffer, end_buffer, middle, last, first);
-    } else if (len2 <= buffer_size) {
-        Pointer end_buffer = copy(middle, last, buffer);
-        __merge_backward(first, middle, buffer, end_buffer, last);
-    } else {
-       BidirectionalIterator first_cut = first;
-       BidirectionalIterator second_cut = middle;
-       Distance len11 = 0;
-       Distance len22 = 0;
-       if (len1 > len2) {
-           len11 = len1 / 2;
-           advance(first_cut, len11);
-           second_cut = lower_bound(middle, last, *first_cut);
-           distance(middle, second_cut, len22);   
-       } else {
-           len22 = len2 / 2;
-           advance(second_cut, len22);
-           first_cut = upper_bound(first, middle, *second_cut);
-           distance(first, first_cut, len11);
-       }
-       BidirectionalIterator new_middle =
-           __rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
-                             len22, buffer, buffer_size);
-       __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,
-                        buffer_size);
-       __merge_adaptive(new_middle, second_cut, last, len1 - len11,
-                        len2 - len22, buffer, buffer_size);
-    }
-}
-
-template <class BidirectionalIterator, class Distance, class Pointer,
-         class Compare>
-void __merge_adaptive(BidirectionalIterator first, 
-                     BidirectionalIterator middle, 
-                     BidirectionalIterator last, Distance len1, Distance len2,
-                     Pointer buffer, Distance buffer_size, Compare comp) {
-    if (len1 <= len2 && len1 <= buffer_size) {
-       Pointer end_buffer = copy(first, middle, buffer);
-       merge(buffer, end_buffer, middle, last, first, comp);
-    } else if (len2 <= buffer_size) {
-       Pointer end_buffer = copy(middle, last, buffer);
-       __merge_backward(first, middle, buffer, end_buffer, last, comp);
-    } else {
-       BidirectionalIterator first_cut = first;
-       BidirectionalIterator second_cut = middle;
-       Distance len11 = 0;
-       Distance len22 = 0;
-       if (len1 > len2) {
-           len11 = len1 / 2;
-           advance(first_cut, len11);
-           second_cut = lower_bound(middle, last, *first_cut, comp);
-           distance(middle, second_cut, len22);   
-       } else {
-           len22 = len2 / 2;
-           advance(second_cut, len22);
-           first_cut = upper_bound(first, middle, *second_cut, comp);
-           distance(first, first_cut, len11);
-       }
-       BidirectionalIterator new_middle =
-           __rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
-                             len22, buffer, buffer_size);
-       __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,
-                        buffer_size, comp);
-       __merge_adaptive(new_middle, second_cut, last, len1 - len11,
-                        len2 - len22, buffer, buffer_size, comp);
-    }
-}
-
-template <class BidirectionalIterator, class T, class Distance>
-inline void __inplace_merge_aux(BidirectionalIterator first,
-                               BidirectionalIterator middle,
-                               BidirectionalIterator last, T*, Distance*) {
-    Distance len1 = 0;
-    distance(first, middle, len1);
-    Distance len2 = 0;
-    distance(middle, last, len2);
-
-    temporary_buffer<BidirectionalIterator, T> buf(first, last);
-    if (buf.begin() == 0)
-      __merge_without_buffer(first, middle, last, len1, len2);
-    else
-      __merge_adaptive(first, middle, last, len1, len2,
-                       buf.begin(), Distance(buf.size()));
-}
-
-template <class BidirectionalIterator, class T, class Distance, class Compare>
-inline void __inplace_merge_aux(BidirectionalIterator first,
-                               BidirectionalIterator middle,
-                               BidirectionalIterator last, T*, Distance*,
-                               Compare comp) {
-    Distance len1 = 0;
-    distance(first, middle, len1);
-    Distance len2 = 0;
-    distance(middle, last, len2);
-
-    temporary_buffer<BidirectionalIterator, T> buf(first, last);
-    if (buf.begin() == 0)
-      __merge_without_buffer(first, middle, last, len1, len2, comp);
-    else
-      __merge_adaptive(first, middle, last, len1, len2,
-                       buf.begin(), Distance(buf.size()),
-                       comp);
-}
-
-template <class BidirectionalIterator>
-inline void inplace_merge(BidirectionalIterator first,
-                         BidirectionalIterator middle,
-                         BidirectionalIterator last) {
-    if (first == middle || middle == last) return;
-    __inplace_merge_aux(first, middle, last, value_type(first),
-                       distance_type(first));
-}
-
-template <class BidirectionalIterator, class Compare>
-inline void inplace_merge(BidirectionalIterator first,
-                         BidirectionalIterator middle,
-                         BidirectionalIterator last, Compare comp) {
-    if (first == middle || middle == last) return;
-    __inplace_merge_aux(first, middle, last, value_type(first),
-                       distance_type(first), comp);
-}
-
-template <class InputIterator1, class InputIterator2>
-bool includes(InputIterator1 first1, InputIterator1 last1,
-             InputIterator2 first2, InputIterator2 last2) {
-    while (first1 != last1 && first2 != last2)
-       if (*first2 < *first1)
-           return false;
-       else if(*first1 < *first2) 
-           ++first1;
-       else
-           ++first1, ++first2;
-
-    return first2 == last2;
-}
-
-template <class InputIterator1, class InputIterator2, class Compare>
-bool includes(InputIterator1 first1, InputIterator1 last1,
-             InputIterator2 first2, InputIterator2 last2, Compare comp) {
-    while (first1 != last1 && first2 != last2)
-       if (comp(*first2, *first1))
-           return false;
-       else if(comp(*first1, *first2)) 
-           ++first1;
-       else
-           ++first1, ++first2;
-
-    return first2 == last2;
-}
-
-template <class InputIterator1, class InputIterator2, class OutputIterator>
-OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
-                         InputIterator2 first2, InputIterator2 last2,
-                         OutputIterator result) {
-  while (first1 != last1 && first2 != last2) {
-    if (*first1 < *first2) {
-      *result = *first1;
-      ++first1;
-    }
-    else if (*first2 < *first1) {
-      *result = *first2;
-      ++first2;
-    }
-    else {
-      *result = *first1;
-      ++first1;
-      ++first2;
-    }
-    ++result;
-  }
-  return copy(first2, last2, copy(first1, last1, result));
-}
-
-template <class InputIterator1, class InputIterator2, class OutputIterator,
-          class Compare>
-OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
-                         InputIterator2 first2, InputIterator2 last2,
-                         OutputIterator result, Compare comp) {
-  while (first1 != last1 && first2 != last2) {
-    if (comp(*first1, *first2)) {
-      *result = *first1;
-      ++first1;
-    }
-    else if (comp(*first2, *first1)) {
-      *result = *first2;
-      ++first2;
-    }
-    else {
-      *result = *first1;
-      ++first1;
-      ++first2;
-    }
-    ++result;
-  }
-  return copy(first2, last2, copy(first1, last1, result));
-}
-
-template <class InputIterator1, class InputIterator2, class OutputIterator>
-OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
-                                InputIterator2 first2, InputIterator2 last2,
-                                OutputIterator result) {
-  while (first1 != last1 && first2 != last2) 
-    if (*first1 < *first2) 
-      ++first1;
-    else if (*first2 < *first1) 
-      ++first2;
-    else {
-      *result = *first1;
-      ++first1;
-      ++first2;
-      ++result;
-    }
-  return result;
-}
-
-template <class InputIterator1, class InputIterator2, class OutputIterator,
-          class Compare>
-OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
-                                InputIterator2 first2, InputIterator2 last2,
-                                OutputIterator result, Compare comp) {
-  while (first1 != last1 && first2 != last2)
-    if (comp(*first1, *first2))
-      ++first1;
-    else if (comp(*first2, *first1))
-      ++first2;
-    else {
-      *result = *first1;
-      ++first1;
-      ++first2;
-      ++result;
-    }
-  return result;
-}
-
-template <class InputIterator1, class InputIterator2, class OutputIterator>
-OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
-                              InputIterator2 first2, InputIterator2 last2,
-                              OutputIterator result) {
-  while (first1 != last1 && first2 != last2)
-    if (*first1 < *first2) {
-      *result = *first1;
-      ++first1;
-      ++result;
-    }
-    else if (*first2 < *first1)
-      ++first2;
-    else {
-      ++first1;
-      ++first2;
-    }
-  return copy(first1, last1, result);
-}
-
-template <class InputIterator1, class InputIterator2, class OutputIterator, 
-          class Compare>
-OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
-                              InputIterator2 first2, InputIterator2 last2, 
-                              OutputIterator result, Compare comp) {
-  while (first1 != last1 && first2 != last2)
-    if (comp(*first1, *first2)) {
-      *result = *first1;
-      ++first1;
-      ++result;
-    }
-    else if (comp(*first2, *first1))
-      ++first2;
-    else {
-      ++first1;
-      ++first2;
-    }
-  return copy(first1, last1, result);
-}
-
-template <class InputIterator1, class InputIterator2, class OutputIterator>
-OutputIterator set_symmetric_difference(InputIterator1 first1,
-                                        InputIterator1 last1,
-                                        InputIterator2 first2,
-                                        InputIterator2 last2,
-                                        OutputIterator result) {
-  while (first1 != last1 && first2 != last2)
-    if (*first1 < *first2) {
-      *result = *first1;
-      ++first1;
-      ++result;
-    }
-    else if (*first2 < *first1) {
-      *result = *first2;
-      ++first2;
-      ++result;
-    }
-    else {
-      ++first1;
-      ++first2;
-    }
-  return copy(first2, last2, copy(first1, last1, result));
-}
-
-template <class InputIterator1, class InputIterator2, class OutputIterator,
-          class Compare>
-OutputIterator set_symmetric_difference(InputIterator1 first1,
-                                        InputIterator1 last1,
-                                        InputIterator2 first2,
-                                        InputIterator2 last2,
-                                        OutputIterator result, Compare comp) {
-  while (first1 != last1 && first2 != last2)
-    if (comp(*first1, *first2)) {
-      *result = *first1;
-      ++first1;
-      ++result;
-    }
-    else if (comp(*first2, *first1)) {
-      *result = *first2;
-      ++first2;
-      ++result;
-    }
-    else {
-      ++first1;
-      ++first2;
-    }
-  return copy(first2, last2, copy(first1, last1, result));
-}
-
-template <class ForwardIterator>
-ForwardIterator max_element(ForwardIterator first, ForwardIterator last) {
-    if (first == last) return first;
-    ForwardIterator result = first;
-    while (++first != last) 
-       if (*result < *first) result = first;
-    return result;
-}
-
-template <class ForwardIterator, class Compare>
-ForwardIterator max_element(ForwardIterator first, ForwardIterator last,
-                           Compare comp) {
-    if (first == last) return first;
-    ForwardIterator result = first;
-    while (++first != last) 
-       if (comp(*result, *first)) result = first;
-    return result;
-}
-
-template <class ForwardIterator>
-ForwardIterator min_element(ForwardIterator first, ForwardIterator last) {
-    if (first == last) return first;
-    ForwardIterator result = first;
-    while (++first != last) 
-       if (*first < *result) result = first;
-    return result;
-}
-
-template <class ForwardIterator, class Compare>
-ForwardIterator min_element(ForwardIterator first, ForwardIterator last,
-                           Compare comp) {
-    if (first == last) return first;
-    ForwardIterator result = first;
-    while (++first != last) 
-       if (comp(*first, *result)) result = first;
-    return result;
-}
-
-template <class BidirectionalIterator>
-bool next_permutation(BidirectionalIterator first,
-                     BidirectionalIterator last) {
-    if (first == last) return false;
-    BidirectionalIterator i = first;
-    ++i;
-    if (i == last) return false;
-    i = last;
-    --i;
-
-    for(;;) {
-       BidirectionalIterator ii = i;
-        --i;
-       if (*i < *ii) {
-           BidirectionalIterator j = last;
-           while (!(*i < *--j));
-           iter_swap(i, j);
-           reverse(ii, last);
-           return true;
-       }
-       if (i == first) {
-           reverse(first, last);
-           return false;
-       }
-    }
-}
-
-template <class BidirectionalIterator, class Compare>
-bool next_permutation(BidirectionalIterator first, BidirectionalIterator last,
-                     Compare comp) {
-    if (first == last) return false;
-    BidirectionalIterator i = first;
-    ++i;
-    if (i == last) return false;
-    i = last;
-    --i;
-
-    for(;;) {
-       BidirectionalIterator ii = i;
-        --i;
-       if (comp(*i, *ii)) {
-           BidirectionalIterator j = last;
-           while (!comp(*i, *--j));
-           iter_swap(i, j);
-           reverse(ii, last);
-           return true;
-       }
-       if (i == first) {
-           reverse(first, last);
-           return false;
-       }
-    }
-}
-
-template <class BidirectionalIterator>
-bool prev_permutation(BidirectionalIterator first,
-                     BidirectionalIterator last) {
-    if (first == last) return false;
-    BidirectionalIterator i = first;
-    ++i;
-    if (i == last) return false;
-    i = last;
-    --i;
-
-    for(;;) {
-       BidirectionalIterator ii = i;
-        --i;
-       if (*ii < *i) {
-           BidirectionalIterator j = last;
-           while (!(*--j < *i));
-           iter_swap(i, j);
-           reverse(ii, last);
-           return true;
-       }
-       if (i == first) {
-           reverse(first, last);
-           return false;
-       }
-    }
-}
-
-template <class BidirectionalIterator, class Compare>
-bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last,
-                     Compare comp) {
-    if (first == last) return false;
-    BidirectionalIterator i = first;
-    ++i;
-    if (i == last) return false;
-    i = last;
-    --i;
-
-    for(;;) {
-       BidirectionalIterator ii = i;
-        --i;
-       if (comp(*ii, *i)) {
-           BidirectionalIterator j = last;
-           while (!comp(*--j, *i));
-           iter_swap(i, j);
-           reverse(ii, last);
-           return true;
-       }
-       if (i == first) {
-           reverse(first, last);
-           return false;
-       }
-    }
-}
-
-template <class InputIterator, class T>
-T accumulate(InputIterator first, InputIterator last, T init) {
-  for ( ; first != last; ++first)
-    init = init + *first;
-  return init;
-}
-
-template <class InputIterator, class T, class BinaryOperation>
-T accumulate(InputIterator first, InputIterator last, T init,
-             BinaryOperation binary_op) {
-  for ( ; first != last; ++first)
-    init = binary_op(init, *first);
-  return init;
-}
-
-template <class InputIterator1, class InputIterator2, class T>
-T inner_product(InputIterator1 first1, InputIterator1 last1,
-                InputIterator2 first2, T init) {
-  for ( ; first1 != last1; ++first1, ++first2)
-    init = init + (*first1 * *first2);
-  return init;
-}
-
-template <class InputIterator1, class InputIterator2, class T,
-          class BinaryOperation1, class BinaryOperation2>
-T inner_product(InputIterator1 first1, InputIterator1 last1,
-                InputIterator2 first2, T init, BinaryOperation1 binary_op1,
-                BinaryOperation2 binary_op2) {
-  for ( ; first1 != last1; ++first1, ++first2)
-    init = binary_op1(init, binary_op2(*first1, *first2));
-  return init;
-}
-
-template <class InputIterator, class OutputIterator, class T>
-OutputIterator __partial_sum(InputIterator first, InputIterator last,
-                            OutputIterator result, T*) {
-    T value = *first;
-    while (++first != last) {
-       value = value + *first;
-       *++result = value;
-    }
-    return ++result;
-}
-
-template <class InputIterator, class OutputIterator>
-OutputIterator partial_sum(InputIterator first, InputIterator last,
-                          OutputIterator result) {
-    if (first == last) return result;
-    *result = *first;
-    return __partial_sum(first, last, result, value_type(first));
-}
-
-template <class InputIterator, class OutputIterator, class T,
-         class BinaryOperation>
-OutputIterator __partial_sum(InputIterator first, InputIterator last,
-                            OutputIterator result, T*,
-                            BinaryOperation binary_op) {
-    T value = *first;
-    while (++first != last) {
-       value = binary_op(value, *first);
-       *++result = value;
-    }
-    return ++result;
-}
-
-template <class InputIterator, class OutputIterator, class BinaryOperation>
-OutputIterator partial_sum(InputIterator first, InputIterator last,
-                          OutputIterator result, BinaryOperation binary_op) {
-    if (first == last) return result;
-    *result = *first;
-    return __partial_sum(first, last, result, value_type(first), binary_op);
-}
-
-template <class InputIterator, class OutputIterator, class T>
-OutputIterator __adjacent_difference(InputIterator first, InputIterator last, 
-                                    OutputIterator result, T*) {
-    T value = *first;
-    while (++first != last) {
-       T tmp = *first;
-       *++result = tmp - value;
-       value = tmp;
-    }
-    return ++result;
-}
-
-template <class InputIterator, class OutputIterator>
-OutputIterator adjacent_difference(InputIterator first, InputIterator last, 
-                                  OutputIterator result) {
-    if (first == last) return result;
-    *result = *first;
-    return __adjacent_difference(first, last, result, value_type(first));
-}
-
-template <class InputIterator, class OutputIterator, class T, 
-         class BinaryOperation>
-OutputIterator __adjacent_difference(InputIterator first, InputIterator last, 
-                                    OutputIterator result, T*,
-                                    BinaryOperation binary_op) {
-    T value = *first;
-    while (++first != last) {
-       T tmp = *first;
-       *++result = binary_op(tmp, value);
-       value = tmp;
-    }
-    return ++result;
-}
-
-template <class InputIterator, class OutputIterator, class BinaryOperation>
-OutputIterator adjacent_difference(InputIterator first, InputIterator last,
-                                  OutputIterator result,
-                                  BinaryOperation binary_op) {
-    if (first == last) return result;
-    *result = *first;
-    return __adjacent_difference(first, last, result, value_type(first),
-                                binary_op);
-}
-
-template <class InputIterator, class ForwardIterator>
-InputIterator find_first_of(InputIterator first1, InputIterator last1,
-                            ForwardIterator first2, ForwardIterator last2)
-{
-  for ( ; first1 != last1; ++first1) 
-    for (ForwardIterator iter = first2; iter != last2; ++iter)
-      if (*first1 == *iter)
-        return first1;
-  return last1;
-}
-
-template <class InputIterator, class ForwardIterator, class BinaryPredicate>
-InputIterator find_first_of(InputIterator first1, InputIterator last1,
-                            ForwardIterator first2, ForwardIterator last2,
-                            BinaryPredicate comp)
-{
-  for ( ; first1 != last1; ++first1) 
-    for (ForwardIterator iter = first2; iter != last2; ++iter)
-      if (comp(*first1, *iter))
-        return first1;
-  return last1;
-}
-
-
-// Search [first2, last2) as a subsequence in [first1, last1).
-
-// find_end for forward iterators. 
-template <class ForwardIterator1, class ForwardIterator2>
-ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1,
-                            ForwardIterator2 first2, ForwardIterator2 last2,
-                            forward_iterator_tag, forward_iterator_tag)
-{
-  if (first2 == last2)
-    return last1;
-  else {
-    ForwardIterator1 result = last1;
-    while (1) {
-      ForwardIterator1 new_result = search(first1, last1, first2, last2);
-      if (new_result == last1)
-        return result;
-      else {
-        result = new_result;
-        first1 = new_result;
-        ++first1;
-      }
-    }
-  }
-}
-
-template <class ForwardIterator1, class ForwardIterator2,
-          class BinaryPredicate>
-ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1,
-                            ForwardIterator2 first2, ForwardIterator2 last2,
-                            forward_iterator_tag, forward_iterator_tag,
-                            BinaryPredicate comp)
-{
-  if (first2 == last2)
-    return last1;
-  else {
-    ForwardIterator1 result = last1;
-    while (1) {
-      ForwardIterator1 new_result = search(first1, last1, first2, last2, comp);
-      if (new_result == last1)
-        return result;
-      else {
-        result = new_result;
-        first1 = new_result;
-        ++first1;
-      }
-    }
-  }
-}
-
-// find_end for bidirectional iterators.  Requires partial specialization.
-#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-template <class BidirectionalIterator1, class BidirectionalIterator2>
-BidirectionalIterator1
-__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
-           BidirectionalIterator2 first2, BidirectionalIterator2 last2,
-           bidirectional_iterator_tag, bidirectional_iterator_tag)
-{
-  typedef reverse_iterator<BidirectionalIterator1> reviter1;
-  typedef reverse_iterator<BidirectionalIterator2> reviter2;
-
-  reviter1 rlast1(first1);
-  reviter2 rlast2(first2);
-  reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2);
-
-  if (rresult == rlast1)
-    return last1;
-  else {
-    BidirectionalIterator1 result = rresult.base();
-    advance(result, -distance(first2, last2));
-    return result;
-  }
-}
-
-template <class BidirectionalIterator1, class BidirectionalIterator2,
-          class BinaryPredicate>
-BidirectionalIterator1
-__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
-           BidirectionalIterator2 first2, BidirectionalIterator2 last2,
-           bidirectional_iterator_tag, bidirectional_iterator_tag, 
-           BinaryPredicate comp)
-{
-  typedef reverse_iterator<BidirectionalIterator1> reviter1;
-  typedef reverse_iterator<BidirectionalIterator2> reviter2;
-
-  reviter1 rlast1(first1);
-  reviter2 rlast2(first2);
-  reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2,
-                            comp);
-
-  if (rresult == rlast1)
-    return last1;
-  else {
-    BidirectionalIterator1 result = rresult.base();
-    advance(result, -distance(first2, last2));
-    return result;
-  }
-}
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-// Dispatching functions.
-
-template <class ForwardIterator, class BidirectionalIterator>
-inline ForwardIterator 
-__find_end(ForwardIterator first1, ForwardIterator last1, 
-           BidirectionalIterator first2, BidirectionalIterator last2,
-           forward_iterator_tag, bidirectional_iterator_tag)
-{
-  return __find_end(first1, last1, first2, last2,
-                    forward_iterator_tag(), forward_iterator_tag());
-}
-template <class BidirectionalIterator, class ForwardIterator>
-inline BidirectionalIterator
-__find_end(BidirectionalIterator first1, BidirectionalIterator last1, 
-           ForwardIterator first2, ForwardIterator last2,
-           bidirectional_iterator_tag, forward_iterator_tag)
-{
-  return __find_end(first1, last1, first2, last2,
-                    forward_iterator_tag(), forward_iterator_tag());
-}
-
-template <class ForwardIterator, class BidirectionalIterator,
-          class BinaryPredicate>
-inline ForwardIterator 
-__find_end(ForwardIterator first1, ForwardIterator last1, 
-           BidirectionalIterator first2, BidirectionalIterator last2,
-           forward_iterator_tag, bidirectional_iterator_tag,
-           BinaryPredicate comp)
-{
-  return __find_end(first1, last1, first2, last2,
-                    forward_iterator_tag(), forward_iterator_tag(),
-                    comp);
-
-}
-template <class BidirectionalIterator, class ForwardIterator,
-          class BinaryPredicate>
-inline BidirectionalIterator
-__find_end(BidirectionalIterator first1, BidirectionalIterator last1, 
-           ForwardIterator first2, ForwardIterator last2,
-           bidirectional_iterator_tag, forward_iterator_tag, 
-           BinaryPredicate comp)
-{
-  return __find_end(first1, last1, first2, last2,
-                    forward_iterator_tag(), forward_iterator_tag(),
-                    comp);
-}
-
-template <class ForwardIterator1, class ForwardIterator2>
-inline ForwardIterator1 
-find_end(ForwardIterator1 first1, ForwardIterator1 last1, 
-         ForwardIterator2 first2, ForwardIterator2 last2)
-{
-#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
-  return __find_end(first1, last1, first2, last2,
-                    iterator_traits<ForwardIterator1>::iterator_category(),
-                    iterator_traits<ForwardIterator2>::iterator_category());
-#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-  return __find_end(first1, last1, first2, last2,
-                    forward_iterator_tag(), forward_iterator_tag());
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-}
-
-template <class ForwardIterator1, class ForwardIterator2, 
-          class BinaryPredicate>
-inline ForwardIterator1 
-find_end(ForwardIterator1 first1, ForwardIterator1 last1, 
-         ForwardIterator2 first2, ForwardIterator2 last2,
-         BinaryPredicate comp)
-{
-#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
-  return __find_end(first1, last1, first2, last2,
-                    iterator_traits<ForwardIterator1>::iterator_category(),
-                    iterator_traits<ForwardIterator2>::iterator_category(),
-                    comp);
-#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-  return __find_end(first1, last1, first2, last2,
-                    forward_iterator_tag(), forward_iterator_tag(),
-                    comp);
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-}
-
-// Returns x ** n, where n >= 0.  Note that "multiplication"
-//  is required to be associative, but not necessarily commutative.
-    
-template <class T, class Integer, class MonoidOperation>
-T power(T x, Integer n, MonoidOperation op) {
-  if (n == 0)
-    return identity_element(op);
-  else {
-    while ((n & 1) == 0) {
-      n >>= 1;
-      x = op(x, x);
-    }
-
-    T result = x;
-    n >>= 1;
-    while (n != 0) {
-      x = op(x, x);
-      if ((n & 1) != 0)
-        result = op(result, x);
-      n >>= 1;
-    }
-    return result;
-  }
-}
-
-template <class T, class Integer>
-inline T power(T x, Integer n) {
-  return power(x, n, multiplies<T>());
-}
-
-
-template <class ForwardIterator, class T>
-void iota(ForwardIterator first, ForwardIterator last, T value) {
-    while (first != last) *first++ = value++;
-}
-
-template <class RandomAccessIterator, class Distance>
-bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,
-               Distance*)
-{
-  const Distance n = last - first;
-
-  Distance parent = 0;
-  for (Distance child = 1; child < n; ++child) {
-    if (first[parent] < first[child]) 
-      return false;
-    if (child % 2 == 0)
-      ++parent;
-  }
-  return true;
-}
-
-template <class RandomAccessIterator>
-inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last)
-{
-  return __is_heap(first, last, distance_type(first));
-}
-
-
-template <class RandomAccessIterator, class Distance, class StrictWeakOrdering>
-bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,
-               StrictWeakOrdering comp,
-               Distance*)
-{
-  const Distance n = last - first;
-
-  Distance parent = 0;
-  for (Distance child = 1; child < n; ++child) {
-    if (comp(first[parent], first[child]))
-      return false;
-    if (child % 2 == 0)
-      ++parent;
-  }
-  return true;
-}
-
-template <class RandomAccessIterator, class StrictWeakOrdering>
-inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last,
-                    StrictWeakOrdering comp)
-{
-  return __is_heap(first, last, comp, distance_type(first));
-}
-
-
-template <class ForwardIterator>
-bool is_sorted(ForwardIterator first, ForwardIterator last)
-{
-  if (first == last)
-    return true;
-
-  ForwardIterator next = first;
-  for (++next; next != last; first = next, ++next) {
-    if (*next < *first)
-      return false;
-  }
-
-  return true;
-}
-
-template <class ForwardIterator, class StrictWeakOrdering>
-bool is_sorted(ForwardIterator first, ForwardIterator last,
-               StrictWeakOrdering comp)
-{
-  if (first == last)
-    return true;
-
-  ForwardIterator next = first;
-  for (++next; next != last; first = next, ++next) {
-    if (comp(*next, *first))
-      return false;
-  }
-
-  return true;
-}
-
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-#pragma reset woff 1209
-#endif
+#include <stl_algo.h>
+#include <stl_numeric.h>
+
+#ifdef __STL_USE_NAMESPACES
+
+// Names from <stl_algo.h>
+using __STD::for_each; 
+using __STD::find; 
+using __STD::find_if; 
+using __STD::adjacent_find; 
+using __STD::count; 
+using __STD::count_if; 
+using __STD::search; 
+using __STD::search_n; 
+using __STD::swap_ranges; 
+using __STD::transform; 
+using __STD::replace; 
+using __STD::replace_if; 
+using __STD::replace_copy; 
+using __STD::replace_copy_if; 
+using __STD::generate; 
+using __STD::generate_n; 
+using __STD::remove; 
+using __STD::remove_if; 
+using __STD::remove_copy; 
+using __STD::remove_copy_if; 
+using __STD::unique; 
+using __STD::unique_copy; 
+using __STD::reverse; 
+using __STD::reverse_copy; 
+using __STD::rotate; 
+using __STD::rotate_copy; 
+using __STD::random_shuffle; 
+using __STD::random_sample; 
+using __STD::random_sample_n; 
+using __STD::partition; 
+using __STD::stable_partition; 
+using __STD::sort; 
+using __STD::stable_sort; 
+using __STD::partial_sort; 
+using __STD::partial_sort_copy; 
+using __STD::nth_element; 
+using __STD::lower_bound; 
+using __STD::upper_bound; 
+using __STD::equal_range; 
+using __STD::binary_search; 
+using __STD::merge; 
+using __STD::inplace_merge; 
+using __STD::includes; 
+using __STD::set_union; 
+using __STD::set_intersection; 
+using __STD::set_difference; 
+using __STD::set_symmetric_difference; 
+using __STD::min_element; 
+using __STD::max_element; 
+using __STD::next_permutation; 
+using __STD::prev_permutation; 
+using __STD::find_first_of; 
+using __STD::find_end; 
+using __STD::is_sorted; 
+using __STD::is_heap; 
+
+// Names from stl_heap.h
+using __STD::push_heap;
+using __STD::pop_heap;
+using __STD::make_heap;
+using __STD::sort_heap;
+
+// Names from <stl_numeric.h>
+using __STD::accumulate; 
+using __STD::inner_product; 
+using __STD::partial_sum; 
+using __STD::adjacent_difference; 
+using __STD::power; 
+using __STD::iota; 
+
+#endif /* __STL_USE_NAMESPACES */
 
 #endif /* __SGI_STL_ALGO_H */
+
+// Local Variables:
+// mode:C++
+// End:
index eccf465..f35e7af 100644 (file)
@@ -11,8 +11,7 @@
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
  *
- *
- * Copyright (c) 1996
+ * Copyright (c) 1996,1997
  * Silicon Graphics Computer Systems, Inc.
  *
  * Permission to use, copy, modify, distribute and sell this software
  * purpose.  It is provided "as is" without express or implied warranty.
  */
 
-#ifndef _SGI_STL_ALGOBASE_H
-#define _SGI_STL_ALGOBASE_H
+#ifndef __SGI_STL_ALGOBASE_H
+#define __SGI_STL_ALGOBASE_H
 
-#include <string.h>
-#include <limits.h>
-#include <function.h>
+#ifndef __SGI_STL_PAIR_H
 #include <pair.h>
+#endif
+#ifndef __SGI_STL_ITERATOR_H
 #include <iterator.h>
-#include <new.h>
-#include <type_traits.h>
-
-template <class ForwardIterator1, class ForwardIterator2, class T>
-inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, T*) {
-    T tmp = *a;
-    *a = *b;
-    *b = tmp;
-}
-
-template <class ForwardIterator1, class ForwardIterator2>
-inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) {
-    __iter_swap(a, b, value_type(a));
-}
-
-template <class T>
-inline void swap(T& a, T& b) {
-    T tmp = a;
-    a = b;
-    b = tmp;
-}
-
-#ifdef __BORLANDC__
-#include <stdlib.h>
-#else
-
-template <class T>
-inline const T& min(const T& a, const T& b) {
-    return b < a ? b : a;
-}
-
-template <class T>
-inline const T& max(const T& a, const T& b) {
-    return  a < b ? b : a;
-}
-
 #endif
-
-template <class T, class Compare>
-inline const T& min(const T& a, const T& b, Compare comp) {
-    return comp(b, a) ? b : a;
-}
-
-template <class T, class Compare>
-inline const T& max(const T& a, const T& b, Compare comp) {
-    return comp(a, b) ? b : a;
-}
-
-template <class InputIterator, class Distance>
-inline void __distance(InputIterator first, InputIterator last, Distance& n, 
-                       input_iterator_tag) {
-    while (first != last) { ++first; ++n; }
-}
-
-template <class RandomAccessIterator, class Distance>
-inline void __distance(RandomAccessIterator first, RandomAccessIterator last, 
-                      Distance& n, random_access_iterator_tag) {
-    n += last - first;
-}
-
-template <class InputIterator, class Distance>
-inline void distance(InputIterator first, InputIterator last, Distance& n) {
-    __distance(first, last, n, iterator_category(first));
-}
-
-#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-template <class InputIterator>
-inline iterator_traits<InputIterator>::difference_type
-__distance(InputIterator first, InputIterator last, input_iterator_tag) {
-  iterator_traits<InputIterator>::difference_type n = 0;
-  while (first != last) {
-    ++first; ++n;
-  }
-  return n;
-}
-
-template <class RandomAccessIterator>
-inline iterator_traits<RandomAccessIterator>::difference_type
-__distance(RandomAccessIterator first, RandomAccessIterator last,
-           random_access_iterator_tag) {
-  return last - first;
-}
-
-template <class InputIterator>
-inline iterator_traits<InputIterator>::difference_type
-distance(InputIterator first, InputIterator last) {
-  return __distance(first, last,
-                    iterator_traits<InputIterator>::iterator_category());
-}
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-template <class InputIterator, class Distance>
-inline void __advance(InputIterator& i, Distance n, input_iterator_tag) {
-    while (n--) ++i;
-}
-
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-#pragma set woff 1183
+#ifndef __SGI_STL_INTERNAL_ALGOBASE_H
+#include <stl_algobase.h>
 #endif
-
-template <class BidirectionalIterator, class Distance>
-inline void __advance(BidirectionalIterator& i, Distance n, 
-                      bidirectional_iterator_tag) {
-    if (n >= 0)
-       while (n--) ++i;
-    else
-       while (n++) --i;
-}
-
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-#pragma reset woff 1183
+#ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H
+#include <stl_uninitialized.h>
 #endif
 
-template <class RandomAccessIterator, class Distance>
-inline void __advance(RandomAccessIterator& i, Distance n, 
-                     random_access_iterator_tag) {
-    i += n;
-}
-
-template <class InputIterator, class Distance>
-inline void advance(InputIterator& i, Distance n) {
-    __advance(i, n, iterator_category(i));
-}
-
-template <class InputIterator, class OutputIterator>
-inline OutputIterator __copy(InputIterator first, InputIterator last,
-                             OutputIterator result, input_iterator_tag)
-{
-  for ( ; first != last; ++result, ++first)
-    *result = *first;
-  return result;
-}
-
-template <class RandomAccessIterator, class OutputIterator, class Distance>
-inline OutputIterator
-__copy_d(RandomAccessIterator first, RandomAccessIterator last,
-         OutputIterator result, Distance*)
-{
-  for (Distance n = last - first; n > 0; --n, ++result, ++first) 
-    *result = *first;
-  return result;
-}
-
-template <class RandomAccessIterator, class OutputIterator>
-inline OutputIterator 
-__copy(RandomAccessIterator first, RandomAccessIterator last,
-       OutputIterator result, random_access_iterator_tag)
-{
-  return __copy_d(first, last, result, distance_type(first));
-}
-
-template <class InputIterator, class OutputIterator>
-struct __copy_dispatch
-{
-  OutputIterator operator()(InputIterator first, InputIterator last,
-                            OutputIterator result) {
-    return __copy(first, last, result, iterator_category(first));
-  }
-};
-
-#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 
-
-template <class T>
-inline T* __copy_t(const T* first, const T* last, T* result, __true_type) {
-  memmove(result, first, sizeof(T) * (last - first));
-  return result + (last - first);
-}
-
-template <class T>
-inline T* __copy_t(const T* first, const T* last, T* result, __false_type) {
-  return __copy_d(first, last, result, (ptrdiff_t*) 0);
-}
-
-template <class T>
-struct __copy_dispatch<T*, T*>
-{
-  T* operator()(T* first, T* last, T* result) {
-    return __copy_t(first, last, result,
-                    __type_traits<T>::has_trivial_assignment_operator());
-  }
-};
-
-template <class T>
-struct __copy_dispatch<const T*, T*>
-{
-  T* operator()(const T* first, const T* last, T* result) {
-    return __copy_t(first, last, result, 
-                    __type_traits<T>::has_trivial_assignment_operator());
-  }
-};
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-template <class InputIterator, class OutputIterator>
-inline OutputIterator copy(InputIterator first, InputIterator last,
-                           OutputIterator result)
-{
-  return __copy_dispatch<InputIterator,OutputIterator>()(first, last, result);
-}
-
-inline char* copy(const char* first, const char* last, char* result) {
-  memmove(result, first, last - first);
-  return result + (last - first);
-}
-
-inline wchar_t* copy(const wchar_t* first, const wchar_t* last,
-                     wchar_t* result) {
-  memmove(result, first, sizeof(wchar_t) * (last - first));
-  return result + (last - first);
-}
-
-template <class BidirectionalIterator1, class BidirectionalIterator2>
-inline BidirectionalIterator2 __copy_backward(BidirectionalIterator1 first, 
-                                              BidirectionalIterator1 last, 
-                                              BidirectionalIterator2 result) {
-  while (first != last) *--result = *--last;
-  return result;
-}
-
-
-template <class BidirectionalIterator1, class BidirectionalIterator2>
-struct __copy_backward_dispatch
-{
-  BidirectionalIterator2 operator()(BidirectionalIterator1 first, 
-                                    BidirectionalIterator1 last, 
-                                    BidirectionalIterator2 result) {
-    return __copy_backward(first, last, result);
-  }
-};
-
-#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 
-
-template <class T>
-inline T* __copy_backward_t(const T* first, const T* last, T* result,
-                            __true_type) {
-  const ptrdiff_t N = last - first;
-  memmove(result - N, first, sizeof(T) * N);
-  return result - N;
-}
-
-template <class T>
-inline T* __copy_backward_t(const T* first, const T* last, T* result,
-                            __false_type) {
-  return __copy_backward(first, last, result);
-}
-
-template <class T>
-struct __copy_backward_dispatch<T*, T*>
-{
-  T* operator()(T* first, T* last, T* result) {
-    return
-      __copy_backward_t(first, last, result,
-                        __type_traits<T>::has_trivial_assignment_operator());
-  }
-};
-
-template <class T>
-struct __copy_backward_dispatch<const T*, T*>
-{
-  T* operator()(const T* first, const T* last, T* result) {
-    return
-      __copy_backward_t(first, last, result,
-                        __type_traits<T>::has_trivial_assignment_operator());
-  }
-};
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-template <class BidirectionalIterator1, class BidirectionalIterator2>
-inline BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, 
-                                            BidirectionalIterator1 last, 
-                                            BidirectionalIterator2 result) {
-  return __copy_backward_dispatch<BidirectionalIterator1, 
-                                  BidirectionalIterator2>()(first, last, 
-                                                            result);
-}
-
-template <class InputIterator, class Size, class OutputIterator>
-OutputIterator __copy_n(InputIterator first, Size count,
-                        OutputIterator result,
-                        input_iterator_tag) {
-  for ( ; count > 0; --count, ++first, ++result)
-    *result = *first;
-  return result;
-}
-
-template <class RandomAccessIterator, class Size, class OutputIterator>
-inline OutputIterator __copy_n(RandomAccessIterator first, Size count,
-                               OutputIterator result,
-                               random_access_iterator_tag) {
-  return copy(first, first + count, result);
-}
-
-template <class InputIterator, class Size, class OutputIterator>
-inline OutputIterator copy_n(InputIterator first, Size count,
-                             OutputIterator result) {
-  return __copy_n(first, count, result, iterator_category(first));
-}
-
-template <class ForwardIterator, class T>
-void fill(ForwardIterator first, ForwardIterator last, const T& value) {
-  for ( ; first != last; ++first)
-    *first = value;
-}
-
-template <class OutputIterator, class Size, class T>
-OutputIterator fill_n(OutputIterator first, Size n, const T& value) {
-  for ( ; n > 0; --n, ++first)
-    *first = value;
-  return first;
-}
-
-template <class InputIterator1, class InputIterator2>
-pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1,
-                                             InputIterator1 last1,
-                                             InputIterator2 first2) {
-    while (first1 != last1 && *first1 == *first2) {
-       ++first1;
-       ++first2;
-    }
-    return pair<InputIterator1, InputIterator2>(first1, first2);
-}
-
-template <class InputIterator1, class InputIterator2, class BinaryPredicate>
-pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1,
-                                             InputIterator1 last1,
-                                             InputIterator2 first2,
-                                             BinaryPredicate binary_pred) {
-    while (first1 != last1 && binary_pred(*first1, *first2)) {
-       ++first1;
-       ++first2;
-    }
-    return pair<InputIterator1, InputIterator2>(first1, first2);
-}
-
-template <class InputIterator1, class InputIterator2>
-inline bool equal(InputIterator1 first1, InputIterator1 last1,
-                 InputIterator2 first2) {
-  for ( ; first1 != last1; ++first1, ++first2)
-    if (*first1 != *first2)
-      return false;
-  return true;
-}
-
-template <class InputIterator1, class InputIterator2, class BinaryPredicate>
-inline bool equal(InputIterator1 first1, InputIterator1 last1,
-                 InputIterator2 first2, BinaryPredicate binary_pred) {
-  for ( ; first1 != last1; ++first1, ++first2)
-    if (!binary_pred(*first1, *first2))
-      return false;
-  return true;
-}
-
-template <class InputIterator1, class InputIterator2>
-bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
-                            InputIterator2 first2, InputIterator2 last2) {
-  for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) {
-    if (*first1 < *first2)
-      return true;
-    if (*first2 < *first1)
-      return false;
-  }
-  return first1 == last1 && first2 != last2;
-}
-
-template <class InputIterator1, class InputIterator2, class Compare>
-bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
-                            InputIterator2 first2, InputIterator2 last2,
-                            Compare comp) {
-  for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) {
-    if (comp(*first1, *first2))
-      return true;
-    if (comp(*first2, *first1))
-      return false;
-  }
-  return first1 == last1 && first2 != last2;
-}
-
-inline bool 
-lexicographical_compare(const unsigned char* first1,
-                        const unsigned char* last1,
-                        const unsigned char* first2,
-                        const unsigned char* last2)
-{
-  const size_t len1 = last1 - first1;
-  const size_t len2 = last2 - first2;
-  const int result = memcmp(first1, first2, min(len1, len2));
-  return result != 0 ? result < 0 : len1 < len2;
-}
-
-inline bool lexicographical_compare(const char* first1, const char* last1,
-                                    const char* first2, const char* last2)
-{
-#if CHAR_MAX == SCHAR_MAX
-  return lexicographical_compare((const signed char*) first1,
-                                 (const signed char*) last1,
-                                 (const signed char*) first2,
-                                 (const signed char*) last2);
-#else
-  return lexicographical_compare((const unsigned char*) first1,
-                                 (const unsigned char*) last1,
-                                 (const unsigned char*) first2,
-                                 (const unsigned char*) last2);
-#endif
-}
-
-template <class InputIterator1, class InputIterator2>
-int lexicographical_compare_3way(InputIterator1 first1, InputIterator1 last1,
-                                 InputIterator2 first2, InputIterator2 last2)
-{
-    while (first1 != last1 && first2 != last2) {
-        if (*first1 < *first2) return -1;
-        if (*first2 < *first1) return 1;
-       ++first1; ++first2;
-    }
-    if (first2 == last2) {
-       return !(first1 == last1);
-    } else {
-        return -1;
-    }
-}
-
-inline int
-lexicographical_compare_3way(const unsigned char* first1,
-                             const unsigned char* last1,
-                             const unsigned char* first2,
-                             const unsigned char* last2)
-{
-  const int len1 = last1 - first1;
-  const int len2 = last2 - first2;
-  const int result = memcmp(first1, first2, min(len1, len2));
-  return result == 0 ?  len1 - len2 : result;
-}
-
-inline int lexicographical_compare_3way(const char* first1, const char* last1,
-                                        const char* first2, const char* last2)
-{
-#if CHAR_MAX == SCHAR_MAX
-  return lexicographical_compare_3way(
-                               (const signed char*) first1,
-                                (const signed char*) last1,
-                                (const signed char*) first2,
-                                (const signed char*) last2);
-#else
-  return lexicographical_compare_3way((const unsigned char*) first1,
-                                      (const unsigned char*) last1,
-                                      (const unsigned char*) first2,
-                                      (const unsigned char*) last2);
-#endif
-}
-
-template <class T>
-inline void destroy(T* pointer) {
-    pointer->~T();
-}
-
-template <class T1, class T2>
-inline void construct(T1* p, const T2& value) {
-    new (p) T1(value);
-}
-
-template <class ForwardIterator>
-inline void
-__destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) {
-  for ( ; first < last; ++first)
-    destroy(&*first);
-}
-
-template <class ForwardIterator> 
-inline void __destroy_aux(ForwardIterator, ForwardIterator, __true_type) {
-}
-
-template <class ForwardIterator, class T>
-inline void __destroy(ForwardIterator first, ForwardIterator last, T*) {
-  __destroy_aux(first, last, __type_traits<T>::has_trivial_destructor());
-}
-
-template <class ForwardIterator>
-inline void destroy(ForwardIterator first, ForwardIterator last) {
-  __destroy(first, last, value_type(first));
-}
-
-inline void destroy(char*, char*) {}
-inline void destroy(wchar_t*, wchar_t*) {}
-
-// Valid if copy construction is equivalent to assignment, and if the
-//  destructor is trivial.
-template <class InputIterator, class ForwardIterator>
-inline ForwardIterator 
-__uninitialized_copy_aux(InputIterator first, InputIterator last,
-                         ForwardIterator result,
-                         __true_type) {
-  return copy(first, last, result);
-}
-
-template <class InputIterator, class ForwardIterator>
-ForwardIterator 
-__uninitialized_copy_aux(InputIterator first, InputIterator last,
-                         ForwardIterator result,
-                         __false_type) {
-  ForwardIterator cur = result;
-#     ifdef __STL_USE_EXCEPTIONS
-  try {
-#     endif /* __STL_USE_EXCEPTIONS */
-    for ( ; first != last; ++first, ++cur)
-      construct(&*cur, *first);
-    return cur;
-#     ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    destroy(result, cur);
-    throw;
-  }
-#     endif /* __STL_USE_EXCEPTIONS */
-}
-
-
-template <class InputIterator, class ForwardIterator, class T>
-inline ForwardIterator
-__uninitialized_copy(InputIterator first, InputIterator last,
-                     ForwardIterator result, T*) {
-  return __uninitialized_copy_aux(first, last, result,
-                                  __type_traits<T>::is_POD_type());
-}
-
-template <class InputIterator, class ForwardIterator>
-inline ForwardIterator
-  uninitialized_copy(InputIterator first, InputIterator last,
-                     ForwardIterator result) {
-  return __uninitialized_copy(first, last, result, value_type(result));
-}
-
-inline char* uninitialized_copy(const char* first, const char* last,
-                                char* result) {
-  memmove(result, first, last - first);
-  return result + (last - first);
-}
-
-inline wchar_t* uninitialized_copy(const wchar_t* first, const wchar_t* last,
-                                   wchar_t* result) {
-  memmove(result, first, sizeof(wchar_t) * (last - first));
-  return result + (last - first);
-}
-
-template <class InputIterator, class Size, class ForwardIterator>
-ForwardIterator __uninitialized_copy_n(InputIterator first, Size count,
-                                       ForwardIterator result,
-                                       input_iterator_tag) {
-  ForwardIterator cur = result;
-#     ifdef __STL_USE_EXCEPTIONS
-  try {
-#     endif /* __STL_USE_EXCEPTIONS */
-    for ( ; count > 0 ; --count, ++first, ++cur) 
-      construct(&*cur, *first);
-    return cur;
-#     ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    destroy(result, cur);
-    throw;
-  }
-#     endif /* __STL_USE_EXCEPTIONS */
-}
-
-template <class RandomAccessIterator, class Size, class ForwardIterator>
-inline ForwardIterator
-__uninitialized_copy_n(RandomAccessIterator first, Size count,
-                       ForwardIterator result,
-                       random_access_iterator_tag) {
-  return uninitialized_copy(first, first + count, result);
-}
-
-template <class InputIterator, class Size, class ForwardIterator>
-inline ForwardIterator uninitialized_copy_n(InputIterator first, Size count,
-                                            ForwardIterator result) {
-  return __uninitialized_copy_n(first, count, result,
-                                iterator_category(first));
-}
-
-// Valid if copy construction is equivalent to assignment, and if the
-//  destructor is trivial.
-template <class ForwardIterator, class T>
-inline void
-__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, 
-                         const T& x, __true_type)
-{
-  fill(first, last, x);
-}
-
-template <class ForwardIterator, class T>
-void
-__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, 
-                         const T& x, __false_type)
-{
-  ForwardIterator cur = first;
-#     ifdef __STL_USE_EXCEPTIONS
-  try {
-#     endif /* __STL_USE_EXCEPTIONS */
-    for ( ; cur != last; ++cur)
-      construct(&*cur, x);
-#     ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    destroy(first, cur);
-    throw;
-  }
-#     endif /* __STL_USE_EXCEPTIONS */
-}
-
-template <class ForwardIterator, class T, class T1>
-inline void __uninitialized_fill(ForwardIterator first, ForwardIterator last, 
-                                 const T& x, T1*) {
-  __uninitialized_fill_aux(first, last, x,
-                           __type_traits<T1>::is_POD_type());
-}
-
-template <class ForwardIterator, class T>
-inline void uninitialized_fill(ForwardIterator first, ForwardIterator last, 
-                               const T& x) {
-  __uninitialized_fill(first, last, x, value_type(first));
-}
-
-// Valid if copy construction is equivalent to assignment, and if the
-//  destructor is trivial.
-template <class ForwardIterator, class Size, class T>
-inline ForwardIterator
-__uninitialized_fill_n_aux(ForwardIterator first, Size n,
-                           const T& x, __true_type) {
-  return fill_n(first, n, x);
-}
-
-template <class ForwardIterator, class Size, class T>
-ForwardIterator
-__uninitialized_fill_n_aux(ForwardIterator first, Size n,
-                           const T& x, __false_type) {
-  ForwardIterator cur = first;
-#     ifdef __STL_USE_EXCEPTIONS
-  try {
-#     endif /* __STL_USE_EXCEPTIONS */
-    for ( ; n > 0; --n, ++cur)
-      construct(&*cur, x);
-    return cur;
-#     ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    destroy(first, cur);
-    throw;
-  }
-#     endif /* __STL_USE_EXCEPTIONS */
-}
-
-template <class ForwardIterator, class Size, class T, class T1>
-inline ForwardIterator __uninitialized_fill_n(ForwardIterator first, Size n,
-                                              const T& x, T1*) {
-  return __uninitialized_fill_n_aux(first, n, x,
-                                    __type_traits<T1>::is_POD_type());
-}
-
-template <class ForwardIterator, class Size, class T>
-inline ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n,
-                                            const T& x) {
-  return __uninitialized_fill_n(first, n, x, value_type(first));
-}
-
-// Copies [first1, last1) into [result, result + (last1 - first1)), and
-//  copies [first2, last2) into
-//  [result, result + (last1 - first1) + (last2 - first2)).
-
-template <class InputIterator1, class InputIterator2, class ForwardIterator>
-inline ForwardIterator
-__uninitialized_copy_copy(InputIterator1 first1, InputIterator1 last1,
-                          InputIterator2 first2, InputIterator2 last2,
-                          ForwardIterator result) {
-  ForwardIterator mid = uninitialized_copy(first1, last1, result);
-#     ifdef __STL_USE_EXCEPTIONS
-  try {
-#     endif /* __STL_USE_EXCEPTIONS */
-    return uninitialized_copy(first2, last2, mid);
-#     ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    destroy(result, mid);
-    throw;
-  }
-#     endif /* __STL_USE_EXCEPTIONS */
-}
-
-// Fills [result, mid) with x, and copies [first, last) into
-//  [mid, mid + (last - first)).
-template <class ForwardIterator, class T, class InputIterator>
-inline ForwardIterator 
-__uninitialized_fill_copy(ForwardIterator result, ForwardIterator mid,
-                          const T& x,
-                          InputIterator first, InputIterator last) {
-  uninitialized_fill(result, mid, x);
-#     ifdef __STL_USE_EXCEPTIONS
-  try {
-#     endif /* __STL_USE_EXCEPTIONS */
-    return uninitialized_copy(first, last, mid);
-#     ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    destroy(result, mid);
-    throw;
-  }
-#     endif /* __STL_USE_EXCEPTIONS */
-}
-
-// Copies [first1, last1) into [first2, first2 + (last1 - first1)), and
-//  fills [first2 + (last1 - first1), last2) with x.
-template <class InputIterator, class ForwardIterator, class T>
-inline void
-__uninitialized_copy_fill(InputIterator first1, InputIterator last1,
-                          ForwardIterator first2, ForwardIterator last2,
-                          const T& x) {
-  ForwardIterator mid2 = uninitialized_copy(first1, last1, first2);
-#     ifdef __STL_USE_EXCEPTIONS
-  try {
-#     endif /* __STL_USE_EXCEPTIONS */
-    uninitialized_fill(mid2, last2, x);
-#     ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    destroy(first2, mid2);
-    throw;
-  }
-#     endif /* __STL_USE_EXCEPTIONS */
-}
-
-#endif /* _SGI_STL_ALGOBASE_H */
+#ifdef __STL_USE_NAMESPACES
+
+// Names from stl_algobase.h
+using __STD::iter_swap; 
+using __STD::swap; 
+using __STD::min; 
+using __STD::max; 
+using __STD::copy; 
+using __STD::copy_backward; 
+using __STD::copy_n; 
+using __STD::fill; 
+using __STD::fill_n; 
+using __STD::mismatch; 
+using __STD::equal; 
+using __STD::lexicographical_compare; 
+using __STD::lexicographical_compare_3way; 
+
+// Names from stl_uninitialized.h
+using __STD::uninitialized_copy;
+using __STD::uninitialized_copy_n;
+using __STD::uninitialized_fill;
+using __STD::uninitialized_fill_n;
+
+#endif /* __STL_USE_NAMESPACES */
+
+#endif /* __SGI_STL_ALGOBASE_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/algorithm b/libstdc++/stl/algorithm
new file mode 100644 (file)
index 0000000..515e9bd
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __SGI_STL_ALGORITHM
+#define __SGI_STL_ALGORITHM
+
+#include <stl_algobase.h>
+#include <stl_construct.h>
+#include <stl_tempbuf.h>
+#include <stl_algo.h>
+
+#endif /* __SGI_STL_ALGORITHM */
+
+// Local Variables:
+// mode:C++
+// End:
index 8831976..7cc9610 100644 (file)
  * purpose.  It is provided "as is" without express or implied warranty.
  */
 
-#ifndef __ALLOC_H
-#define __ALLOC_H
+#ifndef __SGI_STL_ALLOC_H
+#define __SGI_STL_ALLOC_H
 
+#ifndef __STL_CONFIG_H
 #include <stl_config.h>
-
-#ifdef __SUNPRO_CC
-#  define __PRIVATE public
-   // Extra access restrictions prevent us from really making some things
-   // private.
-#else
-#  define __PRIVATE private
-#endif
-
-#ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG
-#  define __USE_MALLOC
-#endif
-
-
-// This implements some standard node allocators.  These are
-// NOT the same as the allocators in the C++ draft standard or in
-// in the original STL.  They do not encapsulate different pointer
-// types; indeed we assume that there is only one pointer type.
-// The allocation primitives are intended to allocate individual objects,
-// not larger arenas as with the original STL allocators.
-
-#if 0
-#   include <new>
-#   define __THROW_BAD_ALLOC throw bad_alloc
-#elif !defined(__THROW_BAD_ALLOC)
-#   include <iostream.h>
-#   define __THROW_BAD_ALLOC cerr << "out of memory" << endl; exit(1)
-#endif
-
-#ifndef __ALLOC
-#   define __ALLOC alloc
-#endif
-#ifdef __STL_WIN32THREADS
-#   include <windows.h>
-#endif
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#ifndef __RESTRICT
-#  define __RESTRICT
 #endif
-
-#if !defined(_PTHREADS) && !defined(_NOTHREADS) \
- && !defined(__STL_SGI_THREADS) && !defined(__STL_WIN32THREADS)
-#   define _NOTHREADS
+#ifndef __SGI_STL_INTERNAL_ALLOC_H
+#include <stl_alloc.h>
 #endif
 
-# ifdef _PTHREADS
-    // POSIX Threads
-    // This is dubious, since this is likely to be a high contention
-    // lock.   Performance may not be adequate.
-#   include <pthread.h>
-#   define __NODE_ALLOCATOR_LOCK \
-        if (threads) pthread_mutex_lock(&__node_allocator_lock)
-#   define __NODE_ALLOCATOR_UNLOCK \
-        if (threads) pthread_mutex_unlock(&__node_allocator_lock)
-#   define __NODE_ALLOCATOR_THREADS true
-#   define __VOLATILE volatile  // Needed at -O3 on SGI
-# endif
-# ifdef __STL_WIN32THREADS
-    // The lock needs to be initialized by constructing an allocator
-    // objects of the right type.  We do that here explicitly for alloc.
-#   define __NODE_ALLOCATOR_LOCK \
-        EnterCriticalSection(&__node_allocator_lock)
-#   define __NODE_ALLOCATOR_UNLOCK \
-        LeaveCriticalSection(&__node_allocator_lock)
-#   define __NODE_ALLOCATOR_THREADS true
-#   define __VOLATILE volatile  // may not be needed
-# endif /* WIN32THREADS */
-# ifdef __STL_SGI_THREADS
-    // This should work without threads, with sproc threads, or with
-    // pthreads.  It is suboptimal in all cases.
-    // It is unlikely to even compile on nonSGI machines.
-
-    extern int __us_rsthread_malloc;
-       // The above is copied from malloc.h.  Including <malloc.h>
-       // would be cleaner but fails with certain levels of standard
-       // conformance.
-#   define __NODE_ALLOCATOR_LOCK if (threads && __us_rsthread_malloc) \
-                { __lock(&__node_allocator_lock); }
-#   define __NODE_ALLOCATOR_UNLOCK if (threads && __us_rsthread_malloc) \
-                { __unlock(&__node_allocator_lock); }
-#   define __NODE_ALLOCATOR_THREADS true
-#   define __VOLATILE volatile  // Needed at -O3 on SGI
-# endif
-# ifdef _NOTHREADS
-//  Thread-unsafe
-#   define __NODE_ALLOCATOR_LOCK
-#   define __NODE_ALLOCATOR_UNLOCK
-#   define __NODE_ALLOCATOR_THREADS false
-#   define __VOLATILE
-# endif
-
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-#pragma set woff 1174
-#endif
+#ifdef __STL_USE_NAMESPACES
 
-// Malloc-based allocator.  Typically slower than default alloc below.
-// Typically thread-safe and more storage efficient.
+using __STD::__malloc_alloc_template; 
+using __STD::malloc_alloc; 
+using __STD::simple_alloc; 
+using __STD::debug_alloc; 
+using __STD::__default_alloc_template; 
+using __STD::alloc; 
+using __STD::single_client_alloc; 
 #ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG
-# ifdef __DECLARE_GLOBALS_HERE
-    void (* __malloc_alloc_oom_handler)() = 0;
-    // g++ 2.7.2 does not handle static template data members.
-# else
-    extern void (* __malloc_alloc_oom_handler)();
-# endif
-#endif
-
-template <int inst>
-class __malloc_alloc_template {
-
-private:
-
-static void *oom_malloc(size_t);
-
-static void *oom_realloc(void *, size_t);
-
-#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG
-    static void (* __malloc_alloc_oom_handler)();
-#endif
-
-public:
-
-static void * allocate(size_t n)
-{
-    void *result = malloc(n);
-    if (0 == result) result = oom_malloc(n);
-    return result;
-}
-
-static void deallocate(void *p, size_t /* n */)
-{
-    free(p);
-}
-
-static void * reallocate(void *p, size_t /* old_sz */, size_t new_sz)
-{
-    void * result = realloc(p, new_sz);
-    if (0 == result) result = oom_realloc(p, new_sz);
-    return result;
-}
-
-static void (* set_malloc_handler(void (*f)()))()
-{
-    void (* old)() = __malloc_alloc_oom_handler;
-    __malloc_alloc_oom_handler = f;
-    return(old);
-}
-
-};
-
-// malloc_alloc out-of-memory handling
-
-#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG
-template <int inst>
-void (* __malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = 0;
-#endif
-
-template <int inst>
-void * __malloc_alloc_template<inst>::oom_malloc(size_t n)
-{
-    void (* my_malloc_handler)();
-    void *result;
-
-    for (;;) {
-        my_malloc_handler = __malloc_alloc_oom_handler;
-        if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; }
-        (*my_malloc_handler)();
-        result = malloc(n);
-        if (result) return(result);
-    }
-}
-
-template <int inst>
-void * __malloc_alloc_template<inst>::oom_realloc(void *p, size_t n)
-{
-    void (* my_malloc_handler)();
-    void *result;
-
-    for (;;) {
-        my_malloc_handler = __malloc_alloc_oom_handler;
-        if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; }
-        (*my_malloc_handler)();
-        result = realloc(p, n);
-        if (result) return(result);
-    }
-}
-
-typedef __malloc_alloc_template<0> malloc_alloc;
-
-template<class T, class Alloc>
-class simple_alloc {
-
-public:
-    static T *allocate(size_t n)
-                { return 0 == n? 0 : (T*) Alloc::allocate(n * sizeof (T)); }
-    static T *allocate(void)
-                { return (T*) Alloc::allocate(sizeof (T)); }
-    static void deallocate(T *p, size_t n)
-                { if (0 != n) Alloc::deallocate(p, n * sizeof (T)); }
-    static void deallocate(T *p)
-                { Alloc::deallocate(p, sizeof (T)); }
-};
-
-// Allocator adaptor to check size arguments for debugging.
-// Reports errors using assert.  Checking can be disabled with
-// NDEBUG, but it's far better to just use the underlying allocator
-// instead when no checking is desired.
-// There is some evidence that this can confuse Purify.
-template <class Alloc>
-class debug_alloc {
-
-private:
-
-enum {extra = 8};       // Size of space used to store size.  Note
-                        // that this must be large enough to preserve
-                        // alignment.
-
-public:
-
-static void * allocate(size_t n)
-{
-    char *result = (char *)Alloc::allocate(n + extra);
-    *(size_t *)result = n;
-    return result + extra;
-}
-
-static void deallocate(void *p, size_t n)
-{
-    char * real_p = (char *)p - extra;
-    assert(*(size_t *)real_p == n);
-    Alloc::deallocate(real_p, n + extra);
-}
-
-static void * reallocate(void *p, size_t old_sz, size_t new_sz)
-{
-    char * real_p = (char *)p - extra;
-    assert(*(size_t *)real_p == old_sz);
-    char * result = (char *)
-                  Alloc::reallocate(real_p, old_sz + extra, new_sz + extra);
-    *(size_t *)result = new_sz;
-    return result + extra;
-}
-
-
-};
-
-
-# ifdef __USE_MALLOC
-
-typedef malloc_alloc alloc;
-typedef malloc_alloc single_client_alloc;
+using __STD::__malloc_alloc_oom_handler; 
+#endif /* __STL_STATIC_TEMPLATE_MEMBER_BUG */
 
-# else
 
+#endif /* __STL_USE_NAMESPACES */
 
-// Default node allocator.
-// With a reasonable compiler, this should be roughly as fast as the
-// original STL class-specific allocators, but with less fragmentation.
-// Default_alloc_template parameters are experimental and MAY
-// DISAPPEAR in the future.  Clients should just use alloc for now.
-//
-// Important implementation properties:
-// 1. If the client request an object of size > __MAX_BYTES, the resulting
-//    object will be obtained directly from malloc.
-// 2. In all other cases, we allocate an object of size exactly
-//    ROUND_UP(requested_size).  Thus the client has enough size
-//    information that we can return the object to the proper free list
-//    without permanently losing part of the object.
-//
-
-// The first template parameter specifies whether more than one thread
-// may use this allocator.  It is safe to allocate an object from
-// one instance of a default_alloc and deallocate it with another
-// one.  This effectively transfers its ownership to the second one.
-// This may have undesirable effects on reference locality.
-// The second parameter is unreferenced and serves only to allow the
-// creation of multiple default_alloc instances.
-// Node that containers built on different allocator instances have
-// different types, limiting the utility of this approach.
-#ifdef __SUNPRO_CC
-// breaks if we make these template class members:
-  enum {__ALIGN = 8};
-  enum {__MAX_BYTES = 128};
-  enum {__NFREELISTS = __MAX_BYTES/__ALIGN};
-#endif
-
-template <bool threads, int inst>
-class __default_alloc_template {
-
-private:
-  // Really we should use static const int x = N
-  // instead of enum { x = N }, but few compilers accept the former.
-# ifndef __SUNPRO_CC
-    enum {__ALIGN = 8};
-    enum {__MAX_BYTES = 128};
-    enum {__NFREELISTS = __MAX_BYTES/__ALIGN};
-# endif
-  static size_t ROUND_UP(size_t bytes) {
-        return (((bytes) + __ALIGN-1) & ~(__ALIGN - 1));
-  }
-__PRIVATE:
-  union obj {
-        union obj * free_list_link;
-        char client_data[1];    /* The client sees this.        */
-  };
-private:
-# ifdef __SUNPRO_CC
-    static obj * __VOLATILE free_list[]; 
-        // Specifying a size results in duplicate def for 4.1
-# else
-    static obj * __VOLATILE free_list[__NFREELISTS]; 
-# endif
-  static  size_t FREELIST_INDEX(size_t bytes) {
-        return (((bytes) + __ALIGN-1)/__ALIGN - 1);
-  }
-
-  // Returns an object of size n, and optionally adds to size n free list.
-  static void *refill(size_t n);
-  // Allocates a chunk for nobjs of size size.  nobjs may be reduced
-  // if it is inconvenient to allocate the requested number.
-  static char *chunk_alloc(size_t size, int &nobjs);
-
-  // Chunk allocation state.
-  static char *start_free;
-  static char *end_free;
-  static size_t heap_size;
-
-# ifdef __STL_SGI_THREADS
-    static volatile unsigned long __node_allocator_lock;
-    static void __lock(volatile unsigned long *); 
-    static inline void __unlock(volatile unsigned long *);
-# endif
-
-# ifdef _PTHREADS
-    static pthread_mutex_t __node_allocator_lock;
-# endif
-
-# ifdef __STL_WIN32THREADS
-    static CRITICAL_SECTION __node_allocator_lock;
-    static bool __node_allocator_lock_initialized;
-
-  public:
-    __default_alloc_template() {
-       // This assumes the first constructor is called before threads
-       // are started.
-        if (!__node_allocator_lock_initialized) {
-            InitializeCriticalSection(&__node_allocator_lock);
-            __node_allocator_lock_initialized = true;
-        }
-    }
-  private:
-# endif
-
-    class lock {
-        public:
-            lock() { __NODE_ALLOCATOR_LOCK; }
-            ~lock() { __NODE_ALLOCATOR_UNLOCK; }
-    };
-    friend class lock;
-
-public:
-
-  /* n must be > 0      */
-  static void * allocate(size_t n)
-  {
-    obj * __VOLATILE * my_free_list;
-    obj * __RESTRICT result;
-
-    if (n > (size_t) __MAX_BYTES) {
-        return(malloc_alloc::allocate(n));
-    }
-    my_free_list = free_list + FREELIST_INDEX(n);
-    // Acquire the lock here with a constructor call.
-    // This ensures that it is released in exit or during stack
-    // unwinding.
-#       ifndef _NOTHREADS
-        /*REFERENCED*/
-        lock lock_instance;
-#       endif
-    result = *my_free_list;
-    if (result == 0) {
-        void *r = refill(ROUND_UP(n));
-        return r;
-    }
-    *my_free_list = result -> free_list_link;
-    return (result);
-  };
-
-  /* p may not be 0 */
-  static void deallocate(void *p, size_t n)
-  {
-    obj *q = (obj *)p;
-    obj * __VOLATILE * my_free_list;
-
-    if (n > (size_t) __MAX_BYTES) {
-        malloc_alloc::deallocate(p, n);
-        return;
-    }
-    my_free_list = free_list + FREELIST_INDEX(n);
-    // acquire lock
-#       ifndef _NOTHREADS
-        /*REFERENCED*/
-        lock lock_instance;
-#       endif /* _NOTHREADS */
-    q -> free_list_link = *my_free_list;
-    *my_free_list = q;
-    // lock is released here
-  }
-
-  static void * reallocate(void *p, size_t old_sz, size_t new_sz);
-
-} ;
-
-typedef __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0> alloc;
-typedef __default_alloc_template<false, 0> single_client_alloc;
-
-
-
-/* We allocate memory in large chunks in order to avoid fragmenting     */
-/* the malloc heap too much.                                            */
-/* We assume that size is properly aligned.                             */
-/* We hold the allocation lock.                                         */
-template <bool threads, int inst>
-char*
-__default_alloc_template<threads, inst>::chunk_alloc(size_t size, int& nobjs)
-{
-    char * result;
-    size_t total_bytes = size * nobjs;
-    size_t bytes_left = end_free - start_free;
-
-    if (bytes_left >= total_bytes) {
-        result = start_free;
-        start_free += total_bytes;
-        return(result);
-    } else if (bytes_left >= size) {
-        nobjs = bytes_left/size;
-        total_bytes = size * nobjs;
-        result = start_free;
-        start_free += total_bytes;
-        return(result);
-    } else {
-        size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);
-        // Try to make use of the left-over piece.
-        if (bytes_left > 0) {
-            obj * __VOLATILE * my_free_list =
-                        free_list + FREELIST_INDEX(bytes_left);
-
-            ((obj *)start_free) -> free_list_link = *my_free_list;
-            *my_free_list = (obj *)start_free;
-        }
-        start_free = (char *)malloc(bytes_to_get);
-        if (0 == start_free) {
-            int i;
-            obj * __VOLATILE * my_free_list, *p;
-            // Try to make do with what we have.  That can't
-            // hurt.  We do not try smaller requests, since that tends
-            // to result in disaster on multi-process machines.
-            for (i = size; i <= __MAX_BYTES; i += __ALIGN) {
-                my_free_list = free_list + FREELIST_INDEX(i);
-                p = *my_free_list;
-                if (0 != p) {
-                    *my_free_list = p -> free_list_link;
-                    start_free = (char *)p;
-                    end_free = start_free + i;
-                    return(chunk_alloc(size, nobjs));
-                    // Any leftover piece will eventually make it to the
-                    // right free list.
-                }
-            }
-           end_free = 0;       // In case of exception.
-            start_free = (char *)malloc_alloc::allocate(bytes_to_get);
-            // This should either throw an
-            // exception or remedy the situation.  Thus we assume it
-            // succeeded.
-        }
-        heap_size += bytes_to_get;
-        end_free = start_free + bytes_to_get;
-        return(chunk_alloc(size, nobjs));
-    }
-}
-
-
-/* Returns an object of size n, and optionally adds to size n free list.*/
-/* We assume that n is properly aligned.                                */
-/* We hold the allocation lock.                                         */
-template <bool threads, int inst>
-void* __default_alloc_template<threads, inst>::refill(size_t n)
-{
-    int nobjs = 20;
-    char * chunk = chunk_alloc(n, nobjs);
-    obj * __VOLATILE * my_free_list;
-    obj * result;
-    obj * current_obj, * next_obj;
-    int i;
-
-    if (1 == nobjs) return(chunk);
-    my_free_list = free_list + FREELIST_INDEX(n);
-
-    /* Build free list in chunk */
-      result = (obj *)chunk;
-      *my_free_list = next_obj = (obj *)(chunk + n);
-      for (i = 1; ; i++) {
-        current_obj = next_obj;
-        next_obj = (obj *)((char *)next_obj + n);
-        if (nobjs - 1 == i) {
-            current_obj -> free_list_link = 0;
-            break;
-        } else {
-            current_obj -> free_list_link = next_obj;
-        }
-      }
-    return(result);
-}
-
-template <bool threads, int inst>
-void*
-__default_alloc_template<threads, inst>::reallocate(void *p,
-                                                    size_t old_sz,
-                                                    size_t new_sz)
-{
-    void * result;
-    size_t copy_sz;
-
-    if (old_sz > (size_t) __MAX_BYTES && new_sz > (size_t) __MAX_BYTES) {
-        return(realloc(p, new_sz));
-    }
-    if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return(p);
-    result = allocate(new_sz);
-    copy_sz = new_sz > old_sz? old_sz : new_sz;
-    memcpy(result, p, copy_sz);
-    deallocate(p, old_sz);
-    return(result);
-}
-
-#ifdef _PTHREADS
-    template <bool threads, int inst>
-    pthread_mutex_t
-    __default_alloc_template<threads, inst>::__node_allocator_lock
-        = PTHREAD_MUTEX_INITIALIZER;
-#endif
-
-#ifdef __STL_WIN32THREADS
-    template <bool threads, int inst> CRITICAL_SECTION
-    __default_alloc_template<threads, inst>::__node_allocator_lock;
-
-    template <bool threads, int inst> bool
-    __default_alloc_template<threads, inst>::__node_allocator_lock_initialized
-       = false;
-#endif
-
-#ifdef __STL_SGI_THREADS
-#include <mutex.h>
-#include <time.h>
-// Somewhat generic lock implementations.  We need only test-and-set
-// and some way to sleep.  These should work with both SGI pthreads
-// and sproc threads.  They may be useful on other systems.
-template <bool threads, int inst>
-volatile unsigned long
-__default_alloc_template<threads, inst>::__node_allocator_lock = 0;
-
-#if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) || defined(__GNUC__)
-#   define __test_and_set(l,v) test_and_set(l,v)
-#endif
-
-template <bool threads, int inst>
-void 
-__default_alloc_template<threads, inst>::__lock(volatile unsigned long *lock)
-{
-    const unsigned low_spin_max = 30;  // spin cycles if we suspect uniprocessor
-    const unsigned high_spin_max = 1000; // spin cycles for multiprocessor
-    static unsigned spin_max = low_spin_max;
-    unsigned my_spin_max;
-    static unsigned last_spins = 0;
-    unsigned my_last_spins;
-    static struct timespec ts = {0, 1000};
-    unsigned junk;
-#   define __ALLOC_PAUSE junk *= junk; junk *= junk; junk *= junk; junk *= junk
-    int i;
-
-    if (!__test_and_set((unsigned long *)lock, 1)) {
-        return;
-    }
-    my_spin_max = spin_max;
-    my_last_spins = last_spins;
-    for (i = 0; i < my_spin_max; i++) {
-        if (i < my_last_spins/2 || *lock) {
-            __ALLOC_PAUSE;
-            continue;
-        }
-        if (!__test_and_set((unsigned long *)lock, 1)) {
-            // got it!
-            // Spinning worked.  Thus we're probably not being scheduled
-            // against the other process with which we were contending.
-            // Thus it makes sense to spin longer the next time.
-            last_spins = i;
-            spin_max = high_spin_max;
-            return;
-        }
-    }
-    // We are probably being scheduled against the other process.  Sleep.
-    spin_max = low_spin_max;
-    for (;;) {
-        if (!__test_and_set((unsigned long *)lock, 1)) {
-            return;
-        }
-        nanosleep(&ts, 0);
-    }
-}
-
-template <bool threads, int inst>
-inline void
-__default_alloc_template<threads, inst>::__unlock(volatile unsigned long *lock)
-{
-#   if defined(__GNUC__) && __mips >= 3
-        asm("sync");
-        *lock = 0;
-#   elif __mips >= 3 && (defined (_ABIN32) || defined(_ABI64))
-        __lock_release(lock);
-#   else 
-        *lock = 0;
-        // This is not sufficient on many multiprocessors, since
-        // writes to protected variables and the lock may be reordered.
-#   endif
-}
-#endif
-
-template <bool threads, int inst>
-char *__default_alloc_template<threads, inst>::start_free = 0;
-
-template <bool threads, int inst>
-char *__default_alloc_template<threads, inst>::end_free = 0;
-
-template <bool threads, int inst>
-size_t __default_alloc_template<threads, inst>::heap_size = 0;
-
-template <bool threads, int inst>
-__default_alloc_template<threads, inst>::obj * __VOLATILE
-__default_alloc_template<threads, inst> ::free_list[
-# ifdef __SUNPRO_CC
-    __NFREELISTS
-# else
-    __default_alloc_template<threads, inst>::__NFREELISTS
-# endif
-] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
-// The 16 zeros are necessary to make version 4.1 of the SunPro
-// compiler happy.  Otherwise it appears to allocate too little
-// space for the array.
-
-# ifdef __STL_WIN32THREADS
-  // Create one to get critical section initialized.
-  // We do this onece per file, but only the first constructor
-  // does anything.
-  static alloc __node_allocator_dummy_instance;
-# endif
-
-#endif /* ! __USE_MALLOC */
-
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-#pragma reset woff 1174
-#endif
-
-#undef __PRIVATE
+#endif /* __SGI_STL_ALLOC_H */
 
-#endif /* __ALLOC_H */
+// Local Variables:
+// mode:C++
+// End:
index 71b4917..03a3fb1 100644 (file)
  * purpose.  It is provided "as is" without express or implied warranty.
  */
 
-// vector<bool> is replaced by bit_vector at present because partial 
-// specialization is not yet implemented.  
-
 #ifndef __SGI_STL_BVECTOR_H
 #define __SGI_STL_BVECTOR_H
 
-#include <stddef.h>
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+#include <vector.h>
+#else
 #include <algobase.h>
 #include <alloc.h>
+#endif 
 
+#include <stl_bvector.h>
 
-#define __WORD_BIT (int(CHAR_BIT*sizeof(unsigned int)))
-
-class bit_vector {
-public:
-    typedef bool value_type;
-    typedef size_t size_type;
-    typedef ptrdiff_t difference_type; 
-
-    class iterator;
-    class const_iterator;
-
-    class reference {
-      friend class iterator;
-      friend class const_iterator;
-    protected:
-       unsigned int* p;
-       unsigned int mask;
-       reference(unsigned int* x, unsigned int y) : p(x), mask(y) {}
-    public:
-       reference() : p(0), mask(0) {}
-       operator bool() const { return !(!(*p & mask)); }
-       reference& operator=(bool x) {
-           if (x)      
-               *p |= mask;
-           else 
-               *p &= ~mask;
-           return *this;
-       }
-       reference& operator=(const reference& x) { return *this = bool(x); }
-       bool operator==(const reference& x) const {
-           return bool(*this) == bool(x);
-       }
-       bool operator<(const reference& x) const {
-           return bool(*this) < bool(x);
-       }
-       void flip() { *p ^= mask; }
-    };
-
-    typedef bool const_reference;
-
-    typedef reference bit_reference;
-    typedef const_reference bit_const_reference;
-
-    class iterator : public random_access_iterator<bool, difference_type> {
-      friend class bit_vector;
-      friend class const_iterator;
-    public:
-      typedef bit_reference  reference;
-      typedef bit_reference* pointer;
-    protected:
-       unsigned int* p;
-       unsigned int offset;
-       void bump_up() {
-           if (offset++ == __WORD_BIT - 1) {
-               offset = 0;
-               ++p;
-           }
-       }
-    void bump_down() {
-       if (offset-- == 0) {
-           offset = __WORD_BIT - 1;
-           --p;
-       }
-    }
-    public:
-       iterator() : p(0), offset(0) {}
-       iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {}
-       reference operator*() const { return reference(p, 1U << offset); }
-       iterator& operator++() {
-           bump_up();
-           return *this;
-       }
-       iterator operator++(int) {
-           iterator tmp = *this;
-           bump_up();
-           return tmp;
-       }
-       iterator& operator--() {
-           bump_down();
-           return *this;
-       }
-       iterator operator--(int) {
-           iterator tmp = *this;
-           bump_down();
-           return tmp;
-       }
-       iterator& operator+=(difference_type i) {
-           difference_type n = i + offset;
-           p += n / __WORD_BIT;
-           n = n % __WORD_BIT;
-           if (n < 0) {
-               offset = n + __WORD_BIT;
-               --p;
-           } else
-               offset = n;
-           return *this;
-       }
-       iterator& operator-=(difference_type i) {
-           *this += -i;
-           return *this;
-       }
-       iterator operator+(difference_type i) const {
-           iterator tmp = *this;
-           return tmp += i;
-       }
-       iterator operator-(difference_type i) const {
-           iterator tmp = *this;
-           return tmp -= i;
-       }
-       difference_type operator-(iterator x) const {
-           return __WORD_BIT * (p - x.p) + offset - x.offset;
-       }
-       reference operator[](difference_type i) { return *(*this + i); }
-       bool operator==(const iterator& x) const {
-           return p == x.p && offset == x.offset;
-       }
-       bool operator!=(const iterator& x) const {
-           return p != x.p || offset != x.offset;
-       }
-       bool operator<(iterator x) const {
-           return p < x.p || (p == x.p && offset < x.offset);
-       }
-    };
-
-    class const_iterator : public random_access_iterator<bool, difference_type>
-    {
-      friend class bit_vector;
-    public:
-      typedef bit_const_reference reference;
-      typedef const bool*         pointer;
-    protected:
-       unsigned int* p;
-       unsigned int offset;
-       void bump_up() {
-           if (offset++ == __WORD_BIT - 1) {
-               offset = 0;
-               ++p;
-           }
-       }
-    void bump_down() {
-       if (offset-- == 0) {
-           offset = __WORD_BIT - 1;
-           --p;
-       }
-    }
-    public:
-       const_iterator() : p(0), offset(0) {}
-       const_iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {}
-       const_iterator(const iterator& x) : p(x.p), offset(x.offset) {}
-       const_reference operator*() const {
-           return bit_vector::reference(p, 1U << offset);
-       }
-       const_iterator& operator++() {
-           bump_up();
-           return *this;
-       }
-       const_iterator operator++(int) {
-           const_iterator tmp = *this;
-           bump_up();
-           return tmp;
-       }
-       const_iterator& operator--() {
-           bump_down();
-           return *this;
-       }
-       const_iterator operator--(int) {
-           const_iterator tmp = *this;
-           bump_down();
-           return tmp;
-       }
-       const_iterator& operator+=(difference_type i) {
-           difference_type n = i + offset;
-           p += n / __WORD_BIT;
-           n = n % __WORD_BIT;
-           if (n < 0) {
-               offset = n + __WORD_BIT;
-               --p;
-           } else
-               offset = n;
-           return *this;
-       }
-       const_iterator& operator-=(difference_type i) {
-           *this += -i;
-           return *this;
-       }
-       const_iterator operator+(difference_type i) const {
-           const_iterator tmp = *this;
-           return tmp += i;
-       }
-       const_iterator operator-(difference_type i) const {
-           const_iterator tmp = *this;
-           return tmp -= i;
-       }
-       difference_type operator-(const_iterator x) const {
-           return __WORD_BIT * (p - x.p) + offset - x.offset;
-       }
-       const_reference operator[](difference_type i) { 
-           return *(*this + i); 
-       }
-       bool operator==(const const_iterator& x) const {
-           return p == x.p && offset == x.offset;
-       }
-       bool operator!=(const const_iterator& x) const {
-           return p != x.p || offset != x.offset;
-       }
-       bool operator<(const_iterator x) const {
-           return p < x.p || (p == x.p && offset < x.offset);
-       }
-    };
-
-#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
-    typedef reverse_iterator<const_iterator> const_reverse_iterator;
-    typedef reverse_iterator<iterator> reverse_iterator;
-#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-    typedef reverse_iterator<const_iterator, value_type, const_reference, 
-                             difference_type> const_reverse_iterator;
-    typedef reverse_iterator<iterator, value_type, reference, difference_type>
-        reverse_iterator;
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-protected:
-    typedef simple_alloc<unsigned int, alloc> data_allocator;
-    iterator start;
-    iterator finish;
-    unsigned int* end_of_storage;
-    unsigned int* bit_alloc(size_type n) {
-       return data_allocator::allocate((n + __WORD_BIT - 1)/__WORD_BIT);
-    }
-    void deallocate() {
-      if (start.p)
-        data_allocator::deallocate(start.p, end_of_storage - start.p);
-    }
-    void initialize(size_type n) {
-       unsigned int* q = bit_alloc(n);
-       end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT;
-       start = iterator(q, 0);
-       finish = start + n;
-    }
-    void insert_aux(iterator position, bool x) {
-      if (finish.p != end_of_storage) {
-       copy_backward(position, finish, finish + 1);
-       *position = x;
-       ++finish;
-      } else {
-       size_type len = size() ? 2 * size() : __WORD_BIT;
-       unsigned int* q = bit_alloc(len);
-       iterator i = copy(begin(), position, iterator(q, 0));
-       *i++ = x;
-       finish = copy(position, end(), i);
-       deallocate();
-       end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
-       start = iterator(q, 0);
-      }
-    }
-
-#ifdef __STL_MEMBER_TEMPLATES
-    template <class InputIterator>
-    void initialize_range(InputIterator first, InputIterator last,
-                          input_iterator_tag) {
-      start = iterator();
-      finish = iterator();
-      end_of_storage = 0;
-      for ( ; first != last; ++first) 
-        push_back(*first);
-    }
-
-    template <class ForwardIterator>
-    void initialize_range(ForwardIterator first, ForwardIterator last,
-                          forward_iterator_tag) {
-      size_type n = 0;
-      distance(first, last, n);
-      initialize(n);
-      copy(first, last, start);
-    }
+#ifdef __STL_USE_NAMESPACES
 
-    template <class InputIterator>
-    void insert_range(iterator pos,
-                      InputIterator first, InputIterator last,
-                      input_iterator_tag) {
-      for ( ; first != last; ++first) {
-        pos = insert(pos, *first);
-        ++pos;
-      }
-    }
+using __STD::bit_vector;
 
-    template <class ForwardIterator>
-    void insert_range(iterator position,
-                      ForwardIterator first, ForwardIterator last,
-                      forward_iterator_tag) {
-      if (first != last) {
-        size_type n = 0;
-        distance(first, last, n);
-        if (capacity() - size() >= n) {
-          copy_backward(position, end(), finish + n);
-          copy(first, last, position);
-          finish += n;
-        }
-        else {
-          size_type len = size() + max(size(), n);
-          unsigned int* q = bit_alloc(len);
-          iterator i = copy(begin(), position, iterator(q, 0));
-          i = copy(first, last, i);
-          finish = copy(position, end(), i);
-          deallocate();
-          end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
-          start = iterator(q, 0);
-        }
-      }
-    }      
+#endif /* __STL_USE_NAMESPACES */
 
-#endif /* __STL_MEMBER_TEMPLATES */
-
-    typedef bit_vector self;
-public:
-    iterator begin() { return start; }
-    const_iterator begin() const { return start; }
-    iterator end() { return finish; }
-    const_iterator end() const { return finish; }
-
-    reverse_iterator rbegin() { return reverse_iterator(end()); }
-    const_reverse_iterator rbegin() const { 
-        return const_reverse_iterator(end()); 
-    }
-    reverse_iterator rend() { return reverse_iterator(begin()); }
-    const_reverse_iterator rend() const { 
-        return const_reverse_iterator(begin()); 
-    }
-
-    size_type size() const { return size_type(end() - begin()); }
-    size_type max_size() const { return size_type(-1); }
-    size_type capacity() const {
-       return size_type(const_iterator(end_of_storage, 0) - begin());
-    }
-    bool empty() const { return begin() == end(); }
-    reference operator[](size_type n) { return *(begin() + n); }
-    const_reference operator[](size_type n) const { return *(begin() + n); }
-    bit_vector() : start(iterator()), finish(iterator()), end_of_storage(0) {}
-    bit_vector(size_type n, bool value) {
-        initialize(n);
-        fill(start.p, end_of_storage, value ? ~0 : 0);
-    }
-    bit_vector(int n, bool value) {
-        initialize(n);
-        fill(start.p, end_of_storage, value ? ~0 : 0);
-    }
-    bit_vector(long n, bool value) {
-        initialize(n);
-        fill(start.p, end_of_storage, value ? ~0 : 0);
-    }
-    explicit bit_vector(size_type n) {
-        initialize(n);
-        fill(start.p, end_of_storage, 0);
-    }
-    bit_vector(const self& x) {
-       initialize(x.size());
-       copy(x.begin(), x.end(), start);
-    }
-
-#ifdef __STL_MEMBER_TEMPLATES
-    template <class InputIterator>
-    bit_vector(InputIterator first, InputIterator last) {
-        initialize_range(first, last, iterator_category(first));
-    }
-#else /* __STL_MEMBER_TEMPLATES */
-    bit_vector(const_iterator first, const_iterator last) {
-       size_type n = 0;
-       distance(first, last, n);
-       initialize(n);
-       copy(first, last, start);
-    }
-    bit_vector(const bool* first, const bool* last) {
-       size_type n = 0;
-       distance(first, last, n);
-       initialize(n);
-       copy(first, last, start);
-    }
-#endif /* __STL_MEMBER_TEMPLATES */
-
-    ~bit_vector() { deallocate(); }
-    self& operator=(const self& x) {
-       if (&x == this) return *this;
-       if (x.size() > capacity()) {
-           deallocate();
-           initialize(x.size());
-       }
-       copy(x.begin(), x.end(), begin());
-       finish = begin() + x.size();
-       return *this;
-    }
-    void reserve(size_type n) {
-       if (capacity() < n) {
-           unsigned int* q = bit_alloc(n);
-           finish = copy(begin(), end(), iterator(q, 0));
-           deallocate();
-           start = iterator(q, 0);
-           end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT;
-       }
-    }
-    reference front() { return *begin(); }
-    const_reference front() const { return *begin(); }
-    reference back() { return *(end() - 1); }
-    const_reference back() const { return *(end() - 1); }
-    void push_back(bool x) {
-       if (finish.p != end_of_storage)
-           *finish++ = x;
-       else
-           insert_aux(end(), x);
-    }
-    void swap(bit_vector& x) {
-       ::swap(start, x.start);
-       ::swap(finish, x.finish);
-       ::swap(end_of_storage, x.end_of_storage);
-    }
-    iterator insert(iterator position, bool x = bool()) {
-       size_type n = position - begin();
-       if (finish.p != end_of_storage && position == end())
-           *finish++ = x;
-       else
-           insert_aux(position, x);
-       return begin() + n;
-    }
-
-#ifdef __STL_MEMBER_TEMPLATES
-    template <class InputIterator> void insert(iterator position,
-                                               InputIterator first,
-                                               InputIterator last) {
-      insert_range(position, first, last, iterator_category(first));
-    }
-#else /* __STL_MEMBER_TEMPLATES */
-    void insert(iterator position, const_iterator first, 
-               const_iterator last) {
-      if (first == last) return;
-      size_type n = 0;
-      distance(first, last, n);
-      if (capacity() - size() >= n) {
-       copy_backward(position, end(), finish + n);
-       copy(first, last, position);
-       finish += n;
-      } else {
-       size_type len = size() + max(size(), n);
-       unsigned int* q = bit_alloc(len);
-       iterator i = copy(begin(), position, iterator(q, 0));
-       i = copy(first, last, i);
-       finish = copy(position, end(), i);
-       deallocate();
-       end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
-       start = iterator(q, 0);
-      }
-    }
-
-    void insert(iterator position, const bool* first, const bool* last) {
-      if (first == last) return;
-      size_type n = 0;
-      distance(first, last, n);
-      if (capacity() - size() >= n) {
-       copy_backward(position, end(), finish + n);
-       copy(first, last, position);
-       finish += n;
-      } else {
-       size_type len = size() + max(size(), n);
-       unsigned int* q = bit_alloc(len);
-       iterator i = copy(begin(), position, iterator(q, 0));
-       i = copy(first, last, i);
-       finish = copy(position, end(), i);
-       deallocate();
-       end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
-       start = iterator(q, 0);
-      }
-    }
-#endif /* __STL_MEMBER_TEMPLATES */
-  
-    void insert(iterator position, size_type n, bool x) {
-      if (n == 0) return;
-      if (capacity() - size() >= n) {
-       copy_backward(position, end(), finish + n);
-       fill(position, position + n, x);
-       finish += n;
-      } else {
-       size_type len = size() + max(size(), n);
-       unsigned int* q = bit_alloc(len);
-       iterator i = copy(begin(), position, iterator(q, 0));
-       fill_n(i, n, x);
-       finish = copy(position, end(), i + n);
-       deallocate();
-       end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
-       start = iterator(q, 0);
-      }
-    }
-
-    void insert(iterator pos, int n, bool x)  { insert(pos, (size_type)n, x); }
-    void insert(iterator pos, long n, bool x) { insert(pos, (size_type)n, x); }
-
-    void pop_back() { --finish; }
-    void erase(iterator position) {
-       if (position + 1 != end())
-           copy(position + 1, end(), position);
-       --finish;
-    }
-    void erase(iterator first, iterator last) {
-       finish = copy(last, end(), first);
-    }
-    void resize(size_type new_size, bool x = bool()) {
-      if (new_size < size()) 
-        erase(begin() + new_size, end());
-      else
-        insert(end(), new_size - size(), x);
-    }
-    void clear() { erase(begin(), end()); }
-};
-
-inline bool operator==(const bit_vector& x, const bit_vector& y) {
-    return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
-}
-
-inline bool operator<(const bit_vector& x, const bit_vector& y) {
-    return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
-}
+#endif /* __SGI_STL_BVECTOR_H */
 
-inline void swap(bit_vector::reference x, bit_vector::reference y) {
-    bool tmp = x;
-    x = y;
-    y = tmp;
-}
+// Local Variables:
+// mode:C++
+// End:
 
-#undef __WORD_BIT
 
-#endif /* __SGI_STL_BVECTOR_H */
index e7d24d3..49690f8 100644 (file)
  * purpose.  It is provided "as is" without express or implied warranty.
  *
  */
-//
-//  Inclusion of this file is DEPRECATED.
-//  This is the original HP default allocator.
-//  DO NOT USE THIS FILE unless you have an old container implementation
-//  that requires an allocator with the HP-style interface.
-//  SGI STL uses a different allocator interface.
-//  SGI-style allocators are not parametrized with respect to
-//  the object type; they traffic in void * pointers.
-//  This file is not included by any other SGI STL header.
-//
+
+// Inclusion of this file is DEPRECATED.  This is the original HP
+// default allocator.  It is provided only for backward compatibility.
+// 
+// DO NOT USE THIS FILE unless you have an old container implementation
+// that requires an allocator with the HP-style interface.  SGI STL
+// uses a different allocator interface.  SGI-style allocators are not
+// parametrized with respect to the object type; they traffic in void *
+// pointers.  This file is not included by any other SGI STL header.
 
 #ifndef DEFALLOC_H
 #define DEFALLOC_H
diff --git a/libstdc++/stl/deque b/libstdc++/stl/deque
new file mode 100644 (file)
index 0000000..61654ac
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __SGI_STL_DEQUE
+#define __SGI_STL_DEQUE
+
+#include <stl_algobase.h>
+#include <stl_alloc.h>
+#include <stl_construct.h>
+#include <stl_uninitialized.h>
+#include <stl_deque.h>
+
+#endif /* __SGI_STL_DEQUE */
+
+// Local Variables:
+// mode:C++
+// End:
index e202a11..ede38b1 100644 (file)
 #ifndef __SGI_STL_DEQUE_H
 #define __SGI_STL_DEQUE_H
 
-/* Class invariants:
- *  For any nonsingular iterator i:
- *    i.node is the address of an element in the map array.  The
- *      contents of i.node is a pointer to the beginning of a node.
- *    i.first == *(i.node) 
- *    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, and that a deque
- *    with N elements, where N is the buffer size, must have two nodes.
- *  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].
- */
-
-
-/*
- * In previous versions of deque, node_size was fixed by the 
- * implementation.  In this version, however, users can select
- * the node size.  Deque has three template parameters; the third,
- * a number of type size_t, is the number of elements per node.
- * If the third template parameter is 0 (which is the default), 
- * then deque will use a default node size.
- *
- * The only reason for using an alternate node size is if your application
- * requires a different performance tradeoff than the default.  If,
- * for example, your program contains many deques each of which contains
- * only a few elements, then you might want to save memory (possibly
- * by sacrificing some speed) by using smaller nodes.
- *
- * Unfortunately, some compilers have trouble with non-type template 
- * parameters; stl_config.h defines __STL_NON_TYPE_TMPL_PARAM_BUG if
- * that is the case.  If your compiler is one of them, then you will
- * not be able to use alternate node sizes; you will have to use the
- * default value.
- */
-
-#include <stddef.h>
 #include <algobase.h>
 #include <alloc.h>
+#include <stl_deque.h>
 
-// Note: this function is simply a kludge to work around several compilers'
-//  bugs in handling constant expressions.
-inline size_t __deque_buf_size(size_t n, size_t sz)
-{
-  return n != 0 ? n : (sz < 512 ? size_t(512 / sz) : size_t(1));
-}
-
-#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
-template <class T, class Ref, class Ptr, size_t BufSiz>
-struct __deque_iterator {
-  typedef __deque_iterator<T, T&, T*, BufSiz>             iterator;
-  typedef __deque_iterator<T, const T&, const T*, BufSiz> const_iterator;
-  static size_t buffer_size() {return __deque_buf_size(BufSiz, sizeof(T)); }
-#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */
-template <class T, class Ref, class Ptr>
-struct __deque_iterator {
-  typedef __deque_iterator<T, T&, T*>             iterator;
-  typedef __deque_iterator<T, const T&, const T*> const_iterator;
-  static size_t buffer_size() {return __deque_buf_size(0, sizeof(T)); }
-#endif
-
-  typedef random_access_iterator_tag iterator_category;
-  typedef T value_type;
-  typedef Ptr pointer;
-  typedef Ref reference;
-  typedef size_t size_type;
-  typedef ptrdiff_t difference_type;
-  typedef T** map_pointer;
-
-  typedef __deque_iterator self;
-
-  T* cur;
-  T* first;
-  T* last;
-  map_pointer node;
-
-  __deque_iterator(T* x, map_pointer y) 
-    : cur(x), first(*y), last(*y + buffer_size()), node(y) {}
-  __deque_iterator() : cur(0), first(0), last(0), node(0) {}
-  __deque_iterator(const iterator& x)
-    : cur(x.cur), first(x.first), last(x.last), node(x.node) {}
-
-  reference operator*() const { return *cur; }
-#ifndef __SGI_STL_NO_ARROW_OPERATOR
-  pointer operator->() const { return &(operator*()); }
-#endif /* __SGI_STL_NO_ARROW_OPERATOR */
-
-  difference_type operator-(const self& x) const {
-    return buffer_size() * (node - x.node - 1) +
-      (cur - first) + (x.last - x.cur);
-  }
-
-  self& operator++() {
-    ++cur;
-    if (cur == last) {
-      set_node(node + 1);
-      cur = first;
-    }
-    return *this; 
-  }
-  self operator++(int)  {
-    self tmp = *this;
-    ++*this;
-    return tmp;
-  }
-
-  self& operator--() {
-    if (cur == first) {
-      set_node(node - 1);
-      cur = last;
-    }
-    --cur;
-    return *this;
-  }
-  self operator--(int) {
-    self tmp = *this;
-    --*this;
-    return tmp;
-  }
-
-  self& operator+=(difference_type n) {
-    difference_type offset = n + (cur - first);
-    if (offset >= 0 && offset < buffer_size())
-      cur += n;
-    else {
-      difference_type node_offset =
-        offset > 0 ? offset / buffer_size()
-                   : -difference_type((-offset - 1) / buffer_size()) - 1;
-      set_node(node + node_offset);
-      cur = first + (offset - node_offset * 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); }
-
-  bool operator==(const self& x) const { return cur == x.cur; }
-  bool operator!=(const self& x) const { return !(*this == x); }
-  bool operator<(const self& x) const {
-    return (node == x.node) ? (cur < x.cur) : (node < x.node);
-  }
-
-  void set_node(map_pointer new_node) {
-    node = new_node;
-    first = *new_node;
-    last = first + buffer_size();
-  }
-};
-
-#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
-
-template <class T, class Ref, class Ptr, size_t BufSiz>
-inline random_access_iterator_tag
-iterator_category(const __deque_iterator<T, Ref, Ptr, BufSiz>&) {
-  return random_access_iterator_tag();
-}
-
-template <class T, class Ref, class Ptr, size_t BufSiz>
-inline T* value_type(const __deque_iterator<T, Ref, Ptr, BufSiz>&) {
-  return 0;
-}
-
-template <class T, class Ref, class Ptr, size_t BufSiz>
-inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr, BufSiz>&) {
-  return 0;
-}
-
-#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */
-
-template <class T, class Ref, class Ptr>
-inline random_access_iterator_tag
-iterator_category(const __deque_iterator<T, Ref, Ptr>&) {
-  return random_access_iterator_tag();
-}
-
-template <class T, class Ref, class Ptr>
-inline T* value_type(const __deque_iterator<T, Ref, Ptr>&) { return 0; }
-
-template <class T, class Ref, class Ptr>
-inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr>&) {
-  return 0;
-}
-
-#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-// See __deque_buf_size().  The only reason that the default value is 0
-//  is as a workaround for bugs in the way that some compilers handle
-//  constant expressions.
-template <class T, class Alloc = alloc, size_t BufSiz = 0> 
-class deque {
-public:                         // Basic types
-  typedef T value_type;
-  typedef value_type* pointer;
-  typedef value_type& reference;
-  typedef const value_type& const_reference;
-  typedef size_t size_type;
-  typedef ptrdiff_t difference_type;
-
-public:                         // Iterators
-#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
-  typedef __deque_iterator<T, T&, T*, BufSiz>              iterator;
-  typedef __deque_iterator<T, const T&, const T&, BufSiz>  const_iterator;
-#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */
-  typedef __deque_iterator<T, T&, T*>                      iterator;
-  typedef __deque_iterator<T, const T&, const T*>          const_iterator;
-#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
-
-#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
-  typedef reverse_iterator<const_iterator> const_reverse_iterator;
-  typedef reverse_iterator<iterator> reverse_iterator;
-#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-  typedef reverse_iterator<const_iterator, value_type, const_reference, 
-                           difference_type>  
-          const_reverse_iterator;
-  typedef reverse_iterator<iterator, value_type, reference, difference_type>
-          reverse_iterator; 
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-protected:                      // Internal typedefs
-  typedef pointer* map_pointer;
-  typedef simple_alloc<value_type, Alloc> data_allocator;
-  typedef simple_alloc<pointer, Alloc> map_allocator;
-
-  static size_type buffer_size() {
-    return __deque_buf_size(BufSiz, sizeof(value_type));
-  }
-  static size_type initial_map_size() { return 8; }
-
-protected:                      // Data members
-  iterator start;
-  iterator finish;
-
-  map_pointer map;
-  size_type map_size;
-
-public:                         // Basic accessors
-  iterator begin() { return start; }
-  iterator end() { return finish; }
-  const_iterator begin() const { return start; }
-  const_iterator end() const { return finish; }
-
-  reverse_iterator rbegin() { return reverse_iterator(finish); }
-  reverse_iterator rend() { return reverse_iterator(start); }
-  const_reverse_iterator rbegin() const {
-    return const_reverse_iterator(finish);
-  }
-  const_reverse_iterator rend() const {
-    return const_reverse_iterator(start);
-  }
-
-  reference operator[](size_type n) { return start[n]; }
-  const_reference operator[](size_type n) const { return start[n]; }
-
-  reference front() { return *start; }
-  reference back() {
-    iterator tmp = finish;
-    --tmp;
-    return *tmp;
-  }
-  const_reference front() const { return *start; }
-  const_reference back() const {
-    const_iterator tmp = finish;
-    --tmp;
-    return *tmp;
-  }
-
-  size_type size() const { return finish - start;; }
-  size_type max_size() const { return size_type(-1); }
-  bool empty() const { return finish == start; }
-
-public:                         // Constructor, destructor.
-  deque()
-    : start(), finish(), map(0), map_size(0)
-  {
-    create_map_and_nodes(0);
-  }
-
-  deque(const deque& x)
-    : start(), finish(), map(0), map_size(0)
-  {
-    create_map_and_nodes(x.size());
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      uninitialized_copy(x.begin(), x.end(), start);
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_map_and_nodes();
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */
-  }
-
-  deque(size_type n, const value_type& value)
-    : start(), finish(), map(0), map_size(0) {
-      fill_initialize(n, value);
-  }
-
-  deque(int n, const value_type& value)
-    : start(), finish(), map(0), map_size(0) {
-      fill_initialize(n, value);
-  }
-  deque(long n, const value_type& value)
-    : start(), finish(), map(0), map_size(0) {
-      fill_initialize(n, value);
-  }
-
-  explicit deque(size_type n)
-    : start(), finish(), map(0), map_size(0) {
-    fill_initialize(n, value_type());
-  }
-
-#ifdef __STL_MEMBER_TEMPLATES
-
-  template <class InputIterator>
-  deque(InputIterator first, InputIterator last)
-    : start(), finish(), map(0), map_size(0)
-  {
-    range_initialize(first, last, iterator_category(first));
-  }
-
-#else /* __STL_MEMBER_TEMPLATES */
-
-  deque(const value_type* first, const value_type* last)
-    : start(), finish(), map(0), map_size(0)
-  {
-    create_map_and_nodes(last - first);
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      uninitialized_copy(first, last, start);
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_map_and_nodes();
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */
-  }
-
-  deque(const_iterator first, const_iterator last)
-    : start(), finish(), map(0), map_size(0)
-  {
-    create_map_and_nodes(last - first);
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      uninitialized_copy(first, last, start);
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_map_and_nodes();
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */
-  }
-
-#endif /* __STL_MEMBER_TEMPLATES */
-
-  ~deque() {
-    destroy(start, finish);
-    destroy_map_and_nodes();
-  }
-
-  deque& operator= (const deque& x) {
-    const size_type len = size();
-    if (&x != this) {
-      if (len >= x.size())
-        erase(copy(x.begin(), x.end(), start), finish);
-      else {
-        const_iterator mid = x.begin() + len;
-        copy(x.begin(), mid, start);
-        insert(finish, mid, x.end());
-      }
-    }
-    return *this;
-  }        
-
-  void swap(deque& x) {
-    ::swap(start, x.start);
-    ::swap(finish, x.finish);
-    ::swap(map, x.map);
-    ::swap(map_size, x.map_size);
-  }
-
-public:                         // push_* and pop_*
-  
-  void push_back(const value_type& t) {
-    if (finish.cur != finish.last - 1) {
-      construct(finish.cur, t);
-      ++finish.cur;
-    }
-    else
-      push_back_aux(t);
-  }
-
-  void push_front(const value_type& t) {
-    if (start.cur != start.first) {
-      construct(start.cur - 1, t);
-      --start.cur;
-    }
-    else
-      push_front_aux(t);
-  }
-
-  void pop_back() {
-    if (finish.cur != finish.first) {
-      --finish.cur;
-      destroy(finish.cur);
-    }
-    else
-      pop_back_aux();
-  }
-
-  void pop_front() {
-    if (start.cur != start.last - 1) {
-      destroy(start.cur);
-      ++start.cur;
-    }
-    else 
-      pop_front_aux();
-  }
-
-public:                         // Insert
-
-  iterator insert(iterator position, const value_type& x) {
-    if (position.cur == start.cur) {
-      push_front(x);
-      return start;
-    }
-    else if (position.cur == finish.cur) {
-      push_back(x);
-      iterator tmp = finish;
-      --tmp;
-      return tmp;
-    }
-    else {
-      return insert_aux(position, x);
-    }
-  }
-
-  iterator insert(iterator position) { return insert(position, value_type()); }
-
-  void insert(iterator pos, size_type n, const value_type& x); 
-
-  void insert(iterator pos, int n, const value_type& x) {
-    insert(pos, (size_type) n, x);
-  }
-  void insert(iterator pos, long n, const value_type& x) {
-    insert(pos, (size_type) n, x);
-  }
-
-#ifdef __STL_MEMBER_TEMPLATES  
-
-  template <class InputIterator>
-  void insert(iterator pos, InputIterator first, InputIterator last) {
-    insert(pos, first, last, iterator_category(first));
-  }
-
-#else /* __STL_MEMBER_TEMPLATES */
-
-  void insert(iterator pos, const value_type* first, const value_type* last);
-  void insert(iterator pos, const_iterator first, const_iterator last);
-
-#endif /* __STL_MEMBER_TEMPLATES */
-
-  void resize(size_type new_size, const value_type& x) {
-    const size_type len = size();
-    if (new_size < len) 
-      erase(start + new_size, finish);
-    else
-      insert(finish, new_size - len, x);
-  }
-
-  void resize(size_type new_size) { resize(new_size, value_type()); }
-
-public:                         // Erase
-  void erase(iterator pos) {
-    iterator next = pos;
-    ++next;
-    if (pos - start < size() / 2) {
-      copy_backward(start, pos, next);
-      pop_front();
-    }
-    else {
-      copy(next, finish, pos);
-      pop_back();
-    }
-  }
-
-  void erase(iterator first, iterator last);
-  void clear(); 
-
-protected:                        // Internal construction/destruction
-
-  void create_map_and_nodes(size_type num_elements);
-  void destroy_map_and_nodes();
-  void fill_initialize(size_type n, const value_type& value);
-
-#ifdef __STL_MEMBER_TEMPLATES  
-
-  template <class InputIterator>
-  void range_initialize(InputIterator first, InputIterator last,
-                        input_iterator_tag);
-
-  template <class ForwardIterator>
-  void range_initialize(ForwardIterator first, ForwardIterator last,
-                        forward_iterator_tag);
-
-#endif /* __STL_MEMBER_TEMPLATES */
-
-protected:                        // Internal push_* and pop_*
-
-  void push_back_aux(const value_type& t);
-  void push_front_aux(const value_type& t);
-  void pop_back_aux();
-  void pop_front_aux();
-
-protected:                        // Internal insert functions
-
-#ifdef __STL_MEMBER_TEMPLATES  
-
-  template <class InputIterator>
-  void insert(iterator pos, InputIterator first, InputIterator last,
-              input_iterator_tag);
-
-  template <class ForwardIterator>
-  void insert(iterator pos, ForwardIterator first, ForwardIterator last,
-              forward_iterator_tag);
-
-#endif /* __STL_MEMBER_TEMPLATES */
-
-  iterator insert_aux(iterator pos, const value_type& x);
-  void insert_aux(iterator pos, size_type n, const value_type& x);
-
-#ifdef __STL_MEMBER_TEMPLATES  
-
-  template <class ForwardIterator>
-  void insert_aux(iterator pos, ForwardIterator first, ForwardIterator last,
-                  size_type n);
-
-#else /* __STL_MEMBER_TEMPLATES */
-  
-  void insert_aux(iterator pos,
-                  const value_type* first, const value_type* last,
-                  size_type n);
-
-  void insert_aux(iterator pos, const_iterator first, const_iterator last,
-                  size_type n);
-#endif /* __STL_MEMBER_TEMPLATES */
-
-  iterator reserve_elements_at_front(size_type n) {
-    size_type vacancies = start.cur - start.first;
-    if (n > vacancies) 
-      new_elements_at_front(n - vacancies);
-    return start - n;
-  }
-
-  iterator reserve_elements_at_back(size_type n) {
-    size_type vacancies = (finish.last - finish.cur) - 1;
-    if (n > vacancies)
-      new_elements_at_back(n - vacancies);
-    return finish + n;
-  }
-
-  void new_elements_at_front(size_type new_elements);
-  void new_elements_at_back(size_type new_elements);
-
-  void destroy_nodes_at_front(iterator before_start);
-  void destroy_nodes_at_back(iterator after_finish);
-
-protected:                      // Allocation of map and nodes
-
-  // Makes sure the map has space for new nodes.  Does not actually
-  //  add the nodes.  Can invalidate map pointers.  (And consequently, 
-  //  deque iterators.)
-
-  void reserve_map_at_back (size_type nodes_to_add = 1) {
-    if (nodes_to_add + 1 > map_size - (finish.node - map))
-      reallocate_map(nodes_to_add, false);
-  }
-
-  void reserve_map_at_front (size_type nodes_to_add = 1) {
-    if (nodes_to_add > start.node - map)
-      reallocate_map(nodes_to_add, true);
-  }
-
-  void reallocate_map(size_type nodes_to_add, bool add_at_front);
-
-  pointer allocate_node() { return data_allocator::allocate(buffer_size()); }
-  void deallocate_node(pointer n) {
-    data_allocator::deallocate(n, buffer_size());
-  }
-
-#ifdef __STL_NON_TYPE_TMPL_PARAM_BUG
-public:
-  bool operator==(const deque<T, Alloc, 0>& x) const {
-    return size() == x.size() && equal(begin(), end(), x.begin());
-  }
-  bool operator!=(const deque<T, Alloc, 0>& x) const {
-    return size() != x.size() || !equal(begin(), end(), x.begin());
-  }
-  bool operator<(const deque<T, Alloc, 0>& x) const {
-    return lexicographical_compare(begin(), end(), x.begin(), x.end());
-  }
-#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
-};
-
-// Non-inline member functions
-
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::insert(iterator pos,
-                                      size_type n, const value_type& x) {
-  if (pos.cur == start.cur) {
-    iterator new_start = reserve_elements_at_front(n);
-    uninitialized_fill(new_start, start, x);
-    start = new_start;
-  }
-  else if (pos.cur == finish.cur) {
-    iterator new_finish = reserve_elements_at_back(n);
-    uninitialized_fill(finish, new_finish, x);
-    finish = new_finish;
-  }
-  else 
-    insert_aux(pos, n, x);
-}
-
-#ifndef __STL_MEMBER_TEMPLATES  
-
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::insert(iterator pos,
-                                      const value_type* first,
-                                      const value_type* last) {
-  size_type n = last - first;
-  if (pos.cur == start.cur) {
-    iterator new_start = reserve_elements_at_front(n);
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif
-      uninitialized_copy(first, last, new_start);
-      start = new_start;
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_nodes_at_front(new_start);
-      throw;
-    }
-#       endif
-  }
-  else if (pos.cur == finish.cur) {
-    iterator new_finish = reserve_elements_at_back(n);
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif
-      uninitialized_copy(first, last, finish);
-      finish = new_finish;
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_nodes_at_back(new_finish);
-      throw;
-    }
-#       endif
-  }
-  else
-    insert_aux(pos, first, last, n);
-}
-
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::insert(iterator pos,
-                                      const_iterator first,
-                                      const_iterator last)
-{
-  size_type n = last - first;
-  if (pos.cur == start.cur) {
-    iterator new_start = reserve_elements_at_front(n);
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif
-      uninitialized_copy(first, last, new_start);
-      start = new_start;
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_nodes_at_front(new_start);
-      throw;
-    }
-#       endif      
-  }
-  else if (pos.cur == finish.cur) {
-    iterator new_finish = reserve_elements_at_back(n);
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif
-      uninitialized_copy(first, last, finish);
-      finish = new_finish;
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_nodes_at_back(new_finish);
-      throw;
-    }
-#       endif
-  }
-  else
-    insert_aux(pos, first, last, n);
-}
-
-#endif /* __STL_MEMBER_TEMPLATES */
-
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::erase(iterator first, iterator last) {
-  if (first == start && last == finish)
-    clear();
-  else {
-    difference_type n = last - first;
-    difference_type elems_before = first - start;
-    if (elems_before < (size() - n) / 2) {
-      copy_backward(start, first, last);
-      iterator new_start = start + n;
-      destroy(start, new_start);
-      for (map_pointer cur = start.node; cur < new_start.node; ++cur)
-        data_allocator::deallocate(*cur, buffer_size());
-      start = new_start;
-    }
-    else {
-      copy(last, finish, first);
-      iterator new_finish = finish - n;
-      destroy(new_finish, finish);
-      for (map_pointer cur = new_finish.node + 1; cur <= finish.node; ++cur)
-        data_allocator::deallocate(*cur, buffer_size());
-      finish = new_finish;
-    }
-  }
-}
-
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::clear() {
-  for (map_pointer node = start.node + 1; node < finish.node; ++node) {
-    destroy(*node, *node + buffer_size());
-    data_allocator::deallocate(*node, buffer_size());
-  }
-
-  if (start.node != finish.node) {
-    destroy(start.cur, start.last);
-    destroy(finish.first, finish.cur);
-    data_allocator::deallocate(finish.first, buffer_size());
-  }
-  else
-    destroy(start.cur, finish.cur);
-
-  finish = start;
-}
-
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::create_map_and_nodes(size_type num_elements) {
-  size_type num_nodes = num_elements / buffer_size() + 1;
-
-  map_size = max(initial_map_size(), num_nodes + 2);
-  map = map_allocator::allocate(map_size);
-
-  map_pointer nstart = map + (map_size - num_nodes) / 2;
-  map_pointer nfinish = nstart + num_nodes - 1;
-    
-  map_pointer cur;
-#     ifdef __STL_USE_EXCEPTIONS
-  try {
-#     endif /* __STL_USE_EXCEPTIONS */
-    for (cur = nstart; cur <= nfinish; ++cur)
-      *cur = allocate_node();
-#     ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    for (map_pointer n = nstart; n < cur; ++n)
-      deallocate_node(*n);
-    map_allocator::deallocate(map, map_size);
-    throw;
-  }
-#     endif /* __STL_USE_EXCEPTIONS */
-
-  start.set_node(nstart);
-  finish.set_node(nfinish);
-  start.cur = start.first;
-  finish.cur = finish.first + num_elements % buffer_size();
-}
-
-// This is only used as a cleanup function in catch clauses.
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::destroy_map_and_nodes() {
-  for (map_pointer cur = start.node; cur <= finish.node; ++cur)
-    deallocate_node(*cur);
-  map_allocator::deallocate(map, map_size);
-}
-  
-
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::fill_initialize(size_type n,
-                                               const value_type& value) {
-  create_map_and_nodes(n);
-  map_pointer cur;
-#     ifdef __STL_USE_EXCEPTIONS
-  try {
-#     endif /* __STL_USE_EXCEPTIONS */
-    for (cur = start.node; cur < finish.node; ++cur)
-      uninitialized_fill(*cur, *cur + buffer_size(), value);
-    uninitialized_fill(finish.first, finish.cur, value);
-#       ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    for (map_pointer n = start.node; n < cur; ++n)
-      destroy(*n, *n + buffer_size());
-    destroy_map_and_nodes();
-    throw;
-  }
-#       endif /* __STL_USE_EXCEPTIONS */
-}
-
-#ifdef __STL_MEMBER_TEMPLATES  
-
-template <class T, class Alloc, size_t BufSize>
-template <class InputIterator>
-void deque<T, Alloc, BufSize>::range_initialize(InputIterator first,
-                                                InputIterator last,
-                                                input_iterator_tag) {
-  create_map_and_nodes(0);
-  for ( ; first != last; ++first)
-    push_back(*first);
-}
-
-template <class T, class Alloc, size_t BufSize>
-template <class ForwardIterator>
-void deque<T, Alloc, BufSize>::range_initialize(ForwardIterator first,
-                                                ForwardIterator last,
-                                                forward_iterator_tag) {
-  size_type n = 0;
-  distance(first, last, n);
-  create_map_and_nodes(n);
-#     ifdef __STL_USE_EXCEPTIONS
-  try {
-#     endif /* __STL_USE_EXCEPTIONS */
-    uninitialized_copy(first, last, start);
-#     ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    destroy_map_and_nodes();
-    throw;
-  }
-#     endif /* __STL_USE_EXCEPTIONS */
-}
-
-#endif /* __STL_MEMBER_TEMPLATES */
-
-// Called only if finish.cur == finish.last - 1.
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::push_back_aux(const value_type& t) {
-  value_type t_copy = t;
-  reserve_map_at_back();
-  *(finish.node + 1) = allocate_node();
-#     ifdef __STL_USE_EXCEPTIONS
-  try {
-#     endif /* __STL_USE_EXCEPTIONS */
-    construct(finish.cur, t_copy);
-    finish.set_node(finish.node + 1);
-    finish.cur = finish.first;
-#     ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    deallocate_node(*(finish.node + 1));
-    throw;
-  }
-#     endif /* __STL_USE_EXCEPTIONS */
-}
-
-// Called only if start.cur == start.first.
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::push_front_aux(const value_type& t) {
-  value_type t_copy = t;
-  reserve_map_at_front();
-  *(start.node - 1) = allocate_node();
-#     ifdef __STL_USE_EXCEPTIONS
-  try {
-#     endif /* __STL_USE_EXCEPTIONS */
-    start.set_node(start.node - 1);
-    start.cur = start.last - 1;
-    construct(start.cur, t_copy);
-#     ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    start.set_node(start.node + 1);
-    start.cur = start.first;
-    deallocate_node(*(start.node - 1));
-    throw;
-  }
-#     endif /* __STL_USE_EXCEPTIONS */
-} 
-
-// Called only if finish.cur == finish.first.
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>:: pop_back_aux() {
-  deallocate_node(finish.first);
-  finish.set_node(finish.node - 1);
-  finish.cur = finish.last - 1;
-  destroy(finish.cur);
-}
-
-// Called only if start.cur == start.last - 1.  Note that if the deque
-//  has at least one element (a necessary precondition for this member
-//  function), and if start.cur == start.last, then the deque must have
-//  at least two nodes.
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::pop_front_aux() {
-  destroy(start.cur);
-  deallocate_node(start.first);
-  start.set_node(start.node + 1);
-  start.cur = start.first;
-}      
-
-#ifdef __STL_MEMBER_TEMPLATES  
-
-template <class T, class Alloc, size_t BufSize>
-template <class InputIterator>
-void deque<T, Alloc, BufSize>::insert(iterator pos,
-                                      InputIterator first, InputIterator last,
-                                      input_iterator_tag) {
-  copy(first, last, inserter(*this, pos));
-}
-
-template <class T, class Alloc, size_t BufSize>
-template <class ForwardIterator>
-void deque<T, Alloc, BufSize>::insert(iterator pos,
-                                      ForwardIterator first,
-                                      ForwardIterator last,
-                                      forward_iterator_tag) {
-  size_type n = 0;
-  distance(first, last, n);
-  if (pos.cur == start.cur) {
-    iterator new_start = reserve_elements_at_front(n);
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif
-      uninitialized_copy(first, last, new_start);
-      start = new_start;
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_nodes_at_front(new_start);
-      throw;
-    }
-#       endif
-  }
-  else if (pos.cur == finish.cur) {
-    iterator new_finish = reserve_elements_at_back(n);
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif
-      uninitialized_copy(first, last, finish);
-      finish = new_finish;
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_nodes_at_back(new_finish);
-      throw;
-    }
-#       endif
-  }
-  else
-    insert_aux(pos, first, last, n);
-}
-
-#endif /* __STL_MEMBER_TEMPLATES */
-
-template <class T, class Alloc, size_t BufSize>
-deque<T, Alloc, BufSize>::iterator
-deque<T, Alloc, BufSize>::insert_aux(iterator pos, const value_type& x) {
-  difference_type index = pos - start;
-  value_type x_copy = x;
-  if (index < size() / 2) {
-    push_front(front());
-    iterator front1 = start;
-    ++front1;
-    iterator front2 = front1;
-    ++front2;
-    pos = start + index;
-    iterator pos1 = pos;
-    ++pos1;
-    copy(front2, pos1, front1);
-  }
-  else {
-    push_back(back());
-    iterator back1 = finish;
-    --back1;
-    iterator back2 = back1;
-    --back2;
-    pos = start + index;
-    copy_backward(pos, back2, back1);
-  }
-  *pos = x_copy;
-  return pos;
-}
-
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
-                                          size_type n, const value_type& x) {
-  const difference_type elems_before = pos - start;
-  size_type length = size();
-  value_type x_copy = x;
-  if (elems_before < length / 2) {
-    iterator new_start = reserve_elements_at_front(n);
-    iterator old_start = start;
-    pos = start + elems_before;
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      if (elems_before >= n) {
-        iterator start_n = start + n;
-        uninitialized_copy(start, start_n, new_start);
-        start = new_start;
-        copy(start_n, pos, old_start);
-        fill(pos - n, pos, x_copy);
-      }
-      else {
-        __uninitialized_copy_fill(start, pos, new_start, start, x_copy);
-        start = new_start;
-        fill(old_start, pos, x_copy);
-      }
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_nodes_at_front(new_start);
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */
-  }
-  else {
-    iterator new_finish = reserve_elements_at_back(n);
-    iterator old_finish = finish;
-    const difference_type elems_after = length - elems_before;
-    pos = finish - elems_after;
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      if (elems_after > n) {
-        iterator finish_n = finish - n;
-        uninitialized_copy(finish_n, finish, finish);
-        finish = new_finish;
-        copy_backward(pos, finish_n, old_finish);
-        fill(pos, pos + n, x_copy);
-      }
-      else {
-        __uninitialized_fill_copy(finish, pos + n, x_copy, pos, finish);
-        finish = new_finish;
-        fill(pos, old_finish, x_copy);
-      }
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_nodes_at_back(new_finish);
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */    
-  }
-}
-
-#ifdef __STL_MEMBER_TEMPLATES  
-
-template <class T, class Alloc, size_t BufSize>
-template <class ForwardIterator>
-void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
-                                          ForwardIterator first,
-                                          ForwardIterator last,
-                                          size_type n)
-{
-  const difference_type elems_before = pos - start;
-  size_type length = size();
-  if (elems_before < length / 2) {
-    iterator new_start = reserve_elements_at_front(n);
-    iterator old_start = start;
-    pos = start + elems_before;
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      if (elems_before >= n) {
-        iterator start_n = start + n;      
-        uninitialized_copy(start, start_n, new_start);
-        start = new_start;
-        copy(start_n, pos, old_start);
-        copy(first, last, pos - n);
-      }
-      else {
-        ForwardIterator mid = first;
-        advance(mid, n - elems_before);
-        __uninitialized_copy_copy(start, pos, first, mid, new_start);
-        start = new_start;
-        copy(mid, last, old_start);
-      }
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_nodes_at_front(new_start);
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */
-  }
-  else {
-    iterator new_finish = reserve_elements_at_back(n);
-    iterator old_finish = finish;
-    const difference_type elems_after = length - elems_before;
-    pos = finish - elems_after;
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      if (elems_after > n) {
-        iterator finish_n = finish - n;
-        uninitialized_copy(finish_n, finish, finish);
-        finish = new_finish;
-        copy_backward(pos, finish_n, old_finish);
-        copy(first, last, pos);
-      }
-      else {
-        ForwardIterator mid = first;
-        advance(mid, elems_after);
-        __uninitialized_copy_copy(mid, last, pos, finish, finish);
-        finish = new_finish;
-        copy(first, mid, pos);
-      }
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_nodes_at_back(new_finish);
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */
-  }
-}
-
-#else /* __STL_MEMBER_TEMPLATES */
-
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
-                                          const value_type* first,
-                                          const value_type* last,
-                                          size_type n)
-{
-  const difference_type elems_before = pos - start;
-  size_type length = size();
-  if (elems_before < length / 2) {
-    iterator new_start = reserve_elements_at_front(n);
-    iterator old_start = start;
-    pos = start + elems_before;
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      if (elems_before >= n) {
-        iterator start_n = start + n;
-        uninitialized_copy(start, start_n, new_start);
-        start = new_start;
-        copy(start_n, pos, old_start);
-        copy(first, last, pos - n);
-      }
-      else {
-        const value_type* mid = first + (n - elems_before);
-        __uninitialized_copy_copy(start, pos, first, mid, new_start);
-        start = new_start;
-        copy(mid, last, old_start);
-      }
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_nodes_at_front(new_start);
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */
-  }
-  else {
-    iterator new_finish = reserve_elements_at_back(n);
-    iterator old_finish = finish;
-    const difference_type elems_after = length - elems_before;
-    pos = finish - elems_after;
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      if (elems_after > n) {
-        iterator finish_n = finish - n;
-        uninitialized_copy(finish_n, finish, finish);
-        finish = new_finish;
-        copy_backward(pos, finish_n, old_finish);
-        copy(first, last, pos);
-      }
-      else {
-        const value_type* mid = first + elems_after;
-        __uninitialized_copy_copy(mid, last, pos, finish, finish);
-        finish = new_finish;
-        copy(first, mid, pos);
-      }
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_nodes_at_back(new_finish);
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */
-  }
-}
-
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
-                                          const_iterator first,
-                                          const_iterator last,
-                                          size_type n)
-{
-  const difference_type elems_before = pos - start;
-  size_type length = size();
-  if (elems_before < length / 2) {
-    iterator new_start = reserve_elements_at_front(n);
-    iterator old_start = start;
-    pos = start + elems_before;
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      if (elems_before >= n) {
-        iterator start_n = start + n;
-        uninitialized_copy(start, start_n, new_start);
-        start = new_start;
-        copy(start_n, pos, old_start);
-        copy(first, last, pos - n);
-      }
-      else {
-        const_iterator mid = first + (n - elems_before);
-        __uninitialized_copy_copy(start, pos, first, mid, new_start);
-        start = new_start;
-        copy(mid, last, old_start);
-      }
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_nodes_at_front(new_start);
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */
-  }
-  else {
-    iterator new_finish = reserve_elements_at_back(n);
-    iterator old_finish = finish;
-    const difference_type elems_after = length - elems_before;
-    pos = finish - elems_after;
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      if (elems_after > n) {
-        iterator finish_n = finish - n;
-        uninitialized_copy(finish_n, finish, finish);
-        finish = new_finish;
-        copy_backward(pos, finish_n, old_finish);
-        copy(first, last, pos);
-      }
-      else {
-        const_iterator mid = first + elems_after;
-        __uninitialized_copy_copy(mid, last, pos, finish, finish);
-        finish = new_finish;
-        copy(first, mid, pos);
-      }
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy_nodes_at_back(new_finish);
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */
-  }
-}
-
-#endif /* __STL_MEMBER_TEMPLATES */
-
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::new_elements_at_front(size_type new_elements) {
-  size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size();
-  reserve_map_at_front(new_nodes);
-  size_type i;
-#       ifdef __STL_USE_EXCEPTIONS
-  try {
-#       endif /* __STL_USE_EXCEPTIONS */
-    for (i = 1; i <= new_nodes; ++i)
-      *(start.node - i) = allocate_node();
-#       ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    for (size_type j = 1; j < i; ++j)
-      deallocate_node(*(start.node - j));      
-    throw;
-  }
-#       endif /* __STL_USE_EXCEPTIONS */
-}
-
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::new_elements_at_back(size_type new_elements) {
-  size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size();
-  reserve_map_at_back(new_nodes);
-  size_type i;
-#       ifdef __STL_USE_EXCEPTIONS
-  try {
-#       endif /* __STL_USE_EXCEPTIONS */
-    for (i = 1; i <= new_nodes; ++i)
-      *(finish.node + i) = allocate_node();
-#       ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    for (size_type j = 1; j < i; ++j)
-      deallocate_node(*(finish.node + j));      
-    throw;
-  }
-#       endif /* __STL_USE_EXCEPTIONS */
-}
-
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::destroy_nodes_at_front(iterator before_start) {
-  for (map_pointer n = before_start.node; n < start.node; ++n)
-    deallocate_node(*n);
-}
-
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::destroy_nodes_at_back(iterator after_finish) {
-  for (map_pointer n = after_finish.node; n > finish.node; --n)
-    deallocate_node(*n);
-}
-
-template <class T, class Alloc, size_t BufSize>
-void deque<T, Alloc, BufSize>::reallocate_map(size_type nodes_to_add,
-                                              bool add_at_front) {
-  size_type old_num_nodes = finish.node - start.node + 1;
-  size_type new_num_nodes = old_num_nodes + nodes_to_add;
-
-  map_pointer new_nstart;
-  if (map_size > 2 * new_num_nodes) {
-    new_nstart = map + (map_size - new_num_nodes) / 2 
-                     + (add_at_front ? nodes_to_add : 0);
-    if (new_nstart < start.node)
-      copy(start.node, finish.node + 1, new_nstart);
-    else
-      copy_backward(start.node, finish.node + 1, new_nstart + old_num_nodes);
-  }
-  else {
-    size_type new_map_size = map_size + max(map_size, nodes_to_add) + 2;
-
-    map_pointer new_map = map_allocator::allocate(new_map_size);
-    new_nstart = new_map + (new_map_size - new_num_nodes) / 2
-                         + (add_at_front ? nodes_to_add : 0);
-    copy(start.node, finish.node + 1, new_nstart);
-    map_allocator::deallocate(map, map_size);
-
-    map = new_map;
-    map_size = new_map_size;
-  }
-
-  start.set_node(new_nstart);
-  finish.set_node(new_nstart + old_num_nodes - 1);
-}
-
-
-// Nonmember functions.
-
-#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
-
-template <class T, class Alloc, size_t BufSiz>
-bool operator==(const deque<T, Alloc, BufSiz>& x,
-                const deque<T, Alloc, BufSiz>& y) {
-  return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
-}
-
-template <class T, class Alloc, size_t BufSiz>
-bool operator<(const deque<T, Alloc, BufSiz>& x,
-               const deque<T, Alloc, BufSiz>& y) {
-  return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
-}
+#ifdef __STL_USE_NAMESPACES
+using __STD::deque;
+#endif /* __STL_USE_NAMESPACES */
 
-#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
-           
-  
 #endif /* __SGI_STL_DEQUE_H */
 
+// Local Variables:
+// mode:C++
+// End:
index e4f4713..6474dd9 100644 (file)
@@ -12,7 +12,7 @@
  * purpose.  It is provided "as is" without express or implied warranty.
  *
  *
- * Copyright (c) 1996
+ * Copyright (c) 1996,1997
  * Silicon Graphics Computer Systems, Inc.
  *
  * Permission to use, copy, modify, distribute and sell this software
 #ifndef __SGI_STL_FUNCTION_H
 #define __SGI_STL_FUNCTION_H
 
-#include <stddef.h>
+#ifndef __STL_CONFIG_H
 #include <stl_config.h>
-
-template <class T>
-inline bool operator!=(const T& x, const T& y) {
-    return !(x == y);
-}
-
-template <class T>
-inline bool operator>(const T& x, const T& y) {
-    return y < x;
-}
-
-template <class T>
-inline bool operator<=(const T& x, const T& y) {
-    return !(y < x);
-}
-
-template <class T>
-inline bool operator>=(const T& x, const T& y) {
-    return !(x < y);
-}
-
-template <class Arg, class Result>
-struct unary_function {
-    typedef Arg argument_type;
-    typedef Result result_type;
-};
-
-template <class Arg1, class Arg2, class Result>
-struct binary_function {
-    typedef Arg1 first_argument_type;
-    typedef Arg2 second_argument_type;
-    typedef Result result_type;
-};      
-
-template <class T>
-struct plus : public binary_function<T, T, T> {
-    T operator()(const T& x, const T& y) const { return x + y; }
-};
-
-template <class T>
-struct minus : public binary_function<T, T, T> {
-    T operator()(const T& x, const T& y) const { return x - y; }
-};
-
-template <class T>
-struct multiplies : public binary_function<T, T, T> {
-    T operator()(const T& x, const T& y) const { return x * y; }
-};
-
-template <class T>
-struct divides : public binary_function<T, T, T> {
-    T operator()(const T& x, const T& y) const { return x / y; }
-};
-
-template <class T> inline T identity_element(plus<T>) { return T(0); }
-
-template <class T> inline T identity_element(multiplies<T>) { return T(1); }
-
-template <class T>
-struct modulus : public binary_function<T, T, T> {
-    T operator()(const T& x, const T& y) const { return x % y; }
-};
-
-template <class T>
-struct negate : public unary_function<T, T> {
-    T operator()(const T& x) const { return -x; }
-};
-
-template <class T>
-struct equal_to : public binary_function<T, T, bool> {
-    bool operator()(const T& x, const T& y) const { return x == y; }
-};
-
-template <class T>
-struct not_equal_to : public binary_function<T, T, bool> {
-    bool operator()(const T& x, const T& y) const { return x != y; }
-};
-
-template <class T>
-struct greater : public binary_function<T, T, bool> {
-    bool operator()(const T& x, const T& y) const { return x > y; }
-};
-
-template <class T>
-struct less : public binary_function<T, T, bool> {
-    bool operator()(const T& x, const T& y) const { return x < y; }
-};
-
-template <class T>
-struct greater_equal : public binary_function<T, T, bool> {
-    bool operator()(const T& x, const T& y) const { return x >= y; }
-};
-
-template <class T>
-struct less_equal : public binary_function<T, T, bool> {
-    bool operator()(const T& x, const T& y) const { return x <= y; }
-};
-
-template <class T>
-struct logical_and : public binary_function<T, T, bool> {
-    bool operator()(const T& x, const T& y) const { return x && y; }
-};
-
-template <class T>
-struct logical_or : public binary_function<T, T, bool> {
-    bool operator()(const T& x, const T& y) const { return x || y; }
-};
-
-template <class T>
-struct logical_not : public unary_function<T, bool> {
-    bool operator()(const T& x) const { return !x; }
-};
-
-template <class Predicate>
-class unary_negate
-  : public unary_function<typename Predicate::argument_type, bool> {
-protected:
-    Predicate pred;
-public:
-    explicit unary_negate(const Predicate& x) : pred(x) {}
-    bool operator()(const argument_type& x) const { return !pred(x); }
-};
-
-template <class Predicate>
-inline unary_negate<Predicate> not1(const Predicate& pred) {
-  return unary_negate<Predicate>(pred);
-}
-
-template <class Predicate> 
-class binary_negate 
-    : public binary_function<typename Predicate::first_argument_type,
-                            typename Predicate::second_argument_type,
-                             bool> {
-protected:
-    Predicate pred;
-public:
-    explicit binary_negate(const Predicate& x) : pred(x) {}
-    bool operator()(const first_argument_type& x, 
-                   const second_argument_type& y) const {
-       return !pred(x, y); 
-    }
-};
-
-template <class Predicate>
-inline binary_negate<Predicate> not2(const Predicate& pred) {
-  return binary_negate<Predicate>(pred);
-}
-
-template <class Operation> 
-class binder1st
-  : public unary_function<typename Operation::second_argument_type,
-                          typename Operation::result_type> {
-protected:
-    Operation op;
-    typename Operation::first_argument_type value;
-public:
-    binder1st(const Operation& x,
-              const typename Operation::first_argument_type& y)
-      : op(x), value(y) {}
-    result_type operator()(const argument_type& x) const {
-       return op(value, x); 
-    }
-};
-
-template <class Operation, class T>
-inline binder1st<Operation> bind1st(const Operation& op, const T& x) {
-  typedef typename Operation::first_argument_type arg1_type;
-  return binder1st<Operation>(op, arg1_type(x));
-}
-
-template <class Operation> 
-class binder2nd
-  : public unary_function<typename Operation::first_argument_type,
-                         typename Operation::result_type> {
-protected:
-    Operation op;
-    typename Operation::second_argument_type value;
-public:
-    binder2nd(const Operation& x,
-              const typename Operation::second_argument_type& y) 
-       : op(x), value(y) {}
-    result_type operator()(const argument_type& x) const {
-       return op(x, value); 
-    }
-};
-
-template <class Operation, class T>
-inline binder2nd<Operation> bind2nd(const Operation& op, const T& x) {
-  typedef typename Operation::second_argument_type arg2_type;
-  return binder2nd<Operation>(op, arg2_type(x));
-}
-
-template <class Operation1, class Operation2>
-class unary_compose : public unary_function<typename Operation2::argument_type,
-                                            typename Operation1::result_type> {
-protected:
-    Operation1 op1;
-    Operation2 op2;
-public:
-    unary_compose(const Operation1& x, const Operation2& y) : op1(x), op2(y) {}
-    result_type operator()(const argument_type& x) const {
-       return op1(op2(x));
-    }
-};
-
-template <class Operation1, class Operation2>
-inline unary_compose<Operation1, Operation2> compose1(const Operation1& op1, 
-                                                      const Operation2& op2) {
-  return unary_compose<Operation1, Operation2>(op1, op2);
-}
-
-template <class Operation1, class Operation2, class Operation3>
-class binary_compose
-  : public unary_function<typename Operation2::argument_type,
-                          typename Operation1::result_type> {
-protected:
-    Operation1 op1;
-    Operation2 op2;
-    Operation3 op3;
-public:
-    binary_compose(const Operation1& x, const Operation2& y, 
-                  const Operation3& z) : op1(x), op2(y), op3(z) { }
-    result_type operator()(const argument_type& x) const {
-       return op1(op2(x), op3(x));
-    }
-};
-
-template <class Operation1, class Operation2, class Operation3>
-inline binary_compose<Operation1, Operation2, Operation3> 
-compose2(const Operation1& op1, const Operation2& op2, const Operation3& op3) {
-  return binary_compose<Operation1, Operation2, Operation3>(op1, op2, op3);
-}
-
-template <class Arg, class Result>
-class pointer_to_unary_function : public unary_function<Arg, Result> {
-protected:
-    Result (*ptr)(Arg);
-public:
-    pointer_to_unary_function() {}
-    explicit pointer_to_unary_function(Result (*x)(Arg)) : ptr(x) {}
-    Result operator()(Arg x) const { return ptr(x); }
-};
-
-template <class Arg, class Result>
-inline pointer_to_unary_function<Arg, Result> ptr_fun(Result (*x)(Arg)) {
-  return pointer_to_unary_function<Arg, Result>(x);
-}
-
-template <class Arg1, class Arg2, class Result>
-class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result> {
-protected:
-    Result (*ptr)(Arg1, Arg2);
-public:
-    pointer_to_binary_function() {}
-    explicit pointer_to_binary_function(Result (*x)(Arg1, Arg2)) : ptr(x) {}
-    Result operator()(Arg1 x, Arg2 y) const { return ptr(x, y); }
-};
-
-template <class Arg1, class Arg2, class Result>
-inline pointer_to_binary_function<Arg1, Arg2, Result> 
-ptr_fun(Result (*x)(Arg1, Arg2)) {
-  return pointer_to_binary_function<Arg1, Arg2, Result>(x);
-}
-
-template <class T>
-struct identity : public unary_function<T, T> {
-    const T& operator()(const T& x) const { return x; }
-};
-
-template <class Pair>
-struct select1st : public unary_function<Pair, typename Pair::first_type> {
-  const typename Pair::first_type& operator()(const Pair& x) const
-  {
-    return x.first;
-  }
-};
-
-template <class Pair>
-struct select2nd : public unary_function<Pair, typename Pair::second_type> {
-  const typename Pair::second_type& operator()(const Pair& x) const
-  {
-    return x.second;
-  }
-};
-
-template <class Arg1, class Arg2>
-struct project1st : public binary_function<Arg1, Arg2, Arg1> {
-  Arg1 operator()(const Arg1& x, const Arg2&) const { return x; }
-};
-
-template <class Arg1, class Arg2>
-struct project2nd : public binary_function<Arg1, Arg2, Arg2> {
-  Arg2 operator()(const Arg1&, const Arg2& y) const { return y; }
-};
-
-template <class Result>
-struct constant_void_fun
-{
-  typedef Result result_type;
-  result_type val;
-  constant_void_fun(const result_type& v) : val(v) {}
-  const result_type& operator()() const { return val; }
-};  
-
-#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
-template <class Result, class Argument = Result>
-#else
-template <class Result, class Argument>
 #endif
-struct constant_unary_fun : public unary_function<Argument, Result> {
-  result_type val;
-  constant_unary_fun(const result_type& v) : val(v) {}
-  const result_type& operator()(const argument_type&) const { return val; }
-};
-
-#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
-template <class Result, class Arg1 = Result, class Arg2 = Arg1>
-#else
-template <class Result, class Arg1, class Arg2>
+#ifndef __SGI_STL_INTERNAL_RELOPS
+#include <stl_relops.h>
+#endif
+#include <stddef.h>
+#ifndef __SGI_STL_INTERNAL_FUNCTION_H
+#include <stl_function.h>
 #endif
-struct constant_binary_fun : public binary_function<Arg1, Arg2, Result> {
-  result_type val;
-  constant_binary_fun(const result_type& v) : val(v) {}
-  const result_type& operator()(const first_argument_type&, 
-                                const second_argument_type&) const {
-    return val;
-  }
-};
-
-template <class Result>
-inline constant_void_fun<Result> constant0(const Result& val)
-{
-  return constant_void_fun<Result>(val);
-}
-
-template <class Result>
-inline constant_unary_fun<Result,Result> constant1(const Result& val)
-{
-  return constant_unary_fun<Result,Result>(val);
-}
-
-template <class Result>
-inline constant_binary_fun<Result,Result,Result> constant2(const Result& val)
-{
-  return constant_binary_fun<Result,Result,Result>(val);
-}
-
-// Note: this code assumes that int is 32 bits.
-class subtractive_rng : public unary_function<unsigned int, unsigned int> {
-private:
-  unsigned int table[55];
-  size_t index1;
-  size_t index2;
-public:
-  unsigned int operator()(unsigned int limit) {
-    index1 = (index1 + 1) % 55;
-    index2 = (index2 + 1) % 55;
-    table[index1] = table[index1] - table[index2];
-    return table[index1] % limit;
-  }
-
-  void initialize(unsigned int seed)
-  {
-    unsigned int k = 1;
-    table[54] = seed;
-    size_t i;
-    for (i = 0; i < 54; i++) {
-        size_t ii = (21 * (i + 1) % 55) - 1;
-        table[ii] = k;
-        k = seed - k;
-        seed = table[ii];
-    }
-    for (int loop = 0; loop < 4; loop++) {
-        for (i = 0; i < 55; i++)
-            table[i] = table[i] - table[(1 + i + 30) % 55];
-    }
-    index1 = 0;
-    index2 = 31;
-  }
-
-  subtractive_rng(unsigned int seed) { initialize(seed); }
-  subtractive_rng() { initialize(161803398u); }
-};
-
-
-// Adaptor function objects: pointers to member functions.
-
-// There are a total of 16 = 2^4 function objects in this family.
-//  (1) Member functions taking no arguments vs member functions taking
-//       one argument.
-//  (2) Call through pointer vs call through reference.
-//  (3) Member function with void return type vs member function with
-//      non-void return type.
-//  (4) Const vs non-const member function.
-
-// Note that choice (4) is not present in the 8/97 draft C++ standard, 
-//  which only allows these adaptors to be used with non-const functions.
-//  This is likely to be recified before the standard becomes final.
-// Note also that choice (3) is nothing more than a workaround: according
-//  to the draft, compilers should handle void and non-void the same way.
-//  This feature is not yet widely implemented, though.  You can only use
-//  member functions returning void if your compiler supports partial
-//  specialization.
-
-// All of this complexity is in the function objects themselves.  You can
-//  ignore it by using the helper function mem_fun, mem_fun_ref,
-//  mem_fun1, and mem_fun1_ref, which create whichever type of adaptor
-//  is appropriate.
-
-
-template <class S, class T>
-class mem_fun_t : public unary_function<T*, S> {
-public:
-  explicit mem_fun_t(S (T::*pf)()) : f(pf) {}
-  S operator()(T* p) const { return (p->*f)(); }
-private:
-  S (T::*f)();
-};
-
-template <class S, class T>
-class const_mem_fun_t : public unary_function<const T*, S> {
-public:
-  explicit const_mem_fun_t(S (T::*pf)() const) : f(pf) {}
-  S operator()(const T* p) const { return (p->*f)(); }
-private:
-  S (T::*f)() const;
-};
-
-
-template <class S, class T>
-class mem_fun_ref_t : public unary_function<T, S> {
-public:
-  explicit mem_fun_ref_t(S (T::*pf)()) : f(pf) {}
-  S operator()(T& r) const { return (r.*f)(); }
-private:
-  S (T::*f)();
-};
-
-template <class S, class T>
-class const_mem_fun_ref_t : public unary_function<T, S> {
-public:
-  explicit const_mem_fun_ref_t(S (T::*pf)() const) : f(pf) {}
-  S operator()(const T& r) const { return (r.*f)(); }
-private:
-  S (T::*f)() const;
-};
-
-template <class S, class T, class A>
-class mem_fun1_t : public binary_function<T*, A, S> {
-public:
-  explicit mem_fun1_t(S (T::*pf)(A)) : f(pf) {}
-  S operator()(T* p, A x) const { return (p->*f)(x); }
-private:
-  S (T::*f)(A);
-};
-
-template <class S, class T, class A>
-class const_mem_fun1_t : public binary_function<const T*, A, S> {
-public:
-  explicit const_mem_fun1_t(S (T::*pf)(A) const) : f(pf) {}
-  S operator()(const T* p, A x) const { return (p->*f)(x); }
-private:
-  S (T::*f)(A) const;
-};
-
-template <class S, class T, class A>
-class mem_fun1_ref_t : public binary_function<T, A, S> {
-public:
-  explicit mem_fun1_ref_t(S (T::*pf)(A)) : f(pf) {}
-  S operator()(T& r, A x) const { return (r.*f)(x); }
-private:
-  S (T::*f)(A);
-};
-
-template <class S, class T, class A>
-class const_mem_fun1_ref_t : public binary_function<T, A, S> {
-public:
-  explicit const_mem_fun1_ref_t(S (T::*pf)(A) const) : f(pf) {}
-  S operator()(const T& r, A x) const { return (r.*f)(x); }
-private:
-  S (T::*f)(A) const;
-};
-
-#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-template <class T>
-class mem_fun_t<void, T> : public unary_function<T*, void> {
-public:
-  explicit mem_fun_t(void (T::*pf)()) : f(pf) {}
-  void operator()(T* p) const { (p->*f)(); }
-private:
-  void (T::*f)();
-};
-
-template <class T>
-class const_mem_fun_t<void, T> : public unary_function<const T*, void> {
-public:
-  explicit const_mem_fun_t(void (T::*pf)() const) : f(pf) {}
-  void operator()(const T* p) const { (p->*f)(); }
-private:
-  void (T::*f)() const;
-};
-
-template <class T>
-class mem_fun_ref_t<void, T> : public unary_function<T, void> {
-public:
-  explicit mem_fun_ref_t(void (T::*pf)()) : f(pf) {}
-  void operator()(T& r) const { (r.*f)(); }
-private:
-  void (T::*f)();
-};
-
-template <class T>
-class const_mem_fun_ref_t<void, T> : public unary_function<T, void> {
-public:
-  explicit const_mem_fun_ref_t(void (T::*pf)() const) : f(pf) {}
-  void operator()(const T& r) const { (r.*f)(); }
-private:
-  void (T::*f)() const;
-};
-
-template <class T, class A>
-class mem_fun1_t<void, T, A> : public binary_function<T*, A, void> {
-public:
-  explicit mem_fun1_t(void (T::*pf)(A)) : f(pf) {}
-  void operator()(T* p, A x) const { (p->*f)(x); }
-private:
-  void (T::*f)(A);
-};
-
-template <class T, class A>
-class const_mem_fun1_t<void, T, A> : public binary_function<const T*, A, void> {
-public:
-  explicit const_mem_fun1_t(void (T::*pf)(A) const) : f(pf) {}
-  void operator()(const T* p, A x) const { (p->*f)(x); }
-private:
-  void (T::*f)(A) const;
-};
-
-template <class T, class A>
-class mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> {
-public:
-  explicit mem_fun1_ref_t(void (T::*pf)(A)) : f(pf) {}
-  void operator()(T& r, A x) const { (r.*f)(x); }
-private:
-  void (T::*f)(A);
-};
-
-template <class T, class A>
-class const_mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> {
-public:
-  explicit const_mem_fun1_ref_t(void (T::*pf)(A) const) : f(pf) {}
-  void operator()(const T& r, A x) const { (r.*f)(x); }
-private:
-  void (T::*f)(A) const;
-};
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-// Mem_fun adaptor helper functions.  There are only four:
-//  mem_fun, mem_fun_ref, mem_fun1, mem_fun1_ref.
-
-template <class S, class T>
-inline mem_fun_t<S,T> mem_fun(S (T::*f)()) { 
-  return mem_fun_t<S,T>(f);
-}
-
-template <class S, class T>
-inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const) {
-  return const_mem_fun_t<S,T>(f);
-}
-
-template <class S, class T>
-inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)()) { 
-  return mem_fun_ref_t<S,T>(f);
-}
-
-template <class S, class T>
-inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const) {
-  return const_mem_fun_ref_t<S,T>(f);
-}
-
-template <class S, class T, class A>
-inline mem_fun1_t<S,T,A> mem_fun1(S (T::*f)(A)) { 
-  return mem_fun1_t<S,T,A>(f);
-}
-
-template <class S, class T, class A>
-inline const_mem_fun1_t<S,T,A> mem_fun1(S (T::*f)(A) const) {
-  return const_mem_fun1_t<S,T,A>(f);
-}
-
-template <class S, class T, class A>
-inline mem_fun1_ref_t<S,T,A> mem_fun1_ref(S (T::*f)(A)) { 
-  return mem_fun1_ref_t<S,T,A>(f);
-}
 
-template <class S, class T, class A>
-inline const_mem_fun1_ref_t<S,T,A> mem_fun1_ref(S (T::*f)(A) const) {
-  return const_mem_fun1_ref_t<S,T,A>(f);
-}
+#ifdef __STL_USE_NAMESPACE_FOR_RELOPS
+
+// Names from stl_relops.h
+using __STD_RELOPS::operator!=;
+using __STD_RELOPS::operator>;
+using __STD_RELOPS::operator<=;
+using __STD_RELOPS::operator>=;
+
+#endif /* __STL_USE_NAMESPACE_FOR_RELOPS */
+
+#ifdef __STL_USE_NAMESPACES
+
+// Names from stl_function.h
+using __STD::unary_function; 
+using __STD::binary_function; 
+using __STD::plus; 
+using __STD::minus; 
+using __STD::multiplies; 
+using __STD::divides; 
+using __STD::identity_element; 
+using __STD::modulus; 
+using __STD::negate; 
+using __STD::equal_to; 
+using __STD::not_equal_to; 
+using __STD::greater; 
+using __STD::less; 
+using __STD::greater_equal; 
+using __STD::less_equal; 
+using __STD::logical_and; 
+using __STD::logical_or; 
+using __STD::logical_not; 
+using __STD::unary_negate; 
+using __STD::binary_negate; 
+using __STD::not1; 
+using __STD::not2; 
+using __STD::binder1st; 
+using __STD::binder2nd; 
+using __STD::bind1st; 
+using __STD::bind2nd; 
+using __STD::unary_compose; 
+using __STD::binary_compose; 
+using __STD::compose1; 
+using __STD::compose2; 
+using __STD::pointer_to_unary_function; 
+using __STD::pointer_to_binary_function; 
+using __STD::ptr_fun; 
+using __STD::identity; 
+using __STD::select1st; 
+using __STD::select2nd; 
+using __STD::project1st; 
+using __STD::project2nd; 
+using __STD::constant_void_fun; 
+using __STD::constant_unary_fun; 
+using __STD::constant_binary_fun; 
+using __STD::constant0; 
+using __STD::constant1; 
+using __STD::constant2; 
+using __STD::subtractive_rng; 
+using __STD::mem_fun_t; 
+using __STD::const_mem_fun_t; 
+using __STD::mem_fun_ref_t; 
+using __STD::const_mem_fun_ref_t; 
+using __STD::mem_fun1_t; 
+using __STD::const_mem_fun1_t; 
+using __STD::mem_fun1_ref_t; 
+using __STD::const_mem_fun1_ref_t; 
+using __STD::mem_fun; 
+using __STD::mem_fun_ref; 
+using __STD::mem_fun1; 
+using __STD::mem_fun1_ref; 
+
+#endif /* __STL_USE_NAMESPACES */
 
 #endif /* __SGI_STL_FUNCTION_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/functional b/libstdc++/stl/functional
new file mode 100644 (file)
index 0000000..d046dbb
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef __SGI_STL_FUNCTIONAL
+#define __SGI_STL_FUNCTIONAL
+
+#include <stl_config.h>
+#include <stddef.h>
+#include <stl_function.h>
+
+#endif /* __SGI_STL_FUNCTIONAL */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/hash_map b/libstdc++/stl/hash_map
new file mode 100644 (file)
index 0000000..f7421e0
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef __SGI_STL_HASH_MAP
+#define __SGI_STL_HASH_MAP
+
+#ifndef __SGI_STL_INTERNAL_HASHTABLE_H
+#include <stl_hashtable.h>
+#endif 
+
+#include <stl_hash_map.h>
+
+#endif /* __SGI_STL_HASH_MAP */
+
+// Local Variables:
+// mode:C++
+// End:
index c52b993..81cb578 100644 (file)
 #ifndef __SGI_STL_HASH_MAP_H
 #define __SGI_STL_HASH_MAP_H
 
-#ifndef __SGI_STL_HASHTABLE_H
-#include <hashtable.h>
-#endif /* __SGI_STL_HASHTABLE_H */
+#ifndef __SGI_STL_INTERNAL_HASHTABLE_H
+#include <stl_hashtable.h>
+#endif 
 
+#include <stl_hash_map.h>
 
-#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
-template <class Key, class T, class HashFcn = hash<Key>,
-          class EqualKey = equal_to<Key>,
-          class Alloc = alloc>
-#else
-template <class Key, class T, class HashFcn, class EqualKey, 
-          class Alloc = alloc>
-#endif
-class hash_map
-{
-private:
-  typedef hashtable<pair<const Key, T>, Key, HashFcn,
-                    select1st<pair<const Key, T> >, EqualKey, Alloc> ht;
-  ht rep;
+#ifdef __STL_USE_NAMESPACES
+using __STD::hash;
+using __STD::hashtable;
+using __STD::hash_map;
+using __STD::hash_multimap;
+#endif /* __STL_USE_NAMESPACES */
 
-public:
-  typedef ht::key_type key_type;
-  typedef ht::value_type value_type;
-  typedef ht::hasher hasher;
-  typedef ht::key_equal key_equal;
-  typedef T data_type;
-
-  typedef ht::size_type size_type;
-  typedef ht::difference_type difference_type;
-  typedef ht::pointer pointer;
-  typedef ht::const_pointer const_pointer;
-  typedef ht::reference reference;
-  typedef ht::const_reference const_reference;
-
-  typedef ht::iterator iterator;
-  typedef ht::const_iterator const_iterator;
-
-  hasher hash_funct() const { return rep.hash_funct(); }
-  key_equal key_eq() const { return rep.key_eq(); }
-
-public:
-  hash_map() : rep(100, hasher(), key_equal()) {}
-  explicit hash_map(size_type n) : rep(n, hasher(), key_equal()) {}
-  hash_map(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
-  hash_map(size_type n, const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) {}
-
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  hash_map(InputIterator f, InputIterator l)
-    : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
-  template <class InputIterator>
-  hash_map(InputIterator f, InputIterator l, size_type n)
-    : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
-  template <class InputIterator>
-  hash_map(InputIterator f, InputIterator l, size_type n,
-           const hasher& hf)
-    : rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
-  template <class InputIterator>
-  hash_map(InputIterator f, InputIterator l, size_type n,
-           const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) { rep.insert_unique(f, l); }
-
-#else
-  hash_map(const value_type* f, const value_type* l)
-    : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
-  hash_map(const value_type* f, const value_type* l, size_type n)
-    : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
-  hash_map(const value_type* f, const value_type* l, size_type n,
-           const hasher& hf)
-    : rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
-  hash_map(const value_type* f, const value_type* l, size_type n,
-           const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) { rep.insert_unique(f, l); }
-
-  hash_map(const_iterator f, const_iterator l)
-    : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
-  hash_map(const_iterator f, const_iterator l, size_type n)
-    : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
-  hash_map(const_iterator f, const_iterator l, size_type n,
-           const hasher& hf)
-    : rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
-  hash_map(const_iterator f, const_iterator l, size_type n,
-           const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) { rep.insert_unique(f, l); }
-#endif /*__STL_MEMBER_TEMPLATES */
-
-public:
-  size_type size() const { return rep.size(); }
-  size_type max_size() const { return rep.max_size(); }
-  bool empty() const { return rep.empty(); }
-  void swap(hash_map& hs) { rep.swap(hs.rep); }
-  friend bool operator==(const hash_map<Key,T,HashFcn,EqualKey,Alloc>&,
-                         const hash_map<Key,T,HashFcn,EqualKey,Alloc>&);
-
-  iterator begin() { return rep.begin(); }
-  iterator end() { return rep.end(); }
-  const_iterator begin() const { return rep.begin(); }
-  const_iterator end() const { return rep.end(); }
-
-public:
-  pair<iterator, bool> insert(const value_type& obj)
-    { return rep.insert_unique(obj); }
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); }
-#else
-  void insert(const value_type* f, const value_type* l) {
-    rep.insert_unique(f,l);
-  }
-  void insert(const_iterator f, const_iterator l) { rep.insert_unique(f, l); }
-#endif /*__STL_MEMBER_TEMPLATES */
-  pair<iterator, bool> insert_noresize(const value_type& obj)
-    { return rep.insert_unique_noresize(obj); }    
-
-  iterator find(const key_type& key) { return rep.find(key); }
-  const_iterator find(const key_type& key) const { return rep.find(key); }
-
-  T& operator[](const key_type& key)
-  {
-    return rep.find_or_insert(value_type(key, T())).second;
-  }
-
-  size_type count(const key_type& key) const { return rep.count(key); }
-  
-  pair<iterator, iterator> equal_range(const key_type& key)
-    { return rep.equal_range(key); }
-  pair<const_iterator, const_iterator> equal_range(const key_type& key) const
-    { return rep.equal_range(key); }
-
-  size_type erase(const key_type& key) {return rep.erase(key); }
-  void erase(iterator it) { rep.erase(it); }
-  void erase(iterator f, iterator l) { rep.erase(f, l); }
-  void clear() { rep.clear(); }
-
-public:
-  void resize(size_type hint) { rep.resize(hint); }
-  size_type bucket_count() const { return rep.bucket_count(); }
-  size_type max_bucket_count() const { return rep.max_bucket_count(); }
-  size_type elems_in_bucket(size_type n) const
-    { return rep.elems_in_bucket(n); }
-};
-
-template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
-inline bool operator==(const hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1,
-                       const hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2)
-{
-  return hm1.rep == hm2.rep;
-}
-
-#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
-template <class Key, class T, class HashFcn = hash<Key>,
-          class EqualKey = equal_to<Key>,
-          class Alloc = alloc>
-#else
-template <class Key, class T, class HashFcn, class EqualKey,
-          class Alloc = alloc>
-#endif
-class hash_multimap
-{
-private:
-  typedef hashtable<pair<const Key, T>, Key, HashFcn,
-                    select1st<pair<const Key, T> >, EqualKey, Alloc> ht;
-  ht rep;
-
-public:
-  typedef ht::key_type key_type;
-  typedef ht::value_type value_type;
-  typedef ht::hasher hasher;
-  typedef ht::key_equal key_equal;
-  typedef T data_type;
-
-  typedef ht::size_type size_type;
-  typedef ht::difference_type difference_type;
-  typedef ht::pointer pointer;
-  typedef ht::const_pointer const_pointer;
-  typedef ht::reference reference;
-  typedef ht::const_reference const_reference;
-
-  typedef ht::iterator iterator;
-  typedef ht::const_iterator const_iterator;
-
-  hasher hash_funct() const { return rep.hash_funct(); }
-  key_equal key_eq() const { return rep.key_eq(); }
-
-public:
-  hash_multimap() : rep(100, hasher(), key_equal()) {}
-  explicit hash_multimap(size_type n) : rep(n, hasher(), key_equal()) {}
-  hash_multimap(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
-  hash_multimap(size_type n, const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) {}
-
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  hash_multimap(InputIterator f, InputIterator l)
-    : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
-  template <class InputIterator>
-  hash_multimap(InputIterator f, InputIterator l, size_type n)
-    : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
-  template <class InputIterator>
-  hash_multimap(InputIterator f, InputIterator l, size_type n,
-                const hasher& hf)
-    : rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
-  template <class InputIterator>
-  hash_multimap(InputIterator f, InputIterator l, size_type n,
-                const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) { rep.insert_equal(f, l); }
-
-#else
-  hash_multimap(const value_type* f, const value_type* l)
-    : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
-  hash_multimap(const value_type* f, const value_type* l, size_type n)
-    : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
-  hash_multimap(const value_type* f, const value_type* l, size_type n,
-                const hasher& hf)
-    : rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
-  hash_multimap(const value_type* f, const value_type* l, size_type n,
-                const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) { rep.insert_equal(f, l); }
-
-  hash_multimap(const_iterator f, const_iterator l)
-    : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
-  hash_multimap(const_iterator f, const_iterator l, size_type n)
-    : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
-  hash_multimap(const_iterator f, const_iterator l, size_type n,
-                const hasher& hf)
-    : rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
-  hash_multimap(const_iterator f, const_iterator l, size_type n,
-                const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) { rep.insert_equal(f, l); }
-#endif /*__STL_MEMBER_TEMPLATES */
-
-public:
-  size_type size() const { return rep.size(); }
-  size_type max_size() const { return rep.max_size(); }
-  bool empty() const { return rep.empty(); }
-  void swap(hash_multimap& hs) { rep.swap(hs.rep); }
-  friend bool operator==(const hash_multimap<Key,T,HashFcn,EqualKey,Alloc>&,
-                         const hash_multimap<Key,T,HashFcn,EqualKey,Alloc>&);
-
-  iterator begin() { return rep.begin(); }
-  iterator end() { return rep.end(); }
-  const_iterator begin() const { return rep.begin(); }
-  const_iterator end() const { return rep.end(); }
-
-public:
-  iterator insert(const value_type& obj) { return rep.insert_equal(obj); }
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); }
-#else
-  void insert(const value_type* f, const value_type* l) {
-    rep.insert_equal(f,l);
-  }
-  void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); }
-#endif /*__STL_MEMBER_TEMPLATES */
-  iterator insert_noresize(const value_type& obj)
-    { return rep.insert_equal_noresize(obj); }    
-
-  iterator find(const key_type& key) { return rep.find(key); }
-  const_iterator find(const key_type& key) const { return rep.find(key); }
-
-  size_type count(const key_type& key) const { return rep.count(key); }
-  
-  pair<iterator, iterator> equal_range(const key_type& key)
-    { return rep.equal_range(key); }
-  pair<const_iterator, const_iterator> equal_range(const key_type& key) const
-    { return rep.equal_range(key); }
-
-  size_type erase(const key_type& key) {return rep.erase(key); }
-  void erase(iterator it) { rep.erase(it); }
-  void erase(iterator f, iterator l) { rep.erase(f, l); }
-  void clear() { rep.clear(); }
-
-public:
-  void resize(size_type hint) { rep.resize(hint); }
-  size_type bucket_count() const { return rep.bucket_count(); }
-  size_type max_bucket_count() const { return rep.max_bucket_count(); }
-  size_type elems_in_bucket(size_type n) const
-    { return rep.elems_in_bucket(n); }
-};
-
-template <class Key, class T, class HF, class EqKey, class Alloc>
-inline bool operator==(const hash_multimap<Key, T, HF, EqKey, Alloc>& hm1,
-                       const hash_multimap<Key, T, HF, EqKey, Alloc>& hm2)
-{
-  return hm1.rep == hm2.rep;
-}
 
 #endif /* __SGI_STL_HASH_MAP_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/hash_set b/libstdc++/stl/hash_set
new file mode 100644 (file)
index 0000000..2244f47
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef __SGI_STL_HASH_SET
+#define __SGI_STL_HASH_SET
+
+#ifndef __SGI_STL_INTERNAL_HASHTABLE_H
+#include <stl_hashtable.h>
+#endif 
+
+#include <stl_hash_set.h>
+
+#endif /* __SGI_STL_HASH_SET */
+
+// Local Variables:
+// mode:C++
+// End:
index 2c7125e..c938ccc 100644 (file)
 #ifndef __SGI_STL_HASH_SET_H
 #define __SGI_STL_HASH_SET_H
 
-#ifndef __SGI_STL_HASHTABLE_H
-#include <hashtable.h>
-#endif /* __SGI_STL_HASHTABLE_H */
-
-#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
-template <class Value, class HashFcn = hash<Value>,
-          class EqualKey = equal_to<Value>,
-          class Alloc = alloc>
-#else
-template <class Value, class HashFcn, class EqualKey, class Alloc = alloc>
-#endif
-class hash_set
-{
-private:
-  typedef hashtable<Value, Value, HashFcn, identity<Value>, 
-                    EqualKey, Alloc> ht;
-  ht rep;
-
-public:
-  typedef ht::key_type key_type;
-  typedef ht::value_type value_type;
-  typedef ht::hasher hasher;
-  typedef ht::key_equal key_equal;
-
-  typedef ht::size_type size_type;
-  typedef ht::difference_type difference_type;
-  typedef ht::const_pointer pointer;
-  typedef ht::const_pointer const_pointer;
-  typedef ht::const_reference reference;
-  typedef ht::const_reference const_reference;
-
-  typedef ht::const_iterator iterator;
-  typedef ht::const_iterator const_iterator;
-
-  hasher hash_funct() const { return rep.hash_funct(); }
-  key_equal key_eq() const { return rep.key_eq(); }
-
-public:
-  hash_set() : rep(100, hasher(), key_equal()) {}
-  explicit hash_set(size_type n) : rep(n, hasher(), key_equal()) {}
-  hash_set(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
-  hash_set(size_type n, const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) {}
-
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  hash_set(InputIterator f, InputIterator l)
-    : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
-  template <class InputIterator>
-  hash_set(InputIterator f, InputIterator l, size_type n)
-    : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
-  template <class InputIterator>
-  hash_set(InputIterator f, InputIterator l, size_type n,
-           const hasher& hf)
-    : rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
-  template <class InputIterator>
-  hash_set(InputIterator f, InputIterator l, size_type n,
-           const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) { rep.insert_unique(f, l); }
-#else
-
-  hash_set(const value_type* f, const value_type* l)
-    : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
-  hash_set(const value_type* f, const value_type* l, size_type n)
-    : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
-  hash_set(const value_type* f, const value_type* l, size_type n,
-           const hasher& hf)
-    : rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
-  hash_set(const value_type* f, const value_type* l, size_type n,
-           const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) { rep.insert_unique(f, l); }
-
-  hash_set(const_iterator f, const_iterator l)
-    : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
-  hash_set(const_iterator f, const_iterator l, size_type n)
-    : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
-  hash_set(const_iterator f, const_iterator l, size_type n,
-           const hasher& hf)
-    : rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
-  hash_set(const_iterator f, const_iterator l, size_type n,
-           const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) { rep.insert_unique(f, l); }
-#endif /*__STL_MEMBER_TEMPLATES */
-
-public:
-  size_type size() const { return rep.size(); }
-  size_type max_size() const { return rep.max_size(); }
-  bool empty() const { return rep.empty(); }
-  void swap(hash_set& hs) { rep.swap(hs.rep); }
-  friend bool operator==(const hash_set<Value,HashFcn,EqualKey,Alloc>&,
-                         const hash_set<Value,HashFcn,EqualKey,Alloc>&);
-
-  iterator begin() const { return rep.begin(); }
-  iterator end() const { return rep.end(); }
-
-public:
-  pair<iterator, bool> insert(const value_type& obj)
-    {
-      pair<ht::iterator, bool> p = rep.insert_unique(obj);
-      return pair<iterator, bool>(p.first, p.second);
-    }
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); }
-#else
-  void insert(const value_type* f, const value_type* l) {
-    rep.insert_unique(f,l);
-  }
-  void insert(const_iterator f, const_iterator l) {rep.insert_unique(f, l); }
-#endif /*__STL_MEMBER_TEMPLATES */
-  pair<iterator, bool> insert_noresize(const value_type& obj)
-    {
-      pair<ht::iterator, bool> p = rep.insert_unique_noresize(obj);
-      return pair<iterator, bool>(p.first, p.second);
-    }
-
-  iterator find(const key_type& key) const { return rep.find(key); }
-
-  size_type count(const key_type& key) const { return rep.count(key); }
-  
-  pair<iterator, iterator> equal_range(const key_type& key) const
-    { return rep.equal_range(key); }
-
-  size_type erase(const key_type& key) {return rep.erase(key); }
-  void erase(iterator it) { rep.erase(it); }
-  void erase(iterator f, iterator l) { rep.erase(f, l); }
-  void clear() { rep.clear(); }
-
-public:
-  void resize(size_type hint) { rep.resize(hint); }
-  size_type bucket_count() const { return rep.bucket_count(); }
-  size_type max_bucket_count() const { return rep.max_bucket_count(); }
-  size_type elems_in_bucket(size_type n) const
-    { return rep.elems_in_bucket(n); }
-};
-
-template <class Value, class HashFcn, class EqualKey, class Alloc>
-inline bool operator==(const hash_set<Value, HashFcn, EqualKey, Alloc>& hs1,
-                       const hash_set<Value, HashFcn, EqualKey, Alloc>& hs2)
-{
-  return hs1.rep == hs2.rep;
-}
-
-#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
-template <class Value, class HashFcn = hash<Value>,
-          class EqualKey = equal_to<Value>,
-          class Alloc = alloc>
-#else
-template <class Value, class HashFcn, class EqualKey, class Alloc = alloc>
-#endif
-class hash_multiset
-{
-private:
-  typedef hashtable<Value, Value, HashFcn, identity<Value>, 
-                    EqualKey, Alloc> ht;
-  ht rep;
-
-public:
-  typedef ht::key_type key_type;
-  typedef ht::value_type value_type;
-  typedef ht::hasher hasher;
-  typedef ht::key_equal key_equal;
-
-  typedef ht::size_type size_type;
-  typedef ht::difference_type difference_type;
-  typedef ht::const_pointer pointer;
-  typedef ht::const_pointer const_pointer;
-  typedef ht::const_reference reference;
-  typedef ht::const_reference const_reference;
-
-  typedef ht::const_iterator iterator;
-  typedef ht::const_iterator const_iterator;
-
-  hasher hash_funct() const { return rep.hash_funct(); }
-  key_equal key_eq() const { return rep.key_eq(); }
-
-public:
-  hash_multiset() : rep(100, hasher(), key_equal()) {}
-  explicit hash_multiset(size_type n) : rep(n, hasher(), key_equal()) {}
-  hash_multiset(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
-  hash_multiset(size_type n, const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) {}
-
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  hash_multiset(InputIterator f, InputIterator l)
-    : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
-  template <class InputIterator>
-  hash_multiset(InputIterator f, InputIterator l, size_type n)
-    : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
-  template <class InputIterator>
-  hash_multiset(InputIterator f, InputIterator l, size_type n,
-                const hasher& hf)
-    : rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
-  template <class InputIterator>
-  hash_multiset(InputIterator f, InputIterator l, size_type n,
-                const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) { rep.insert_equal(f, l); }
-#else
-
-  hash_multiset(const value_type* f, const value_type* l)
-    : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
-  hash_multiset(const value_type* f, const value_type* l, size_type n)
-    : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
-  hash_multiset(const value_type* f, const value_type* l, size_type n,
-                const hasher& hf)
-    : rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
-  hash_multiset(const value_type* f, const value_type* l, size_type n,
-                const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) { rep.insert_equal(f, l); }
-
-  hash_multiset(const_iterator f, const_iterator l)
-    : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
-  hash_multiset(const_iterator f, const_iterator l, size_type n)
-    : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
-  hash_multiset(const_iterator f, const_iterator l, size_type n,
-                const hasher& hf)
-    : rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
-  hash_multiset(const_iterator f, const_iterator l, size_type n,
-                const hasher& hf, const key_equal& eql)
-    : rep(n, hf, eql) { rep.insert_equal(f, l); }
-#endif /*__STL_MEMBER_TEMPLATES */
-
-public:
-  size_type size() const { return rep.size(); }
-  size_type max_size() const { return rep.max_size(); }
-  bool empty() const { return rep.empty(); }
-  void swap(hash_multiset& hs) { rep.swap(hs.rep); }
-  friend bool operator==(const hash_multiset<Value,HashFcn,EqualKey,Alloc>&,
-                         const hash_multiset<Value,HashFcn,EqualKey,Alloc>&);
-
-  iterator begin() const { return rep.begin(); }
-  iterator end() const { return rep.end(); }
-
-public:
-  iterator insert(const value_type& obj) { return rep.insert_equal(obj); }
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); }
-#else
-  void insert(const value_type* f, const value_type* l) {
-    rep.insert_equal(f,l);
-  }
-  void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); }
-#endif /*__STL_MEMBER_TEMPLATES */
-  iterator insert_noresize(const value_type& obj)
-    { return rep.insert_equal_noresize(obj); }    
-
-  iterator find(const key_type& key) const { return rep.find(key); }
-
-  size_type count(const key_type& key) const { return rep.count(key); }
-  
-  pair<iterator, iterator> equal_range(const key_type& key) const
-    { return rep.equal_range(key); }
-
-  size_type erase(const key_type& key) {return rep.erase(key); }
-  void erase(iterator it) { rep.erase(it); }
-  void erase(iterator f, iterator l) { rep.erase(f, l); }
-  void clear() { rep.clear(); }
-
-public:
-  void resize(size_type hint) { rep.resize(hint); }
-  size_type bucket_count() const { return rep.bucket_count(); }
-  size_type max_bucket_count() const { return rep.max_bucket_count(); }
-  size_type elems_in_bucket(size_type n) const
-    { return rep.elems_in_bucket(n); }
-};
-
-template <class Val, class HashFcn, class EqualKey, class Alloc>
-inline bool operator==(const hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs1,
-                       const hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs2)
-{
-  return hs1.rep == hs2.rep;
-}
-
+#ifndef __SGI_STL_INTERNAL_HASHTABLE_H
+#include <stl_hashtable.h>
+#endif 
+
+#include <stl_hash_set.h>
+
+#ifdef __STL_USE_NAMESPACES
+using __STD::hash;
+using __STD::hashtable;
+using __STD::hash_set;
+using __STD::hash_multiset;
+#endif /* __STL_USE_NAMESPACES */
 
 #endif /* __SGI_STL_HASH_SET_H */
index fb4abc2..15dbfc9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996
+ * Copyright (c) 1996,1997
  * Silicon Graphics Computer Systems, Inc.
  *
  * Permission to use, copy, modify, distribute and sell this software
  *
  */
 
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
 #ifndef __SGI_STL_HASHTABLE_H
 #define __SGI_STL_HASHTABLE_H
 
-// Hashtable class, used to implement the hashed associative containers
-// hash_set, hash_map, hash_multiset, and hash_multimap.
-
-
-#include <stdlib.h>
-#include <stddef.h>
+#include <stl_hashtable.h>
 #include <algo.h>
+#include <alloc.h>
 #include <vector.h>
 
-
-template <class Key> struct hash { };
-
-inline size_t __stl_hash_string(const char* s)
-{
-  unsigned long h = 0; 
-  for ( ; *s; ++s)
-    h = 5*h + *s;
-  
-  return size_t(h);
-}
-
-struct hash<char*>
-{
-  size_t operator()(const char* s) const { return __stl_hash_string(s); }
-};
-
-struct hash<const char*>
-{
-  size_t operator()(const char* s) const { return __stl_hash_string(s); }
-};
-
-struct hash<char> {
-  size_t operator()(char x) const { return x; }
-};
-struct hash<unsigned char> {
-  size_t operator()(unsigned char x) const { return x; }
-};
-struct hash<signed char> {
-  size_t operator()(unsigned char x) const { return x; }
-};
-struct hash<short> {
-  size_t operator()(short x) const { return x; }
-};
-struct hash<unsigned short> {
-  size_t operator()(unsigned short x) const { return x; }
-};
-struct hash<int> {
-  size_t operator()(int x) const { return x; }
-};
-struct hash<unsigned int> {
-  size_t operator()(unsigned int x) const { return x; }
-};
-struct hash<long> {
-  size_t operator()(long x) const { return x; }
-};
-struct hash<unsigned long> {
-  size_t operator()(unsigned long x) const { return x; }
-};
-
-template <class Value>
-struct __hashtable_node
-{
-  __hashtable_node* next;
-  Value val;
-};  
-
-template <class Value, class Key, class HashFcn,
-          class ExtractKey, class EqualKey, class Alloc = alloc>
-class hashtable;
-
-template <class Value, class Key, class HashFcn,
-          class ExtractKey, class EqualKey, class Alloc>
-struct __hashtable_iterator;
-
-template <class Value, class Key, class HashFcn,
-          class ExtractKey, class EqualKey, class Alloc>
-struct __hashtable_const_iterator;
-
-template <class Value, class Key, class HashFcn,
-          class ExtractKey, class EqualKey, class Alloc>
-struct __hashtable_iterator {
-  typedef hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>
-          hashtable;
-  typedef __hashtable_iterator<Value, Key, HashFcn, 
-                               ExtractKey, EqualKey, Alloc>
-          iterator;
-  typedef __hashtable_const_iterator<Value, Key, HashFcn, 
-                                     ExtractKey, EqualKey, Alloc>
-          const_iterator;
-  typedef __hashtable_node<Value> node;
-
-  typedef forward_iterator_tag iterator_category;
-  typedef Value value_type;
-  typedef ptrdiff_t difference_type;
-  typedef size_t size_type;
-  typedef Value& reference;
-  typedef Value* pointer;
-
-  node* cur;
-  hashtable* ht;
-
-  __hashtable_iterator(node* n, hashtable* tab) : cur(n), ht(tab) {}
-  __hashtable_iterator() {}
-  reference operator*() const { return cur->val; }
-#ifndef __SGI_STL_NO_ARROW_OPERATOR
-  pointer operator->() const { return &(operator*()); }
-#endif /* __SGI_STL_NO_ARROW_OPERATOR */
-  iterator& operator++();
-  iterator operator++(int);
-  bool operator==(const iterator& it) const { return cur == it.cur; }
-  bool operator!=(const iterator& it) const { return cur != it.cur; }
-};
-
-
-template <class Value, class Key, class HashFcn,
-          class ExtractKey, class EqualKey, class Alloc>
-struct __hashtable_const_iterator {
-  typedef hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>
-          hashtable;
-  typedef __hashtable_iterator<Value, Key, HashFcn, 
-                               ExtractKey, EqualKey, Alloc>
-          iterator;
-  typedef __hashtable_const_iterator<Value, Key, HashFcn, 
-                                     ExtractKey, EqualKey, Alloc>
-          const_iterator;
-  typedef __hashtable_node<Value> node;
-
-  typedef forward_iterator_tag iterator_category;
-  typedef Value value_type;
-  typedef ptrdiff_t difference_type;
-  typedef size_t size_type;
-  typedef const Value& reference;
-  typedef const Value* pointer;
-
-  const node* cur;
-  const hashtable* ht;
-
-  __hashtable_const_iterator(const node* n, const hashtable* tab)
-    : cur(n), ht(tab) {}
-  __hashtable_const_iterator() {}
-  __hashtable_const_iterator(const iterator& it) : cur(it.cur), ht(it.ht) {}
-  reference operator*() const { return cur->val; }
-#ifndef __SGI_STL_NO_ARROW_OPERATOR
-  pointer operator->() const { return &(operator*()); }
-#endif /* __SGI_STL_NO_ARROW_OPERATOR */
-  const_iterator& operator++();
-  const_iterator operator++(int);
-  bool operator==(const const_iterator& it) const { return cur == it.cur; }
-  bool operator!=(const const_iterator& it) const { return cur != it.cur; }
-};
-
-// Note: assumes long is at least 32 bits.
-static const int __stl_num_primes = 28;
-static const unsigned long __stl_prime_list[__stl_num_primes] =
-{
-  53,         97,         193,       389,       769,
-  1543,       3079,       6151,      12289,     24593,
-  49157,      98317,      196613,    393241,    786433,
-  1572869,    3145739,    6291469,   12582917,  25165843,
-  50331653,   100663319,  201326611, 402653189, 805306457, 
-  1610612741, 3221225473, 4294967291
-};
-
-inline unsigned long __stl_next_prime(unsigned long n)
-{
-  const unsigned long* first = __stl_prime_list;
-  const unsigned long* last = __stl_prime_list + __stl_num_primes;
-  const unsigned long* pos = lower_bound(first, last, n);
-  return pos == last ? *(last - 1) : *pos;
-}
-
-
-template <class Value, class Key, class HashFcn,
-          class ExtractKey, class EqualKey,
-          class Alloc>
-class hashtable {
-public:
-  typedef Key key_type;
-  typedef Value value_type;
-  typedef HashFcn hasher;
-  typedef EqualKey key_equal;
-
-  typedef size_t            size_type;
-  typedef ptrdiff_t         difference_type;
-  typedef value_type*       pointer;
-  typedef const value_type* const_pointer;
-  typedef value_type&       reference;
-  typedef const value_type& const_reference;
-
-  hasher hash_funct() const { return hash; }
-  key_equal key_eq() const { return equals; }
-
-private:
-  hasher hash;
-  key_equal equals;
-  ExtractKey get_key;
-
-  typedef __hashtable_node<Value> node;
-  typedef simple_alloc<node, Alloc> node_allocator;
-
-  vector<node*,Alloc> buckets;
-  size_type num_elements;
-
-public:
-  typedef __hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, 
-                               Alloc>
-  iterator;
-
-  typedef __hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey,
-                                     Alloc>
-  const_iterator;
-
-  friend struct
-  __hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>;
-  friend struct
-  __hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>;
-
-public:
-  hashtable(size_type n,
-            const HashFcn&    hf,
-            const EqualKey&   eql,
-            const ExtractKey& ext)
-    : hash(hf), equals(eql), get_key(ext), num_elements(0)
-  {
-    initialize_buckets(n);
-  }
-
-  hashtable(size_type n,
-            const HashFcn&    hf,
-            const EqualKey&   eql)
-    : hash(hf), equals(eql), get_key(ExtractKey()), num_elements(0)
-  {
-    initialize_buckets(n);
-  }
-
-  hashtable(const hashtable& ht)
-    : hash(ht.hash), equals(ht.equals), get_key(ht.get_key), num_elements(0)
-  {
-    copy_from(ht);
-  }
-
-  hashtable& operator= (const hashtable& ht)
-  {
-    if (&ht != this) {
-      clear();
-      hash = ht.hash;
-      equals = ht.equals;
-      get_key = ht.get_key;
-      copy_from(ht);
-    }
-    return *this;
-  }
-
-  ~hashtable() { clear(); }
-
-  size_type size() const { return num_elements; }
-  size_type max_size() const { return size_type(-1); }
-  bool empty() const { return size() == 0; }
-
-  void swap(hashtable& ht)
-  {
-    ::swap(hash, ht.hash);
-    ::swap(equals, ht.equals);
-    ::swap(get_key, ht.get_key);
-    buckets.swap(ht.buckets);
-    ::swap(num_elements, ht.num_elements);
-  }
-
-  iterator begin()
-  { 
-    for (size_type n = 0; n < buckets.size(); ++n)
-      if (buckets[n])
-        return iterator(buckets[n], this);
-    return end();
-  }
-
-  iterator end() { return iterator(0, this); }
-
-  const_iterator begin() const
-  {
-    for (size_type n = 0; n < buckets.size(); ++n)
-      if (buckets[n])
-        return const_iterator(buckets[n], this);
-    return end();
-  }
-
-  const_iterator end() const { return const_iterator(0, this); }
-
-  friend bool operator== (const hashtable<Value, Key,
-                                          HashFcn, ExtractKey, EqualKey,
-                                          Alloc>&,
-                          const hashtable<Value, Key,
-                                          HashFcn, ExtractKey, EqualKey,
-                                          Alloc>&);
-
-public:
-
-  size_type bucket_count() const { return buckets.size(); }
-
-  size_type max_bucket_count() const
-    { return __stl_prime_list[__stl_num_primes - 1]; } 
-
-  size_type elems_in_bucket(size_type bucket) const
-  {
-    size_type result = 0;
-    for (node* cur = buckets[bucket]; cur; cur = cur->next)
-      result += 1;
-    return result;
-  }
-
-  pair<iterator, bool> insert_unique(const value_type& obj)
-  {
-    resize(num_elements + 1);
-    return insert_unique_noresize(obj);
-  }
-
-  iterator insert_equal(const value_type& obj)
-  {
-    resize(num_elements + 1);
-    return insert_equal_noresize(obj);
-  }
-
-  pair<iterator, bool> insert_unique_noresize(const value_type& obj);
-  iterator insert_equal_noresize(const value_type& obj);
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  void insert_unique(InputIterator f, InputIterator l)
-  {
-    insert_unique(f, l, iterator_category(f));
-  }
-
-  template <class InputIterator>
-  void insert_equal(InputIterator f, InputIterator l)
-  {
-    insert_equal(f, l, iterator_category(f));
-  }
-
-  template <class InputIterator>
-  void insert_unique(InputIterator f, InputIterator l,
-                     input_iterator_tag)
-  {
-    for ( ; f != l; ++f)
-      insert_unique(*f);
-  }
-
-  template <class InputIterator>
-  void insert_equal(InputIterator f, InputIterator l,
-                    input_iterator_tag)
-  {
-    for ( ; f != l; ++f)
-      insert_equal(*f);
-  }
-
-  template <class ForwardIterator>
-  void insert_unique(ForwardIterator f, ForwardIterator l,
-                     forward_iterator_tag)
-  {
-    size_type n = 0;
-    distance(f, l, n);
-    resize(num_elements + n);
-    for ( ; n > 0; --n, ++f)
-      insert_unique_noresize(*f);
-  }
-
-  template <class ForwardIterator>
-  void insert_equal(ForwardIterator f, ForwardIterator l,
-                    forward_iterator_tag)
-  {
-    size_type n = 0;
-    distance(f, l, n);
-    resize(num_elements + n);
-    for ( ; n > 0; --n, ++f)
-      insert_equal_noresize(*f);
-  }
-
-#else /* __STL_MEMBER_TEMPLATES */
-  void insert_unique(const value_type* f, const value_type* l)
-  {
-    size_type n = l - f;
-    resize(num_elements + n);
-    for ( ; n > 0; --n, ++f)
-      insert_unique_noresize(*f);
-  }
-
-  void insert_equal(const value_type* f, const value_type* l)
-  {
-    size_type n = l - f;
-    resize(num_elements + n);
-    for ( ; n > 0; --n, ++f)
-      insert_equal_noresize(*f);
-  }
-
-  void insert_unique(const_iterator f, const_iterator l)
-  {
-    size_type n = 0;
-    distance(f, l, n);
-    resize(num_elements + n);
-    for ( ; n > 0; --n, ++f)
-      insert_unique_noresize(*f);
-  }
-
-  void insert_equal(const_iterator f, const_iterator l)
-  {
-    size_type n = 0;
-    distance(f, l, n);
-    resize(num_elements + n);
-    for ( ; n > 0; --n, ++f)
-      insert_equal_noresize(*f);
-  }
-#endif /*__STL_MEMBER_TEMPLATES */
-
-  reference find_or_insert(const value_type& obj);
-
-  iterator find(const key_type& key) 
-  {
-    size_type n = bkt_num_key(key);
-    node* first;
-    for ( first = buckets[n];
-          first && !equals(get_key(first->val), key);
-          first = first->next)
-      {}
-    return iterator(first, this);
-  } 
-
-  const_iterator find(const key_type& key) const
-  {
-    size_type n = bkt_num_key(key);
-    const node* first;
-    for ( first = buckets[n];
-          first && !equals(get_key(first->val), key);
-          first = first->next)
-      {}
-    return const_iterator(first, this);
-  } 
-
-  size_type count(const key_type& key) const
-  {
-    const size_type n = bkt_num_key(key);
-    size_type result = 0;
-
-    for (const node* cur = buckets[n]; cur; cur = cur->next)
-      if (equals(get_key(cur->val), key))
-        ++result;
-    return result;
-  }
-
-  pair<iterator, iterator> equal_range(const key_type& key);
-  pair<const_iterator, const_iterator> equal_range(const key_type& key) const;
-
-  size_type erase(const key_type& key);
-  void erase(const iterator& it);
-  void erase(iterator first, iterator last);
-
-  void erase(const const_iterator& it);
-  void erase(const_iterator first, const_iterator last);
-
-  void resize(size_type num_elements_hint);
-  void clear();
-
-private:
-  size_type next_size(size_type n) const { return __stl_next_prime(n); }
-
-  void initialize_buckets(size_type n)
-  {
-    const size_type n_buckets = next_size(n);
-    buckets.reserve(n_buckets);
-    buckets.insert(buckets.end(), n_buckets, (node*) 0);
-    num_elements = 0;
-  }
-
-  size_type bkt_num_key(const key_type& key) const
-  {
-    return bkt_num_key(key, buckets.size());
-  }
-
-  size_type bkt_num(const value_type& obj) const
-  {
-    return bkt_num_key(get_key(obj));
-  }
-
-  size_type bkt_num_key(const key_type& key, size_t n) const
-  {
-    return hash(key) % n;
-  }
-
-  size_type bkt_num(const value_type& obj, size_t n) const
-  {
-    return bkt_num_key(get_key(obj), n);
-  }
-
-  node* new_node(const value_type& obj)
-  {
-    node* n = node_allocator::allocate();
-    n->next = 0;
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      construct(&n->val, obj);
-      return n;
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      node_allocator::deallocate(n);
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */
-  }
-  
-  void delete_node(node* n)
-  {
-    destroy(&n->val);
-    node_allocator::deallocate(n);
-  }
-
-  void erase_bucket(const size_type n, node* first, node* last);
-  void erase_bucket(const size_type n, node* last);
-
-  void copy_from(const hashtable& ht);
-
-};
-
-template <class V, class K, class HF, class ExK, class EqK, class A>
-__hashtable_iterator<V, K, HF, ExK, EqK, A>&
-__hashtable_iterator<V, K, HF, ExK, EqK, A>::operator++()
-{
-  const node* old = cur;
-  cur = cur->next;
-  if (!cur) {
-    size_type bucket = ht->bkt_num(old->val);
-    while (!cur && ++bucket < ht->buckets.size())
-      cur = ht->buckets[bucket];
-  }
-  return *this;
-}
-
-template <class V, class K, class HF, class ExK, class EqK, class A>
-inline __hashtable_iterator<V, K, HF, ExK, EqK, A>
-__hashtable_iterator<V, K, HF, ExK, EqK, A>::operator++(int)
-{
-  iterator tmp = *this;
-  ++*this;
-  return tmp;
-}
-
-template <class V, class K, class HF, class ExK, class EqK, class A>
-__hashtable_const_iterator<V, K, HF, ExK, EqK, A>&
-__hashtable_const_iterator<V, K, HF, ExK, EqK, A>::operator++()
-{
-  const node* old = cur;
-  cur = cur->next;
-  if (!cur) {
-    size_type bucket = ht->bkt_num(old->val);
-    while (!cur && ++bucket < ht->buckets.size())
-      cur = ht->buckets[bucket];
-  }
-  return *this;
-}
-
-template <class V, class K, class HF, class ExK, class EqK, class A>
-inline __hashtable_const_iterator<V, K, HF, ExK, EqK, A>
-__hashtable_const_iterator<V, K, HF, ExK, EqK, A>::operator++(int)
-{
-  const_iterator tmp = *this;
-  ++*this;
-  return tmp;
-}
-
-#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-template <class V, class K, class HF, class ExK, class EqK, class All>
-inline forward_iterator_tag
-iterator_category(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&)
-{
-  return forward_iterator_tag();
-}
-
-template <class V, class K, class HF, class ExK, class EqK, class All>
-inline V* value_type(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&)
-{
-  return (V*) 0;
-}
-
-template <class V, class K, class HF, class ExK, class EqK, class All>
-inline hashtable<V, K, HF, ExK, EqK, All>::difference_type*
-distance_type(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&)
-{
-  return (hashtable<V, K, HF, ExK, EqK, All>::difference_type*) 0;
-}
-
-template <class V, class K, class HF, class ExK, class EqK, class All>
-inline forward_iterator_tag
-iterator_category(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&)
-{
-  return forward_iterator_tag();
-}
-
-template <class V, class K, class HF, class ExK, class EqK, class All>
-inline V* 
-value_type(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&)
-{
-  return (V*) 0;
-}
-
-template <class V, class K, class HF, class ExK, class EqK, class All>
-inline hashtable<V, K, HF, ExK, EqK, All>::difference_type*
-distance_type(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&)
-{
-  return (hashtable<V, K, HF, ExK, EqK, All>::difference_type*) 0;
-}
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-template <class V, class K, class HF, class Ex, class Eq, class A>
-bool operator==(const hashtable<V, K, HF, Ex, Eq, A>& ht1,
-                const hashtable<V, K, HF, Ex, Eq, A>& ht2)
-{
-  typedef hashtable<V, K, HF, Ex, Eq, A>::node node;
-  if (ht1.buckets.size() != ht2.buckets.size())
-    return false;
-  for (int n = 0; n < ht1.buckets.size(); ++n) {
-    node* cur1 = ht1.buckets[n];
-    node* cur2 = ht2.buckets[n];
-    for ( ; cur1 && cur2 && cur1->val == cur2->val;
-          cur1 = cur1->next, cur2 = cur2->next)
-      {}
-    if (cur1 || cur2)
-      return false;
-  }
-  return true;
-}  
-
-template <class V, class K, class HF, class Ex, class Eq, class A>
-pair<hashtable<V, K, HF, Ex, Eq, A>::iterator, bool> 
-hashtable<V, K, HF, Ex, Eq, A>::insert_unique_noresize(const value_type& obj)
-{
-  const size_type n = bkt_num(obj);
-  node* first = buckets[n];
-
-  for (node* cur = first; cur; cur = cur->next) 
-    if (equals(get_key(cur->val), get_key(obj)))
-      return pair<iterator, bool>(iterator(cur, this), false);
-
-  node* tmp = new_node(obj);
-  tmp->next = first;
-  buckets[n] = tmp;
-  ++num_elements;
-  return pair<iterator, bool>(iterator(tmp, this), true);
-}
-
-template <class V, class K, class HF, class Ex, class Eq, class A>
-hashtable<V, K, HF, Ex, Eq, A>::iterator 
-hashtable<V, K, HF, Ex, Eq, A>::insert_equal_noresize(const value_type& obj)
-{
-  const size_type n = bkt_num(obj);
-  node* first = buckets[n];
-
-  for (node* cur = first; cur; cur = cur->next) 
-    if (equals(get_key(cur->val), get_key(obj))) {
-      node* tmp = new_node(obj);
-      tmp->next = cur->next;
-      cur->next = tmp;
-      ++num_elements;
-      return iterator(tmp, this);
-    }
-
-  node* tmp = new_node(obj);
-  tmp->next = first;
-  buckets[n] = tmp;
-  ++num_elements;
-  return iterator(tmp, this);
-}
-
-template <class V, class K, class HF, class Ex, class Eq, class A>
-hashtable<V, K, HF, Ex, Eq, A>::reference 
-hashtable<V, K, HF, Ex, Eq, A>::find_or_insert(const value_type& obj)
-{
-  resize(num_elements + 1);
-
-  size_type n = bkt_num(obj);
-  node* first = buckets[n];
-
-  for (node* cur = first; cur; cur = cur->next)
-    if (equals(get_key(cur->val), get_key(obj)))
-      return cur->val;
-
-  node* tmp = new_node(obj);
-  tmp->next = first;
-  buckets[n] = tmp;
-  ++num_elements;
-  return tmp->val;
-}
-
-template <class V, class K, class HF, class Ex, class Eq, class A>
-pair<hashtable<V, K, HF, Ex, Eq, A>::iterator,
-     hashtable<V, K, HF, Ex, Eq, A>::iterator> 
-hashtable<V, K, HF, Ex, Eq, A>::equal_range(const key_type& key)
-{
-  typedef pair<iterator, iterator> pii;
-  const size_type n = bkt_num_key(key);
-
-  for (node* first = buckets[n]; first; first = first->next) {
-    if (equals(get_key(first->val), key)) {
-      for (node* cur = first->next; cur; cur = cur->next)
-        if (!equals(get_key(cur->val), key))
-          return pii(iterator(first, this), iterator(cur, this));
-      for (size_type m = n + 1; m < buckets.size(); ++m)
-        if (buckets[m])
-          return pii(iterator(first, this),
-                     iterator(buckets[m], this));
-      return pii(iterator(first, this), end());
-    }
-  }
-  return pii(end(), end());
-}
-
-template <class V, class K, class HF, class Ex, class Eq, class A>
-pair<hashtable<V, K, HF, Ex, Eq, A>::const_iterator, 
-     hashtable<V, K, HF, Ex, Eq, A>::const_iterator> 
-hashtable<V, K, HF, Ex, Eq, A>::equal_range(const key_type& key) const
-{
-  typedef pair<const_iterator, const_iterator> pii;
-  const size_type n = bkt_num_key(key);
-
-  for (const node* first = buckets[n] ; first; first = first->next) {
-    if (equals(get_key(first->val), key)) {
-      for (const node* cur = first->next; cur; cur = cur->next)
-        if (!equals(get_key(cur->val), key))
-          return pii(const_iterator(first, this),
-                     const_iterator(cur, this));
-      for (size_type m = n + 1; m < buckets.size(); ++m)
-        if (buckets[m])
-          return pii(const_iterator(first, this),
-                     const_iterator(buckets[m], this));
-      return pii(const_iterator(first, this), end());
-    }
-  }
-  return pii(end(), end());
-}
-
-template <class V, class K, class HF, class Ex, class Eq, class A>
-hashtable<V, K, HF, Ex, Eq, A>::size_type 
-hashtable<V, K, HF, Ex, Eq, A>::erase(const key_type& key)
-{
-  const size_type n = bkt_num_key(key);
-  node* first = buckets[n];
-  size_type erased = 0;
-
-  if (first) {
-    node* cur = first;
-    node* next = cur->next;
-    while (next) {
-      if (equals(get_key(next->val), key)) {
-        cur->next = next->next;
-        delete_node(next);
-        next = cur->next;
-        ++erased;
-        --num_elements;
-      }
-      else {
-        cur = next;
-        next = cur->next;
-      }
-    }
-    if (equals(get_key(first->val), key)) {
-      buckets[n] = first->next;
-      delete_node(first);
-      ++erased;
-      --num_elements;
-    }
-  }
-  return erased;
-}
-
-template <class V, class K, class HF, class Ex, class Eq, class A>
-void hashtable<V, K, HF, Ex, Eq, A>::erase(const iterator& it)
-{
-  if (node* const p = it.cur) {
-    const size_type n = bkt_num(p->val);
-    node* cur = buckets[n];
-
-    if (cur == p) {
-      buckets[n] = cur->next;
-      delete_node(cur);
-      --num_elements;
-    }
-    else {
-      node* next = cur->next;
-      while (next) {
-        if (next == p) {
-          cur->next = next->next;
-          delete_node(next);
-          --num_elements;
-          break;
-        }
-        else {
-          cur = next;
-          next = cur->next;
-        }
-      }
-    }
-  }
-}
-
-template <class V, class K, class HF, class Ex, class Eq, class A>
-void hashtable<V, K, HF, Ex, Eq, A>::erase(iterator first, iterator last)
-{
-  size_type f_bucket = first.cur ? bkt_num(first.cur->val) : buckets.size();
-  size_type l_bucket = last.cur ? bkt_num(last.cur->val) : buckets.size();
-
-  if (first.cur == last.cur)
-    return;
-  else if (f_bucket == l_bucket)
-    erase_bucket(f_bucket, first.cur, last.cur);
-  else {
-    erase_bucket(f_bucket, first.cur, 0);
-    for (size_type n = f_bucket + 1; n < l_bucket; ++n)
-      erase_bucket(n, 0);
-    if (l_bucket != buckets.size())
-      erase_bucket(l_bucket, last.cur);
-  }
-}
-
-template <class V, class K, class HF, class Ex, class Eq, class A>
-inline void
-hashtable<V, K, HF, Ex, Eq, A>::erase(const_iterator first,
-                                      const_iterator last)
-{
-  erase(iterator(const_cast<hashtable::node*>(first.cur),
-                 const_cast<hashtable*>(first.ht)),
-        iterator(const_cast<hashtable::node*>(last.cur),
-                 const_cast<hashtable*>(last.ht)));
-}
-
-template <class V, class K, class HF, class Ex, class Eq, class A>
-inline void
-hashtable<V, K, HF, Ex, Eq, A>::erase(const const_iterator& it)
-{
-  erase(iterator(const_cast<hashtable::node*>(it.cur),
-                 const_cast<hashtable*>(it.ht)));
-}
-
-template <class V, class K, class HF, class Ex, class Eq, class A>
-void hashtable<V, K, HF, Ex, Eq, A>::resize(size_type num_elements_hint)
-{
-  const size_type old_n = buckets.size();
-  if (num_elements_hint > old_n) {
-    const size_type n = next_size(num_elements_hint);
-    if (n > old_n) {
-      vector<node*, A> tmp(n, (node*) 0);
-#         ifdef __STL_USE_EXCEPTIONS
-      try {
-#         endif /* __STL_USE_EXCEPTIONS */
-        for (size_type bucket = 0; bucket < old_n; ++bucket) {
-          node* first = buckets[bucket];
-          while (first) {
-            size_type new_bucket = bkt_num(first->val, n);
-            buckets[bucket] = first->next;
-            first->next = tmp[new_bucket];
-            tmp[new_bucket] = first;
-            first = buckets[bucket];          
-          }
-        }
-        buckets.swap(tmp);
-#         ifdef __STL_USE_EXCEPTIONS
-      }
-      catch(...) {
-        for (size_type bucket = 0; bucket < tmp.size(); ++bucket) {
-          while (tmp[bucket]) {
-            node* next = tmp[bucket]->next;
-            delete_node(tmp[bucket]);
-            tmp[bucket] = next;
-          }
-        }
-        throw;
-      }
-#         endif /* __STL_USE_EXCEPTIONS */
-    }
-  }
-}
-
-template <class V, class K, class HF, class Ex, class Eq, class A>
-void hashtable<V, K, HF, Ex, Eq, A>::erase_bucket(const size_type n, 
-                                                  node* first, node* last)
-{
-  node* cur = buckets[n];
-  if (cur == first)
-    erase_bucket(n, last);
-  else {
-    node* next;
-    for (next = cur->next; next != first; cur = next, next = cur->next)
-      ;
-    while (next) {
-      cur->next = next->next;
-      delete_node(next);
-      next = cur->next;
-      --num_elements;
-    }
-  }
-}
-
-template <class V, class K, class HF, class Ex, class Eq, class A>
-void 
-hashtable<V, K, HF, Ex, Eq, A>::erase_bucket(const size_type n, node* last)
-{
-  node* cur = buckets[n];
-  while (cur != last) {
-    node* next = cur->next;
-    delete_node(cur);
-    cur = next;
-    buckets[n] = cur;
-    --num_elements;
-  }
-}
-
-template <class V, class K, class HF, class Ex, class Eq, class A>
-void hashtable<V, K, HF, Ex, Eq, A>::clear()
-{
-  for (size_type i = 0; i < buckets.size(); ++i) {
-    node* cur = buckets[i];
-    while (cur != 0) {
-      node* next = cur->next;
-      delete_node(cur);
-      cur = next;
-    }
-    buckets[i] = 0;
-  }
-  num_elements = 0;
-}
-
-    
-template <class V, class K, class HF, class Ex, class Eq, class A>
-void hashtable<V, K, HF, Ex, Eq, A>::copy_from(const hashtable& ht)
-{
-  buckets.clear();
-  buckets.reserve(ht.buckets.size());
-  buckets.insert(buckets.end(), ht.buckets.size(), (node*) 0);
-#   ifdef __STL_USE_EXCEPTIONS
-  try {
-#   endif /* __STL_USE_EXCEPTIONS */
-    for (size_type i = 0; i < ht.buckets.size(); ++i) {
-      if (const node* cur = ht.buckets[i]) {
-        node* copy = new_node(cur->val);
-        buckets[i] = copy;
-
-        for (node* next = cur->next; next; cur = next, next = cur->next) {
-          copy->next = new_node(next->val);
-          copy = copy->next;
-        }
-      }
-    }
-    num_elements = ht.num_elements;
-#   ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    clear();
-    throw;
-  }
-#   endif /* __STL_USE_EXCEPTIONS */
-}
-
+#ifdef __STL_USE_NAMESPACES
+using __STD::hash;
+using __STD::hashtable;
+#endif /* __STL_USE_NAMESPACES */
 
 #endif /* __SGI_STL_HASHTABLE_H */
+
+// Local Variables:
+// mode:C++
+// End:
index b24afaf..2ec93c0 100644 (file)
  * representations about the suitability of this software for any
  * purpose.  It is provided "as is" without express or implied warranty.
  *
+ * Copyright (c) 1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
  */
 
 #ifndef __SGI_STL_HEAP_H
 #define __SGI_STL_HEAP_H
 
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-#pragma set woff 1209
-#endif
-
-template <class RandomAccessIterator, class Distance, class T>
-void __push_heap(RandomAccessIterator first, Distance holeIndex,
-                Distance topIndex, T value) {
-    Distance parent = (holeIndex - 1) / 2;
-    while (holeIndex > topIndex && *(first + parent) < value) {
-       *(first + holeIndex) = *(first + parent);
-       holeIndex = parent;
-       parent = (holeIndex - 1) / 2;
-    }    
-    *(first + holeIndex) = value;
-}
-
-template <class RandomAccessIterator, class Distance, class T>
-inline void __push_heap_aux(RandomAccessIterator first,
-                           RandomAccessIterator last, Distance*, T*) {
-    __push_heap(first, Distance((last - first) - 1), Distance(0), 
-               T(*(last - 1)));
-}
-
-template <class RandomAccessIterator>
-inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) {
-    __push_heap_aux(first, last, distance_type(first), value_type(first));
-}
-
-template <class RandomAccessIterator, class Distance, class T, class Compare>
-void __push_heap(RandomAccessIterator first, Distance holeIndex,
-                Distance topIndex, T value, Compare comp) {
-    Distance parent = (holeIndex - 1) / 2;
-    while (holeIndex > topIndex && comp(*(first + parent), value)) {
-       *(first + holeIndex) = *(first + parent);
-       holeIndex = parent;
-       parent = (holeIndex - 1) / 2;
-    }
-    *(first + holeIndex) = value;
-}
-
-template <class RandomAccessIterator, class Compare, class Distance, class T>
-inline void __push_heap_aux(RandomAccessIterator first,
-                           RandomAccessIterator last, Compare comp,
-                           Distance*, T*) {
-    __push_heap(first, Distance((last - first) - 1), Distance(0), 
-               T(*(last - 1)), comp);
-}
-
-template <class RandomAccessIterator, class Compare>
-inline void push_heap(RandomAccessIterator first, RandomAccessIterator last,
-                     Compare comp) {
-    __push_heap_aux(first, last, comp, distance_type(first), value_type(first));
-}
+#include <stl_config.h>
+#include <stl_heap.h>
 
-template <class RandomAccessIterator, class Distance, class T>
-void __adjust_heap(RandomAccessIterator first, Distance holeIndex,
-                  Distance len, T value) {
-    Distance topIndex = holeIndex;
-    Distance secondChild = 2 * holeIndex + 2;
-    while (secondChild < len) {
-       if (*(first + secondChild) < *(first + (secondChild - 1)))
-           secondChild--;
-       *(first + holeIndex) = *(first + secondChild);
-       holeIndex = secondChild;
-       secondChild = 2 * (secondChild + 1);
-    }
-    if (secondChild == len) {
-       *(first + holeIndex) = *(first + (secondChild - 1));
-       holeIndex = secondChild - 1;
-    }
-    __push_heap(first, holeIndex, topIndex, value);
-}
+#ifdef __STL_USE_NAMESPACES
 
-template <class RandomAccessIterator, class T, class Distance>
-inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last,
-                      RandomAccessIterator result, T value, Distance*) {
-    *result = *first;
-    __adjust_heap(first, Distance(0), Distance(last - first), value);
-}
+using __STD::push_heap;
+using __STD::pop_heap;
+using __STD::make_heap;
+using __STD::sort_heap;
 
-template <class RandomAccessIterator, class T>
-inline void __pop_heap_aux(RandomAccessIterator first,
-                          RandomAccessIterator last, T*) {
-    __pop_heap(first, last - 1, last - 1, T(*(last - 1)), distance_type(first));
-}
+#endif /* __STL_USE_NAMESPACES */
 
-template <class RandomAccessIterator>
-inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last) {
-    __pop_heap_aux(first, last, value_type(first));
-}
-
-template <class RandomAccessIterator, class Distance, class T, class Compare>
-void __adjust_heap(RandomAccessIterator first, Distance holeIndex,
-                  Distance len, T value, Compare comp) {
-    Distance topIndex = holeIndex;
-    Distance secondChild = 2 * holeIndex + 2;
-    while (secondChild < len) {
-       if (comp(*(first + secondChild), *(first + (secondChild - 1))))
-           secondChild--;
-       *(first + holeIndex) = *(first + secondChild);
-       holeIndex = secondChild;
-       secondChild = 2 * (secondChild + 1);
-    }
-    if (secondChild == len) {
-       *(first + holeIndex) = *(first + (secondChild - 1));
-       holeIndex = secondChild - 1;
-    }
-    __push_heap(first, holeIndex, topIndex, value, comp);
-}
-
-template <class RandomAccessIterator, class T, class Compare, class Distance>
-inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last,
-                      RandomAccessIterator result, T value, Compare comp,
-                      Distance*) {
-    *result = *first;
-    __adjust_heap(first, Distance(0), Distance(last - first), value, comp);
-}
-
-template <class RandomAccessIterator, class T, class Compare>
-inline void __pop_heap_aux(RandomAccessIterator first,
-                          RandomAccessIterator last, T*, Compare comp) {
-    __pop_heap(first, last - 1, last - 1, T(*(last - 1)), comp,
-              distance_type(first));
-}
-
-template <class RandomAccessIterator, class Compare>
-inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last,
-                    Compare comp) {
-    __pop_heap_aux(first, last, value_type(first), comp);
-}
-
-template <class RandomAccessIterator, class T, class Distance>
-void __make_heap(RandomAccessIterator first, RandomAccessIterator last, T*,
-                Distance*) {
-    if (last - first < 2) return;
-    Distance len = last - first;
-    Distance parent = (len - 2)/2;
-    
-    while (true) {
-       __adjust_heap(first, parent, len, T(*(first + parent)));
-       if (parent == 0) return;
-       parent--;
-    }
-}
-
-template <class RandomAccessIterator>
-inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) {
-    __make_heap(first, last, value_type(first), distance_type(first));
-}
-
-template <class RandomAccessIterator, class Compare, class T, class Distance>
-void __make_heap(RandomAccessIterator first, RandomAccessIterator last,
-                Compare comp, T*, Distance*) {
-    if (last - first < 2) return;
-    Distance len = last - first;
-    Distance parent = (len - 2)/2;
-    
-    while (true) {
-       __adjust_heap(first, parent, len, T(*(first + parent)), comp);
-       if (parent == 0) return;
-       parent--;
-    }
-}
-
-template <class RandomAccessIterator, class Compare>
-inline void make_heap(RandomAccessIterator first, RandomAccessIterator last,
-                     Compare comp) {
-    __make_heap(first, last, comp, value_type(first), distance_type(first));
-}
-
-template <class RandomAccessIterator>
-void sort_heap(RandomAccessIterator first, RandomAccessIterator last) {
-    while (last - first > 1) pop_heap(first, last--);
-}
-
-template <class RandomAccessIterator, class Compare>
-void sort_heap(RandomAccessIterator first, RandomAccessIterator last,
-              Compare comp) {
-    while (last - first > 1) pop_heap(first, last--, comp);
-}
-
-#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
-#pragma reset woff 1209
-#endif
 
 #endif /* __SGI_STL_HEAP_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/iterator b/libstdc++/stl/iterator
new file mode 100644 (file)
index 0000000..90e6c9c
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __SGI_STL_ITERATOR
+#define __SGI_STL_ITERATOR
+
+#include <stl_config.h>
+#include <stl_relops.h>
+#include <stddef.h>
+#include <iostream.h>
+#include <stl_iterator.h>
+
+#endif /* __SGI_STL_ITERATOR */
+
+// Local Variables:
+// mode:C++
+// End:
index f8a19d0..f8a0237 100644 (file)
 #ifndef __SGI_STL_ITERATOR_H
 #define __SGI_STL_ITERATOR_H
 
+#ifndef __SGI_STL_FUNCTION_H
+#include <function.h>
+#endif
 #include <stddef.h>
 #include <iostream.h>
-#include <function.h>
-
-struct input_iterator_tag {};
-struct output_iterator_tag {};
-struct forward_iterator_tag : public input_iterator_tag {};
-struct bidirectional_iterator_tag : public forward_iterator_tag {};
-struct random_access_iterator_tag : public bidirectional_iterator_tag {};
-
-template <class T, class Distance> struct input_iterator {
-  typedef input_iterator_tag iterator_category;
-  typedef T                  value_type;
-  typedef Distance           difference_type;
-  typedef T*                 pointer;
-  typedef T&                 reference;
-};
-
-struct output_iterator {
-  typedef output_iterator_tag iterator_category;
-  typedef void                value_type;
-  typedef void                difference_type;
-  typedef void                pointer;
-  typedef void                reference;
-};
-
-template <class T, class Distance> struct forward_iterator {
-  typedef forward_iterator_tag iterator_category;
-  typedef T                    value_type;
-  typedef Distance             difference_type;
-  typedef T*                   pointer;
-  typedef T&                   reference;
-};
-
-
-template <class T, class Distance> struct bidirectional_iterator {
-  typedef bidirectional_iterator_tag iterator_category;
-  typedef T                          value_type;
-  typedef Distance                   difference_type;
-  typedef T*                         pointer;
-  typedef T&                         reference;
-};
-
-template <class T, class Distance> struct random_access_iterator {
-  typedef random_access_iterator_tag iterator_category;
-  typedef T                          value_type;
-  typedef Distance                   difference_type;
-  typedef T*                         pointer;
-  typedef T&                         reference;
-};
-
-#if 0
-template <class Category, class T, class Distance = ptrdiff_t,
-          class Pointer = T*, class Reference = T&>
-struct iterator {
-  typedef Category  iterator_category;
-  typedef T         value_type;
-  typedef Distance  difference_type;
-  typedef Pointer   pointer;
-  typedef Reference reference;
-};
+#ifndef __SGI_STL_INTERNAL_ITERATOR_H
+#include <stl_iterator.h>
 #endif
-
-#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-template <class Iterator>
-struct iterator_traits {
-  typedef typename Iterator::iterator_category iterator_category;
-  typedef typename Iterator::value_type        value_type;
-  typedef typename Iterator::difference_type   difference_type;
-  typedef typename Iterator::pointer           pointer;
-  typedef typename Iterator::reference         reference;
-};
-
-template <class T>
-struct iterator_traits<T*> {
-  typedef random_access_iterator_tag iterator_category;
-  typedef T                          value_type;
-  typedef ptrdiff_t                  difference_type;
-  typedef T*                         pointer;
-  typedef T&                         reference;
-};
-
-template <class T>
-struct iterator_traits<const T*> {
-  typedef random_access_iterator_tag iterator_category;
-  typedef T                          value_type;
-  typedef ptrdiff_t                  difference_type;
-  typedef const T*                   pointer;
-  typedef const T&                   reference;
-};
-
-template <class Iterator>
-inline iterator_traits<Iterator>::iterator_category
-iterator_category(const Iterator&) {
-  return iterator_traits<Iterator>::iterator_category();
-}
-
-template <class Iterator>
-inline iterator_traits<Iterator>::difference_type*
-distance_type(const Iterator&) {
-  return static_cast<iterator_traits<Iterator>::difference_type*>(0);
-}
-
-template <class Iterator>
-inline iterator_traits<Iterator>::value_type*
-value_type(const Iterator&) {
-  return static_cast<iterator_traits<Iterator>::value_type*>(0);
-}
-
-#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-template <class T, class Distance> 
-inline input_iterator_tag 
-iterator_category(const input_iterator<T, Distance>&) {
-    return input_iterator_tag();
-}
-
-inline output_iterator_tag iterator_category(const output_iterator&) {
-    return output_iterator_tag();
-}
-
-template <class T, class Distance> 
-inline forward_iterator_tag
-iterator_category(const forward_iterator<T, Distance>&) {
-    return forward_iterator_tag();
-}
-
-template <class T, class Distance> 
-inline bidirectional_iterator_tag
-iterator_category(const bidirectional_iterator<T, Distance>&) {
-    return bidirectional_iterator_tag();
-}
-
-template <class T, class Distance> 
-inline random_access_iterator_tag
-iterator_category(const random_access_iterator<T, Distance>&) {
-    return random_access_iterator_tag();
-}
-
-template <class T>
-inline random_access_iterator_tag iterator_category(const T*) {
-    return random_access_iterator_tag();
-}
-
-template <class T, class Distance> 
-inline T* value_type(const input_iterator<T, Distance>&) {
-    return (T*)(0); 
-}
-
-template <class T, class Distance> 
-inline T* value_type(const forward_iterator<T, Distance>&) {
-    return (T*)(0);
-}
-
-template <class T, class Distance> 
-inline T* value_type(const bidirectional_iterator<T, Distance>&) {
-    return (T*)(0);
-}
-
-template <class T, class Distance> 
-inline T* value_type(const random_access_iterator<T, Distance>&) {
-    return (T*)(0);
-}
-
-template <class T>
-inline T* value_type(const T*) { return (T*)(0); }
-
-template <class T, class Distance> 
-inline Distance* distance_type(const input_iterator<T, Distance>&) {
-    return (Distance*)(0);
-}
-
-template <class T, class Distance> 
-inline Distance* distance_type(const forward_iterator<T, Distance>&) {
-    return (Distance*)(0);
-}
-
-template <class T, class Distance> 
-inline Distance* 
-distance_type(const bidirectional_iterator<T, Distance>&) {
-    return (Distance*)(0);
-}
-
-template <class T, class Distance> 
-inline Distance* 
-distance_type(const random_access_iterator<T, Distance>&) {
-    return (Distance*)(0);
-}
-
-template <class T>
-inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); }
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-template <class Container>
-class back_insert_iterator {
-protected:
-    Container* container;
-public:
-    typedef output_iterator_tag iterator_category;
-    typedef void                value_type;
-    typedef void                difference_type;
-    typedef void                pointer;
-    typedef void                reference;
-
-    explicit back_insert_iterator(Container& x) : container(&x) {}
-    back_insert_iterator<Container>&
-    operator=(const typename Container::value_type& value) { 
-        container->push_back(value);
-        return *this;
-    }
-    back_insert_iterator<Container>& operator*() { return *this; }
-    back_insert_iterator<Container>& operator++() { return *this; }
-    back_insert_iterator<Container>& operator++(int) { return *this; }
-};
-
-#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-template <class Container>
-inline output_iterator_tag
-iterator_category(const back_insert_iterator<Container>&)
-{
-  return output_iterator_tag();
-}
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-template <class Container>
-inline back_insert_iterator<Container> back_inserter(Container& x) {
-  return back_insert_iterator<Container>(x);
-}
-
-template <class Container>
-class front_insert_iterator {
-protected:
-    Container* container;
-public:
-    typedef output_iterator_tag iterator_category;
-    typedef void                value_type;
-    typedef void                difference_type;
-    typedef void                pointer;
-    typedef void                reference;
-
-    explicit front_insert_iterator(Container& x) : container(&x) {}
-    front_insert_iterator<Container>&
-    operator=(const typename Container::value_type& value) { 
-        container->push_front(value);
-        return *this;
-    }
-    front_insert_iterator<Container>& operator*() { return *this; }
-    front_insert_iterator<Container>& operator++() { return *this; }
-    front_insert_iterator<Container>& operator++(int) { return *this; }
-};
-
-#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-template <class Container>
-inline output_iterator_tag
-iterator_category(const front_insert_iterator<Container>&)
-{
-  return output_iterator_tag();
-}
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-template <class Container>
-inline front_insert_iterator<Container> front_inserter(Container& x) {
-  return front_insert_iterator<Container>(x);
-}
-
-template <class Container>
-class insert_iterator {
-protected:
-    Container* container;
-    typename Container::iterator iter;
-public:
-    typedef output_iterator_tag iterator_category;
-    typedef void                value_type;
-    typedef void                difference_type;
-    typedef void                pointer;
-    typedef void                reference;
-
-    insert_iterator(Container& x, typename Container::iterator i) 
-        : container(&x), iter(i) {}
-    insert_iterator<Container>&
-    operator=(const typename Container::value_type& value) { 
-        iter = container->insert(iter, value);
-        ++iter;
-        return *this;
-    }
-    insert_iterator<Container>& operator*() { return *this; }
-    insert_iterator<Container>& operator++() { return *this; }
-    insert_iterator<Container>& operator++(int) { return *this; }
-};
-
-#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-template <class Container>
-inline output_iterator_tag
-iterator_category(const insert_iterator<Container>&)
-{
-  return output_iterator_tag();
-}
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-template <class Container, class Iterator>
-inline insert_iterator<Container> inserter(Container& x, Iterator i) {
-  typedef typename Container::iterator iter;
-  return insert_iterator<Container>(x, iter(i));
-}
-
-#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
-template <class BidirectionalIterator, class T, class Reference = T&, 
-          class Distance = ptrdiff_t> 
-#else
-template <class BidirectionalIterator, class T, class Reference, 
-          class Distance> 
+#ifndef __TYPE_TRAITS_H
+#include <type_traits.h>
+#endif
+#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H
+#include <stl_construct.h>
+#endif
+#ifndef __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H
+#include <stl_raw_storage_iter.h>
 #endif
-class reverse_bidirectional_iterator {
-    typedef reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
-                                           Distance> self;
-    friend bool operator==(const self& x, const self& y);
-protected:
-    BidirectionalIterator current;
-public:
-    typedef bidirectional_iterator_tag iterator_category;
-    typedef T                          value_type;
-    typedef Distance                   difference_type;
-    typedef T*                         pointer;
-    typedef Reference                  reference;
-
-    reverse_bidirectional_iterator() {}
-    explicit reverse_bidirectional_iterator(BidirectionalIterator x)
-      : current(x) {}
-    BidirectionalIterator base() { return current; }
-    Reference operator*() const {
-        BidirectionalIterator tmp = current;
-        return *--tmp;
-    }
-#ifndef __SGI_STL_NO_ARROW_OPERATOR
-    pointer operator->() const { return &(operator*()); }
-#endif /* __SGI_STL_NO_ARROW_OPERATOR */
-    self& operator++() {
-        --current;
-        return *this;
-    }
-    self operator++(int) {
-        self tmp = *this;
-        --current;
-        return tmp;
-    }
-    self& operator--() {
-        ++current;
-        return *this;
-    }
-    self operator--(int) {
-        self tmp = *this;
-        ++current;
-        return tmp;
-    }
-};
-
-#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-template <class BidirectionalIterator, class T, class Reference, 
-          class Distance>
-inline bidirectional_iterator_tag
-iterator_category(const reverse_bidirectional_iterator<BidirectionalIterator,
-                                                       T,
-                                                       Reference, Distance>&) {
-  return bidirectional_iterator_tag();
-}
 
-template <class BidirectionalIterator, class T, class Reference, 
-          class Distance>
-inline T*
-value_type(const reverse_bidirectional_iterator<BidirectionalIterator, T,
-                                               Reference, Distance>&) {
-  return (T*) 0;
-}
+#ifdef __STL_USE_NAMESPACES
 
-template <class BidirectionalIterator, class T, class Reference, 
-          class Distance>
-inline Distance*
-distance_type(const reverse_bidirectional_iterator<BidirectionalIterator, T,
-                                                  Reference, Distance>&) {
-  return (Distance*) 0;
-}
+// Names from stl_iterator.h
 
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+using __STD::input_iterator_tag;
+using __STD::output_iterator_tag;
+using __STD::forward_iterator_tag;
+using __STD::bidirectional_iterator_tag;
+using __STD::random_access_iterator_tag;
 
-template <class BidirectionalIterator, class T, class Reference,
-          class Distance>
-inline bool operator==(
-    const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
-                                         Distance>& x, 
-    const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
-                                         Distance>& y) {
-    return x.current == y.current;
-}
+#if 0
+using __STD::iterator;
+#endif
+using __STD::input_iterator;
+using __STD::output_iterator;
+using __STD::forward_iterator;
+using __STD::bidirectional_iterator;
+using __STD::random_access_iterator;
 
 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-// This is the new version of reverse_iterator, as defined in the
-//  draft C++ standard.  It relies on the iterator_traits template,
-//  which in turn relies on partial specialization.  The class
-//  reverse_bidirectional_iterator is no longer part of the draft
-//  standard, but it is retained for backward compatibility.
-
-template <class Iterator>
-class reverse_iterator : public iterator_traits<Iterator>
-{
-protected:
-  Iterator current;
-public:
-  typedef Iterator iterator_type;
-  typedef reverse_iterator<Iterator> self;
-
-public:
-  reverse_iterator() {}
-  explicit reverse_iterator(iterator_type x) : current(x) {}
-
-  reverse_iterator(const self& x) : current(x.current) {}
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class Iter>
-  reverse_iterator(const reverse_iterator<Iter>& x) : current(x.current) {}
-#endif /* __STL_MEMBER_TEMPLATES */
-    
-  iterator_type base() const { return current; }
-  reference operator*() const {
-    Iterator tmp = current;
-    return *--tmp;
-  }
-#ifndef __SGI_STL_NO_ARROW_OPERATOR
-  pointer operator->() const { return &(operator*()); }
-#endif /* __SGI_STL_NO_ARROW_OPERATOR */
-
-  self& operator++() {
-    --current;
-    return *this;
-  }
-  self operator++(int) {
-    self tmp = *this;
-    --current;
-    return tmp;
-  }
-  self& operator--() {
-    ++current;
-    return *this;
-  }
-  self operator--(int) {
-    self tmp = *this;
-    ++current;
-    return tmp;
-  }
-
-  self operator+(difference_type n) const {
-    return self(current - n);
-  }
-  self& operator+=(difference_type n) {
-    current -= n;
-    return *this;
-  }
-  self operator-(difference_type n) const {
-    return self(current + n);
-  }
-  self& operator-=(difference_type n) {
-    current += n;
-    return *this;
-  }
-  reference operator[](difference_type n) { return *(*this + n); }  
-}; 
-template <class Iterator>
-inline bool operator==(const reverse_iterator<Iterator>& x, 
-                       const reverse_iterator<Iterator>& y) {
-  return x.base() == y.base();
-}
-
-template <class Iterator>
-inline bool operator<(const reverse_iterator<Iterator>& x, 
-                      const reverse_iterator<Iterator>& y) {
-  return y.base() < x.base();
-}
-
-template <class Iterator>
-inline reverse_iterator<Iterator>::difference_type
-operator-(const reverse_iterator<Iterator>& x, 
-          const reverse_iterator<Iterator>& y) {
-  return y.base() - x.base();
-}
-
-template <class Iterator>
-inline reverse_iterator<Iterator> 
-operator+(reverse_iterator<Iterator>::difference_type n,
-          const reverse_iterator<Iterator>& x) {
-  return reverse_iterator<Iterator>(x.base() - n);
-}
-
-#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-// This is the old version of reverse_iterator, as found in the original
-//  HP STL.  It does not use partial specialization.
-
-#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
-template <class RandomAccessIterator, class T, class Reference = T&,
-          class Distance = ptrdiff_t> 
-#else
-template <class RandomAccessIterator, class T, class Reference,
-          class Distance> 
+using __STD::iterator_traits;
 #endif
-class reverse_iterator {
-    typedef reverse_iterator<RandomAccessIterator, T, Reference, Distance>
-        self;
-    friend bool operator==(const self& x, const self& y);
-    friend bool operator<(const self& x, const self& y);
-    friend Distance operator-(const self& x, const self& y);
-    friend self operator+(Distance n, const self& x);
-protected:
-    RandomAccessIterator current;
-public:
-    typedef random_access_iterator_tag iterator_category;
-    typedef T                          value_type;
-    typedef Distance                   difference_type;
-    typedef T*                         pointer;
-    typedef Reference                  reference;
-
-    reverse_iterator() {}
-    explicit reverse_iterator(RandomAccessIterator x) : current(x) {}
-    RandomAccessIterator base() { return current; }
-    Reference operator*() const { return *(current - 1); }
-#ifndef __SGI_STL_NO_ARROW_OPERATOR
-    pointer operator->() const { return &(operator*()); }
-#endif /* __SGI_STL_NO_ARROW_OPERATOR */
-    self& operator++() {
-        --current;
-        return *this;
-    }
-    self operator++(int) {
-        self tmp = *this;
-        --current;
-        return tmp;
-    }
-    self& operator--() {
-        ++current;
-        return *this;
-    }
-    self operator--(int) {
-        self tmp = *this;
-        ++current;
-        return tmp;
-    }
-    self operator+(Distance n) const {
-        return self(current - n);
-    }
-    self& operator+=(Distance n) {
-        current -= n;
-        return *this;
-    }
-    self operator-(Distance n) const {
-        return self(current + n);
-    }
-    self& operator-=(Distance n) {
-        current += n;
-        return *this;
-    }
-    Reference operator[](Distance n) { return *(*this + n); }
-};
-
-template <class RandomAccessIterator, class T, class Reference, class Distance>
-inline random_access_iterator_tag
-iterator_category(const reverse_iterator<RandomAccessIterator, T,
-                                         Reference, Distance>&) {
-  return random_access_iterator_tag();
-}
-
-template <class RandomAccessIterator, class T, class Reference, class Distance>
-inline T* value_type(const reverse_iterator<RandomAccessIterator, T,
-                                            Reference, Distance>&) {
-  return (T*) 0;
-}
-
-template <class RandomAccessIterator, class T, class Reference, class Distance>
-inline Distance* distance_type(const reverse_iterator<RandomAccessIterator, T,
-                                                      Reference, Distance>&) {
-  return (Distance*) 0;
-}
-
-
-template <class RandomAccessIterator, class T, class Reference, class Distance>
-inline bool operator==(const reverse_iterator<RandomAccessIterator, T,
-                                              Reference, Distance>& x, 
-                       const reverse_iterator<RandomAccessIterator, T,
-                                              Reference, Distance>& y) {
-    return x.current == y.current;
-}
-
-template <class RandomAccessIterator, class T, class Reference, class Distance>
-inline bool operator<(const reverse_iterator<RandomAccessIterator, T,
-                                             Reference, Distance>& x, 
-                      const reverse_iterator<RandomAccessIterator, T,
-                                             Reference, Distance>& y) {
-    return y.current < x.current;
-}
-
-template <class RandomAccessIterator, class T, class Reference, class Distance>
-inline Distance operator-(const reverse_iterator<RandomAccessIterator, T,
-                                                 Reference, Distance>& x, 
-                          const reverse_iterator<RandomAccessIterator, T,
-                                                 Reference, Distance>& y) {
-    return y.current - x.current;
-}
-
-template <class RandomAccessIterator, class T, class Reference, class Distance>
-inline reverse_iterator<RandomAccessIterator, T, Reference, Distance> 
-operator+(Distance n,
-          const reverse_iterator<RandomAccessIterator, T, Reference,
-                                 Distance>& x) {
-    return reverse_iterator<RandomAccessIterator, T, Reference, Distance>
-        (x.current - n);
-}
 
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+using __STD::iterator_category;
+using __STD::distance_type;
+using __STD::value_type;
 
-template <class ForwardIterator, class T>
-class raw_storage_iterator {
-protected:
-    ForwardIterator iter;
-public:
-    typedef output_iterator_tag iterator_category;
-    typedef void                value_type;
-    typedef void                difference_type;
-    typedef void                pointer;
-    typedef void                reference;
+using __STD::distance; 
+using __STD::advance; 
 
-    explicit raw_storage_iterator(ForwardIterator x) : iter(x) {}
-    raw_storage_iterator<ForwardIterator, T>& operator*() { return *this; }
-    raw_storage_iterator<ForwardIterator, T>& operator=(const T& element) {
-        construct(&*iter, element);
-        return *this;
-    }        
-    raw_storage_iterator<ForwardIterator, T>& operator++() {
-        ++iter;
-        return *this;
-    }
-    raw_storage_iterator<ForwardIterator, T> operator++(int) {
-        raw_storage_iterator<ForwardIterator, T> tmp = *this;
-        ++iter;
-        return tmp;
-    }
-};
+using __STD::insert_iterator;
+using __STD::front_insert_iterator;
+using __STD::back_insert_iterator;
+using __STD::inserter;
+using __STD::front_inserter;
+using __STD::back_inserter;
 
-#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
+using __STD::reverse_iterator;
+using __STD::reverse_bidirectional_iterator;
 
-template <class ForwardIterator, class T>
-inline output_iterator_tag
-iterator_category(const raw_storage_iterator<ForwardIterator, T>&)
-{
-  return output_iterator_tag();
-}
+using __STD::istream_iterator;
+using __STD::ostream_iterator;
 
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+// Names from stl_construct.h
+using __STD::construct;
+using __STD::destroy;
 
-template <class T, class Distance = ptrdiff_t> 
-class istream_iterator {
-friend bool operator==(const istream_iterator<T, Distance>& x,
-                       const istream_iterator<T, Distance>& y);
-protected:
-    istream* stream;
-    T value;
-    bool end_marker;
-    void read() {
-        end_marker = (*stream) ? true : false;
-        if (end_marker) *stream >> value;
-        end_marker = (*stream) ? true : false;
-    }
-public:
-    typedef input_iterator_tag iterator_category;
-    typedef T                  value_type;
-    typedef Distance           difference_type;
-    typedef const T*           pointer;
-    typedef const T&           reference;
+// Names from stl_raw_storage_iter.h
+using __STD::raw_storage_iterator;
 
-    istream_iterator() : stream(&cin), end_marker(false) {}
-    istream_iterator(istream& s) : stream(&s) { read(); }
-    reference operator*() const { return value; }
-#ifndef __SGI_STL_NO_ARROW_OPERATOR
-    pointer operator->() const { return &(operator*()); }
-#endif /* __SGI_STL_NO_ARROW_OPERATOR */
-    istream_iterator<T, Distance>& operator++() { 
-        read(); 
-        return *this;
-    }
-    istream_iterator<T, Distance> operator++(int)  {
-        istream_iterator<T, Distance> tmp = *this;
-        read();
-        return tmp;
-    }
-};
-
-#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-template <class T, class Distance>
-inline input_iterator_tag 
-iterator_category(const istream_iterator<T, Distance>&) {
-  return input_iterator_tag();
-}
-
-template <class T, class Distance>
-inline T* value_type(const istream_iterator<T, Distance>&) { return (T*) 0; }
-
-template <class T, class Distance>
-inline Distance* distance_type(const istream_iterator<T, Distance>&) {
-  return (Distance*) 0;
-}
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-template <class T, class Distance>
-bool operator==(const istream_iterator<T, Distance>& x,
-                const istream_iterator<T, Distance>& y) {
-    return x.stream == y.stream && x.end_marker == y.end_marker ||
-        x.end_marker == false && y.end_marker == false;
-}
-
-template <class T>
-class ostream_iterator {
-protected:
-    ostream* stream;
-    const char* string;
-public:
-    typedef output_iterator_tag iterator_category;
-    typedef void                value_type;
-    typedef void                difference_type;
-    typedef void                pointer;
-    typedef void                reference;
-
-    ostream_iterator(ostream& s) : stream(&s), string(0) {}
-    ostream_iterator(ostream& s, const char* c) : stream(&s), string(c)  {}
-    ostream_iterator<T>& operator=(const T& value) { 
-        *stream << value;
-        if (string) *stream << string;
-        return *this;
-    }
-    ostream_iterator<T>& operator*() { return *this; }
-    ostream_iterator<T>& operator++() { return *this; } 
-    ostream_iterator<T>& operator++(int) { return *this; } 
-};
-
-#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-template <class T>
-inline output_iterator_tag 
-iterator_category(const ostream_iterator<T>&) {
-  return output_iterator_tag();
-}
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+#endif /* __STL_USE_NAMESPACES */
 
 #endif /* __SGI_STL_ITERATOR_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/list b/libstdc++/stl/list
new file mode 100644 (file)
index 0000000..5294f39
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __SGI_STL_LIST
+#define __SGI_STL_LIST
+
+#include <stl_algobase.h>
+#include <stl_alloc.h>
+#include <stl_construct.h>
+#include <stl_uninitialized.h>
+#include <stl_list.h>
+
+#endif /* __SGI_STL_LIST */
+
+// Local Variables:
+// mode:C++
+// End:
index 6d94928..4e6ee0b 100644 (file)
@@ -12,7 +12,7 @@
  * purpose.  It is provided "as is" without express or implied warranty.
  *
  *
- * Copyright (c) 1996
+ * Copyright (c) 1996,1997
  * Silicon Graphics Computer Systems, Inc.
  *
  * Permission to use, copy, modify, distribute and sell this software
 #ifndef __SGI_STL_LIST_H
 #define __SGI_STL_LIST_H
 
-#include <stddef.h>
 #include <algobase.h>
-#include <iterator.h>
 #include <alloc.h>
+#include <stl_list.h>
 
-template <class T>
-struct __list_node {
-  typedef void* void_pointer;
-  void_pointer next;
-  void_pointer prev;
-  T data;
-};
-
-template<class T, class Ref, class Ptr>
-struct __list_iterator {
-  typedef __list_iterator<T, T&, T*>             iterator;
-  typedef __list_iterator<T, const T&, const T*> const_iterator;
-  typedef __list_iterator<T, Ref, Ptr>           self;
-
-  typedef bidirectional_iterator_tag iterator_category;
-  typedef T value_type;
-  typedef Ptr pointer;
-  typedef Ref reference;
-  typedef __list_node<T>* link_type;
-  typedef size_t size_type;
-  typedef ptrdiff_t difference_type;
-
-  link_type node;
-
-  __list_iterator(link_type x) : node(x) {}
-  __list_iterator() {}
-  __list_iterator(const iterator& x) : node(x.node) {}
-
-  bool operator==(const self& x) const { return node == x.node; }
-  bool operator!=(const self& x) const { return node != x.node; }
-  reference operator*() const { return (*node).data; }
-
-#ifndef __SGI_STL_NO_ARROW_OPERATOR
-  pointer operator->() const { return &(operator*()); }
-#endif /* __SGI_STL_NO_ARROW_OPERATOR */
-
-  self& operator++() { 
-    node = (link_type)((*node).next);
-    return *this;
-  }
-  self operator++(int) { 
-    self tmp = *this;
-    ++*this;
-    return tmp;
-  }
-  self& operator--() { 
-    node = (link_type)((*node).prev);
-    return *this;
-  }
-  self operator--(int) { 
-    self tmp = *this;
-    --*this;
-    return tmp;
-  }
-};
-
-#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-template <class T, class Ref, class Ptr>
-inline bidirectional_iterator_tag
-iterator_category(const __list_iterator<T, Ref, Ptr>&) {
-  return bidirectional_iterator_tag();
-}
-
-template <class T, class Ref, class Ptr>
-inline T*
-value_type(const __list_iterator<T, Ref, Ptr>&) {
-  return 0;
-}
-
-template <class T, class Ref, class Ptr>
-inline ptrdiff_t*
-distance_type(const __list_iterator<T, Ref, Ptr>&) {
-  return 0;
-}
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-template <class T, class Alloc = alloc>
-class list {
-protected:
-    typedef void* void_pointer;
-    typedef __list_node<T> list_node;
-    typedef simple_alloc<list_node, Alloc> list_node_allocator;
-public:      
-    typedef T value_type;
-    typedef value_type* pointer;
-    typedef value_type& reference;
-    typedef const value_type& const_reference;
-    typedef list_node* link_type;
-    typedef size_t size_type;
-    typedef ptrdiff_t difference_type;
-
-public:
-    typedef __list_iterator<T, T&, T*>             iterator;
-    typedef __list_iterator<T, const T&, const T*> const_iterator;
-
-#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
-    typedef reverse_iterator<const_iterator> const_reverse_iterator;
-    typedef reverse_iterator<iterator> reverse_iterator;
-#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-    typedef reverse_bidirectional_iterator<const_iterator, value_type,
-                                           const_reference, difference_type>
-            const_reverse_iterator;
-    typedef reverse_bidirectional_iterator<iterator, value_type, reference,
-                                           difference_type>
-            reverse_iterator; 
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-protected:
-    link_type get_node() { return list_node_allocator::allocate(); }
-    void put_node(link_type p) { list_node_allocator::deallocate(p); }
-
-    link_type create_node(const T& x) {
-      link_type p = get_node();
-#         ifdef __STL_USE_EXCEPTIONS
-      try {
-#         endif /* __STL_USE_EXCEPTIONS */
-        construct(&p->data, x);
-        return p;
-#         ifdef __STL_USE_EXCEPTIONS
-      }
-      catch(...) {
-        put_node(p);
-        throw;
-      }
-#         endif /* __STL_USE_EXCEPTIONS */
-    }
-    void destroy_node(link_type p) {
-      destroy(&p->data);
-      put_node(p);
-    }
-
-protected:
-    void empty_initialize() { 
-      node = get_node();
-      node->next = node;
-      node->prev = node;
-    }
-
-    void fill_initialize(size_type n, const T& value) {
-      empty_initialize();
-#         ifdef __STL_USE_EXCEPTIONS
-      try {
-#         endif /* __STL_USE_EXCEPTIONS */
-        insert(begin(), n, value);
-#         ifdef __STL_USE_EXCEPTIONS
-      }
-      catch(...) {
-        clear();
-        put_node(node);
-        throw;
-      }
-#         endif /* __STL_USE_EXCEPTIONS */
-    }
-
-#ifdef __STL_MEMBER_TEMPLATES
-    template <class InputIterator>
-    void range_initialize(InputIterator first, InputIterator last) {
-      empty_initialize();
-#         ifdef __STL_USE_EXCEPTIONS
-      try {
-#         endif /* __STL_USE_EXCEPTIONS */
-        insert(begin(), first, last);
-#         ifdef __STL_USE_EXCEPTIONS
-      }
-      catch(...) {
-        clear();
-        put_node(node);
-        throw;
-      }
-#         endif /* __STL_USE_EXCEPTIONS */
-    }
-#else  /* __STL_MEMBER_TEMPLATES */
-    void range_initialize(const T* first, const T* last) {
-      empty_initialize();
-#         ifdef __STL_USE_EXCEPTIONS
-      try {
-#         endif /* __STL_USE_EXCEPTIONS */
-        insert(begin(), first, last);
-#         ifdef __STL_USE_EXCEPTIONS
-      }
-      catch(...) {
-        clear();
-        put_node(node);
-        throw;
-      }
-#         endif /* __STL_USE_EXCEPTIONS */
-    }
-    void range_initialize(const_iterator first, const_iterator last) {
-      empty_initialize();
-#         ifdef __STL_USE_EXCEPTIONS
-      try {
-#         endif /* __STL_USE_EXCEPTIONS */
-        insert(begin(), first, last);
-#         ifdef __STL_USE_EXCEPTIONS
-      }
-      catch(...) {
-        clear();
-        put_node(node);
-        throw;
-      }
-#         endif /* __STL_USE_EXCEPTIONS */
-    }  
-#endif /* __STL_MEMBER_TEMPLATES */
-
-protected:
-    link_type node;
-
-public:
-    list() { empty_initialize(); }
-
-    iterator begin() { return (link_type)((*node).next); }
-    const_iterator begin() const { return (link_type)((*node).next); }
-    iterator end() { return node; }
-    const_iterator end() const { return node; }
-    reverse_iterator rbegin() { return reverse_iterator(end()); }
-    const_reverse_iterator rbegin() const { 
-        return const_reverse_iterator(end()); 
-    }
-    reverse_iterator rend() { return reverse_iterator(begin()); }
-    const_reverse_iterator rend() const { 
-        return const_reverse_iterator(begin());
-    } 
-    bool empty() const { return node->next == node; }
-    size_type size() const {
-      size_type result = 0;
-      distance(begin(), end(), result);
-      return result;
-    }
-    size_type max_size() const { return size_type(-1); }
-    reference front() { return *begin(); }
-    const_reference front() const { return *begin(); }
-    reference back() { return *(--end()); }
-    const_reference back() const { return *(--end()); }
-    void swap(list<T, Alloc>& x) { ::swap(node, x.node); }
-    iterator insert(iterator position, const T& x) {
-      link_type tmp = create_node(x);
-      tmp->next = position.node;
-      tmp->prev = position.node->prev;
-      (link_type(position.node->prev))->next = tmp;
-      position.node->prev = tmp;
-      return tmp;
-    }
-    iterator insert(iterator position) { return insert(position, T()); }
-#ifdef __STL_MEMBER_TEMPLATES
-    template <class InputIterator>
-    void insert(iterator position, InputIterator first, InputIterator last);
-#else /* __STL_MEMBER_TEMPLATES */
-    void insert(iterator position, const T* first, const T* last);
-    void insert(iterator position,
-                const_iterator first, const_iterator last);
-#endif /* __STL_MEMBER_TEMPLATES */
-    void insert(iterator pos, size_type n, const T& x);
-    void insert(iterator pos, int n, const T& x) {
-      insert(pos, (size_type)n, x);
-    }
-    void insert(iterator pos, long n, const T& x) {
-      insert(pos, (size_type)n, x);
-    }
-
-    void push_front(const T& x) { insert(begin(), x); }
-    void push_back(const T& x) { insert(end(), x); }
-    void erase(iterator position) {
-      (link_type(position.node->prev))->next = position.node->next;
-      (link_type(position.node->next))->prev = position.node->prev;
-      destroy_node(position.node);
-    }
-    void erase(iterator first, iterator last);
-    void resize(size_type new_size, const T& x);
-    void resize(size_type new_size) { resize(new_size, T()); }
-    void clear();
-
-    void pop_front() { erase(begin()); }
-    void pop_back() { 
-        iterator tmp = end();
-        erase(--tmp);
-    }
-    list(size_type n, const T& value) { fill_initialize(n, value); }
-    list(int n, const T& value) { fill_initialize(n, value); }
-    list(long n, const T& value) { fill_initialize(n, value); }
-    explicit list(size_type n) { fill_initialize(n, T()); }
-
-#ifdef __STL_MEMBER_TEMPLATES
-    template <class InputIterator>
-    list(InputIterator first, InputIterator last) {
-      range_initialize(first, last);
-    }
-
-#else /* __STL_MEMBER_TEMPLATES */
-    list(const T* first, const T* last) { range_initialize(first, last); }
-    list(const_iterator first, const_iterator last) {
-      range_initialize(first, last);
-    }
-#endif /* __STL_MEMBER_TEMPLATES */
-    list(const list<T, Alloc>& x) {
-      range_initialize(x.begin(), x.end());
-    }
-    ~list() {
-        clear();
-       put_node(node);
-    }
-    list<T, Alloc>& operator=(const list<T, Alloc>& x);
-
-protected:
-    void transfer(iterator position, iterator first, iterator last) {
-      if (position != last) {
-       (*(link_type((*last.node).prev))).next = position.node;
-       (*(link_type((*first.node).prev))).next = last.node;
-       (*(link_type((*position.node).prev))).next = first.node;  
-       link_type tmp = link_type((*position.node).prev);
-       (*position.node).prev = (*last.node).prev;
-       (*last.node).prev = (*first.node).prev; 
-       (*first.node).prev = tmp;
-      }
-    }
-
-public:
-    void splice(iterator position, list& x) {
-      if (!x.empty()) 
-        transfer(position, x.begin(), x.end());
-    }
-    void splice(iterator position, list&, iterator i) {
-      iterator j = i;
-      ++j;
-      if (position == i || position == j) return;
-      transfer(position, i, j);
-    }
-    void splice(iterator position, list&, iterator first, iterator last) {
-      if (first != last) 
-        transfer(position, first, last);
-    }
-    void remove(const T& value);
-    void unique();
-    void merge(list& x);
-    void reverse();
-    void sort();
-
-#ifdef __STL_MEMBER_TEMPLATES
-    template <class Predicate> void remove_if(Predicate);
-    template <class BinaryPredicate> void unique(BinaryPredicate);
-    template <class StrictWeakOrdering> void merge(list&, StrictWeakOrdering);
-    template <class StrictWeakOrdering> void sort(StrictWeakOrdering);
-#endif /* __STL_MEMBER_TEMPLATES */
-
-    friend bool operator== (const list& x, const list& y);
-};
-
-template <class T, class Alloc>
-inline bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y) {
-  typedef list<T,Alloc>::link_type link_type;
-  link_type e1 = x.node;
-  link_type e2 = y.node;
-  link_type n1 = (link_type) e1->next;
-  link_type n2 = (link_type) e2->next;
-  for ( ; n1 != e1 && n2 != e2 ;
-          n1 = (link_type) n1->next, n2 = (link_type) n2->next)
-    if (n1->data != n2->data)
-      return false;
-  return n1 == e1 && n2 == e2;
-}
-
-template <class T, class Alloc>
-inline bool operator<(const list<T, Alloc>& x, const list<T, Alloc>& y) {
-    return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
-}
-
-#ifdef __STL_MEMBER_TEMPLATES
-
-template <class T, class Alloc> template <class InputIterator>
-void list<T, Alloc>::insert(iterator position,
-                            InputIterator first, InputIterator last) {
-  for ( ; first != last; ++first)
-    insert(position, *first);
-}
-
-#else /* __STL_MEMBER_TEMPLATES */
-
-template <class T, class Alloc>
-void list<T, Alloc>::insert(iterator position, const T* first, const T* last) {
-  for ( ; first != last; ++first)
-    insert(position, *first);
-}
-
-template <class T, class Alloc>
-void list<T, Alloc>::insert(iterator position,
-                            const_iterator first, const_iterator last) {
-  for ( ; first != last; ++first)
-    insert(position, *first);
-}
-
-#endif /* __STL_MEMBER_TEMPLATES */
-
-template <class T, class Alloc>
-void list<T, Alloc>::insert(iterator position, size_type n, const T& x) {
-  for ( ; n > 0; --n)
-    insert(position, x);
-}
-
-template <class T, class Alloc>
-void list<T, Alloc>::erase(iterator first, iterator last) {
-    while (first != last) erase(first++);
-}
-
-template <class T, class Alloc>
-void list<T, Alloc>::resize(size_type new_size, const T& x)
-{
-  size_type len = size();
-  if (new_size < len) {
-    iterator f;
-    if (new_size < len / 2) {
-      f = begin();
-      advance(f, new_size);
-    }
-    else {
-      f = end();
-      advance(f, difference_type(len) - difference_type(new_size));
-    }
-    erase(f, end());
-  }
-  else
-    insert(end(), new_size - len, x);
-}
-
-template <class T, class Alloc> 
-void list<T, Alloc>::clear()
-{
-  link_type cur = (link_type) node->next;
-  while (cur != node) {
-    link_type tmp = cur;
-    cur = (link_type) cur->next;
-    destroy_node(tmp);
-  }
-  node->next = node;
-  node->prev = node;
-}
-
-template <class T, class Alloc>
-list<T, Alloc>& list<T, Alloc>::operator=(const list<T, Alloc>& x) {
-    if (this != &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);
-    }
-    return *this;
-}
-
-template <class T, class Alloc>
-void list<T, Alloc>::remove(const T& value) {
-  iterator first = begin();
-  iterator last = end();
-  while (first != last) {
-    iterator next = first;
-    ++next;
-    if (*first == value) erase(first);
-    first = next;
-  }
-}
-
-template <class T, class Alloc>
-void list<T, Alloc>::unique() {
-  iterator first = begin();
-  iterator last = end();
-  if (first == last) return;
-  iterator next = first;
-  while (++next != last) {
-    if (*first == *next)
-      erase(next);
-    else
-      first = next;
-    next = first;
-  }
-}
-
-template <class T, class Alloc>
-void list<T, Alloc>::merge(list<T, Alloc>& x) {
-  iterator first1 = begin();
-  iterator last1 = end();
-  iterator first2 = x.begin();
-  iterator last2 = x.end();
-  while (first1 != last1 && first2 != last2)
-    if (*first2 < *first1) {
-      iterator next = first2;
-      transfer(first1, first2, ++next);
-      first2 = next;
-    }
-    else
-      ++first1;
-  if (first2 != last2) transfer(last1, first2, last2);
-}
-
-template <class T, class Alloc>
-void list<T, Alloc>::reverse() {
-  if (node->next == node || link_type(node->next)->next == node) return;
-  iterator first = begin();
-  ++first;
-  while (first != end()) {
-    iterator old = first;
-    ++first;
-    transfer(begin(), old, first);
-  }
-}    
-
-template <class T, class Alloc>
-void list<T, Alloc>::sort() {
-  if (node->next == node || link_type(node->next)->next == node) return;
-  list<T, Alloc> carry;
-  list<T, Alloc> 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);
-      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]);
-  swap(counter[fill-1]);
-}
-
-#ifdef __STL_MEMBER_TEMPLATES
-
-template <class T, class Alloc> template <class Predicate>
-void list<T, 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 <class T, class Alloc> template <class BinaryPredicate>
-void list<T, 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 <class T, class Alloc> template <class StrictWeakOrdering>
-void list<T, Alloc>::merge(list<T, Alloc>& 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;
-      transfer(first1, first2, ++next);
-      first2 = next;
-    }
-    else
-      ++first1;
-  if (first2 != last2) transfer(last1, first2, last2);
-}
-
-template <class T, class Alloc> template <class StrictWeakOrdering>
-void list<T, Alloc>::sort(StrictWeakOrdering comp) {
-  if (node->next == node || link_type(node->next)->next == node) return;
-  list<T, Alloc> carry;
-  list<T, Alloc> 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]);
-}
-
-#endif /* __STL_MEMBER_TEMPLATES */
+#ifdef __STL_USE_NAMESPACES
+using __STD::list;
+#endif /* __STL_USE_NAMESPACES */
 
 #endif /* __SGI_STL_LIST_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/map b/libstdc++/stl/map
new file mode 100644 (file)
index 0000000..4cfb765
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __SGI_STL_MAP
+#define __SGI_STL_MAP
+
+#ifndef __SGI_STL_INTERNAL_TREE_H
+#include <stl_tree.h>
+#endif
+#include <stl_map.h>
+#include <stl_multimap.h>
+
+#endif /* __SGI_STL_MAP */
+
+// Local Variables:
+// mode:C++
+// End:
index 5c9d6b1..a89bd31 100644 (file)
@@ -12,7 +12,7 @@
  * purpose.  It is provided "as is" without express or implied warranty.
  *
  *
- * Copyright (c) 1996
+ * Copyright (c) 1996,1997
  * Silicon Graphics Computer Systems, Inc.
  *
  * Permission to use, copy, modify, distribute and sell this software
 #define __SGI_STL_MAP_H
 
 #include <tree.h>
+#include <stl_map.h>
 
-#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
-template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
-#else
-template <class Key, class T, class Compare, class Alloc = alloc>
-#endif
-class map {
-public:
-
-// typedefs:
-
-  typedef Key key_type;
-  typedef T data_type;
-  typedef pair<const Key, T> value_type;
-  typedef Compare key_compare;
-    
-  class value_compare
-        : public binary_function<value_type, value_type, bool> {
-    friend class map<Key, T, 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:
-  typedef rb_tree<key_type, value_type, 
-                  select1st<value_type>, key_compare, Alloc> rep_type;
-  rep_type t;  // red-black tree representing map
-public:
-  typedef rep_type::pointer pointer;
-  typedef rep_type::reference reference;
-  typedef rep_type::const_reference const_reference;
-  typedef rep_type::iterator iterator;
-  typedef rep_type::const_iterator const_iterator;
-  typedef rep_type::reverse_iterator reverse_iterator;
-  typedef rep_type::const_reverse_iterator const_reverse_iterator;
-  typedef rep_type::size_type size_type;
-  typedef rep_type::difference_type difference_type;
-
-  // allocation/deallocation
-
-  map() : t(Compare()) {}
-  explicit map(const Compare& comp) : t(comp) {}
-
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  map(InputIterator first, InputIterator last)
-    : t(Compare()) { t.insert_unique(first, last); }
-
-  template <class InputIterator>
-  map(InputIterator first, InputIterator last, const Compare& comp)
-    : t(comp) { t.insert_unique(first, last); }
-#else
-  map(const value_type* first, const value_type* last)
-    : t(Compare()) { t.insert_unique(first, last); }
-  map(const value_type* first, const value_type* last, const Compare& comp)
-    : t(comp) { t.insert_unique(first, last); }
-
-  map(const_iterator first, const_iterator last)
-    : t(Compare()) { t.insert_unique(first, last); }
-  map(const_iterator first, const_iterator last, const Compare& comp)
-    : t(comp) { t.insert_unique(first, last); }
-#endif /* __STL_MEMBER_TEMPLATES */
-
-  map(const map<Key, T, Compare, Alloc>& x) : t(x.t) {}
-  map<Key, T, Compare, Alloc>& operator=(const map<Key, T, Compare, Alloc>& x)
-  {
-    t = x.t;
-    return *this; 
-  }
-
-  // accessors:
-
-  key_compare key_comp() const { return t.key_comp(); }
-  value_compare value_comp() const { return value_compare(t.key_comp()); }
-  iterator begin() { return t.begin(); }
-  const_iterator begin() const { return t.begin(); }
-  iterator end() { return t.end(); }
-  const_iterator end() const { return t.end(); }
-  reverse_iterator rbegin() { return t.rbegin(); }
-  const_reverse_iterator rbegin() const { return t.rbegin(); }
-  reverse_iterator rend() { return t.rend(); }
-  const_reverse_iterator rend() const { return t.rend(); }
-  bool empty() const { return t.empty(); }
-  size_type size() const { return t.size(); }
-  size_type max_size() const { return t.max_size(); }
-  T& operator[](const key_type& k) {
-    return (*((insert(value_type(k, T()))).first)).second;
-  }
-  void swap(map<Key, T, Compare, Alloc>& x) { t.swap(x.t); }
-
-  // insert/erase
-
-  pair<iterator,bool> insert(const value_type& x) { return t.insert_unique(x); }
-  iterator insert(iterator position, const value_type& x) {
-    return t.insert_unique(position, x);
-  }
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  void insert(InputIterator first, InputIterator last) {
-    t.insert_unique(first, last);
-  }
-#else
-  void insert(const value_type* first, const value_type* last) {
-    t.insert_unique(first, last);
-  }
-  void insert(const_iterator first, const_iterator last) {
-    t.insert_unique(first, last);
-  }
-#endif /* __STL_MEMBER_TEMPLATES */
-
-  void erase(iterator position) { t.erase(position); }
-  size_type erase(const key_type& x) { return t.erase(x); }
-  void erase(iterator first, iterator last) { t.erase(first, last); }
-  void clear() { t.clear(); }
-
-  // map operations:
-
-  iterator find(const key_type& x) { return t.find(x); }
-  const_iterator find(const key_type& x) const { return t.find(x); }
-  size_type count(const key_type& x) const { return t.count(x); }
-  iterator lower_bound(const key_type& x) {return t.lower_bound(x); }
-  const_iterator lower_bound(const key_type& x) const {
-    return t.lower_bound(x); 
-  }
-  iterator upper_bound(const key_type& x) {return t.upper_bound(x); }
-  const_iterator upper_bound(const key_type& x) const {
-    return t.upper_bound(x); 
-  }
-  
-  pair<iterator,iterator> equal_range(const key_type& x) {
-    return t.equal_range(x);
-  }
-  pair<const_iterator,const_iterator> equal_range(const key_type& x) const {
-    return t.equal_range(x);
-  }
-  friend bool operator==(const map&, const map&);
-  friend bool operator<(const map&, const map&);
-};
-
-template <class Key, class T, class Compare, class Alloc>
-inline bool operator==(const map<Key, T, Compare, Alloc>& x, 
-                       const map<Key, T, Compare, Alloc>& y) {
-  return x.t == y.t;
-}
-
-template <class Key, class T, class Compare, class Alloc>
-inline bool operator<(const map<Key, T, Compare, Alloc>& x, 
-                      const map<Key, T, Compare, Alloc>& y) {
-  return x.t < y.t;
-}
+#ifdef __STL_USE_NAMESPACES
+using __STD::map;
+#endif /* __STL_USE_NAMESPACES */
 
 #endif /* __SGI_STL_MAP_H */
 
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/memory b/libstdc++/stl/memory
new file mode 100644 (file)
index 0000000..a806588
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef __SGI_STL_MEMORY
+#define __SGI_STL_MEMORY
+
+#include <stl_algobase.h>
+#include <stl_alloc.h>
+#include <stl_construct.h>
+#include <stl_tempbuf.h>
+#include <stl_uninitialized.h>
+#include <stl_raw_storage_iter.h>
+
+// Note: auto_ptr is commented out in this release because the details
+//  of the interface are still being discussed by the C++ standardization
+//  committee.  It will be included once the iterface is finalized.
+
+#if 0
+#if defined(_MUTABLE_IS_KEYWORD) && defined(_EXPLICIT_IS_KEYWORD) && \
+    defined(__STL_MEMBER_TEMPLATES)
+
+__STL_BEGIN_NAMESPACE
+
+template <class X> class auto_ptr {
+private:
+  X* ptr;
+  mutable bool owns;
+public:
+  typedef X element_type;
+  explicit auto_ptr(X* p = 0) __STL_NOTHROW : ptr(p), owns(p) {}
+  auto_ptr(const auto_ptr& a) __STL_NOTHROW : ptr(a.ptr), owns(a.owns) {
+    a.owns = 0;
+  }
+  template <class T> auto_ptr(const auto_ptr<T>& a) __STL_NOTHROW
+    : ptr(a.ptr), owns(a.owns) {
+      a.owns = 0;
+  }
+
+  auto_ptr& operator=(const auto_ptr& a) __STL_NOTHROW {
+    if (&a != this) {
+      if (owns)
+        delete ptr;
+      owns = a.owns;
+      ptr = a.ptr;
+      a.owns = 0;
+    }
+  }
+  template <class T> auto_ptr& operator=(const auto_ptr<T>& a) __STL_NOTHROW {
+    if (&a != this) {
+      if (owns)
+        delete ptr;
+      owns = a.owns;
+      ptr = a.ptr;
+      a.owns = 0;
+    }
+  }
+  ~auto_ptr() {
+    if (owns)
+      delete ptr;
+  }
+
+  X& operator*() const __STL_NOTHROW { return *ptr; }
+  X* operator->() const __STL_NOTHROW { return ptr; }
+  X* get() const __STL_NOTHROW { return ptr; }
+  X* release const __STL_NOTHROW { owns = false; return ptr }
+};
+
+__STL_END_NAMESPACE
+#endif /* mutable && explicit && member templates */
+#endif /* 0 */
+
+
+#endif /* __SGI_STL_MEMORY */
+
+
+// Local Variables:
+// mode:C++
+// End:
index f15880a..1a8ec4a 100644 (file)
@@ -12,7 +12,7 @@
  * purpose.  It is provided "as is" without express or implied warranty.
  *
  *
- * Copyright (c) 1996
+ * Copyright (c) 1996,1997
  * Silicon Graphics Computer Systems, Inc.
  *
  * Permission to use, copy, modify, distribute and sell this software
 #define __SGI_STL_MULTIMAP_H
 
 #include <tree.h>
+#include <stl_multimap.h>
 
-#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
-template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
-#else
-template <class Key, class T, class Compare, class Alloc = alloc>
-#endif
-class multimap {
-public:
-
-// typedefs:
-
-  typedef Key key_type;
-  typedef T data_type;
-  typedef pair<const Key, T> value_type;
-  typedef Compare key_compare;
-
-  class value_compare : public binary_function<value_type, value_type, bool> {
-    friend class multimap<Key, T, 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:
-  typedef rb_tree<key_type, value_type, 
-                  select1st<value_type>, key_compare, Alloc> rep_type;
-  rep_type t;  // red-black tree representing multimap
-public:
-  typedef rep_type::pointer pointer;
-  typedef rep_type::reference reference;
-  typedef rep_type::const_reference const_reference;
-  typedef rep_type::iterator iterator;
-  typedef rep_type::const_iterator const_iterator; 
-  typedef rep_type::reverse_iterator reverse_iterator;
-  typedef rep_type::const_reverse_iterator const_reverse_iterator;
-  typedef rep_type::size_type size_type;
-  typedef rep_type::difference_type difference_type;
-
-// allocation/deallocation
-
-  multimap() : t(Compare()) { }
-  explicit multimap(const Compare& comp) : t(comp) { }
-
-#ifdef __STL_MEMBER_TEMPLATES  
-  template <class InputIterator>
-  multimap(InputIterator first, InputIterator last)
-    : t(Compare()) { t.insert_equal(first, last); }
-
-  template <class InputIterator>
-  multimap(InputIterator first, InputIterator last, const Compare& comp)
-    : t(comp) { t.insert_equal(first, last); }
-#else
-  multimap(const value_type* first, const value_type* last)
-    : t(Compare()) { t.insert_equal(first, last); }
-  multimap(const value_type* first, const value_type* last,
-           const Compare& comp)
-    : t(comp) { t.insert_equal(first, last); }
-
-  multimap(const_iterator first, const_iterator last)
-    : t(Compare()) { t.insert_equal(first, last); }
-  multimap(const_iterator first, const_iterator last, const Compare& comp)
-    : t(comp) { t.insert_equal(first, last); }
-#endif /* __STL_MEMBER_TEMPLATES */
-
-  multimap(const multimap<Key, T, Compare, Alloc>& x) : t(x.t) { }
-  multimap<Key, T, Compare, Alloc>&
-  operator=(const multimap<Key, T, Compare, Alloc>& x) {
-    t = x.t;
-    return *this; 
-  }
-
-  // accessors:
-
-  key_compare key_comp() const { return t.key_comp(); }
-  value_compare value_comp() const { return value_compare(t.key_comp()); }
-  iterator begin() { return t.begin(); }
-  const_iterator begin() const { return t.begin(); }
-  iterator end() { return t.end(); }
-  const_iterator end() const { return t.end(); }
-  reverse_iterator rbegin() { return t.rbegin(); }
-  const_reverse_iterator rbegin() const { return t.rbegin(); }
-  reverse_iterator rend() { return t.rend(); }
-  const_reverse_iterator rend() const { return t.rend(); }
-  bool empty() const { return t.empty(); }
-  size_type size() const { return t.size(); }
-  size_type max_size() const { return t.max_size(); }
-  void swap(multimap<Key, T, Compare, Alloc>& x) { t.swap(x.t); }
-
-  // insert/erase
-
-  iterator insert(const value_type& x) { return t.insert_equal(x); }
-  iterator insert(iterator position, const value_type& x) {
-    return t.insert_equal(position, x);
-  }
-#ifdef __STL_MEMBER_TEMPLATES  
-  template <class InputIterator>
-  void insert(InputIterator first, InputIterator last) {
-    t.insert_equal(first, last);
-  }
-#else
-  void insert(const value_type* first, const value_type* last) {
-    t.insert_equal(first, last);
-  }
-  void insert(const_iterator first, const_iterator last) {
-    t.insert_equal(first, last);
-  }
-#endif /* __STL_MEMBER_TEMPLATES */
-  void erase(iterator position) { t.erase(position); }
-  size_type erase(const key_type& x) { return t.erase(x); }
-  void erase(iterator first, iterator last) { t.erase(first, last); }
-  void clear() { t.clear(); }
-
-  // multimap operations:
-
-  iterator find(const key_type& x) { return t.find(x); }
-  const_iterator find(const key_type& x) const { return t.find(x); }
-  size_type count(const key_type& x) const { return t.count(x); }
-  iterator lower_bound(const key_type& x) {return t.lower_bound(x); }
-  const_iterator lower_bound(const key_type& x) const {
-    return t.lower_bound(x); 
-  }
-  iterator upper_bound(const key_type& x) {return t.upper_bound(x); }
-  const_iterator upper_bound(const key_type& x) const {
-    return t.upper_bound(x); 
-  }
-   pair<iterator,iterator> equal_range(const key_type& x) {
-    return t.equal_range(x);
-  }
-  pair<const_iterator,const_iterator> equal_range(const key_type& x) const {
-    return t.equal_range(x);
-  }
-  friend bool operator==(const multimap&, const multimap&);
-  friend bool operator<(const multimap&, const multimap&);
-};
-
-template <class Key, class T, class Compare, class Alloc>
-inline bool operator==(const multimap<Key, T, Compare, Alloc>& x, 
-                       const multimap<Key, T, Compare, Alloc>& y) {
-  return x.t == y.t;
-}
-
-template <class Key, class T, class Compare, class Alloc>
-inline bool operator<(const multimap<Key, T, Compare, Alloc>& x, 
-                      const multimap<Key, T, Compare, Alloc>& y) {
-  return x.t < y.t;
-}
+#ifdef __STL_USE_NAMESPACES
+using __STD::multimap;
+#endif /* __STL_USE_NAMESPACES */
 
 #endif /* __SGI_STL_MULTIMAP_H */
+
+// Local Variables:
+// mode:C++
+// End:
index 3df4557..3024fd7 100644 (file)
@@ -12,7 +12,7 @@
  * purpose.  It is provided "as is" without express or implied warranty.
  *
  *
- * Copyright (c) 1996
+ * Copyright (c) 1996,1997
  * Silicon Graphics Computer Systems, Inc.
  *
  * Permission to use, copy, modify, distribute and sell this software
 #define __SGI_STL_MULTISET_H
 
 #include <tree.h>
+#include <stl_multiset.h>
 
-#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
-template <class Key, class Compare = less<Key>, class Alloc = alloc>
-#else
-template <class Key, class Compare, class Alloc = alloc>
-#endif
-class multiset {
-public:
-  // typedefs:
-
-  typedef Key key_type;
-  typedef Key value_type;
-  typedef Compare key_compare;
-  typedef Compare value_compare;
-private:
-  typedef rb_tree<key_type, value_type, 
-                  identity<value_type>, key_compare, Alloc> rep_type;
-  rep_type t;  // red-black tree representing multiset
-public:
-  typedef rep_type::const_pointer pointer;
-  typedef rep_type::const_reference reference;
-  typedef rep_type::const_reference const_reference;
-  typedef rep_type::const_iterator iterator;
-  typedef rep_type::const_iterator const_iterator;
-  typedef rep_type::const_reverse_iterator reverse_iterator;
-  typedef rep_type::const_reverse_iterator const_reverse_iterator;
-  typedef rep_type::size_type size_type;
-  typedef rep_type::difference_type difference_type;
-
-  // allocation/deallocation
-
-  multiset() : t(Compare()) {}
-  explicit multiset(const Compare& comp) : t(comp) {}
-
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  multiset(InputIterator first, InputIterator last)
-    : t(Compare()) { t.insert_equal(first, last); }
-  template <class InputIterator>
-  multiset(InputIterator first, InputIterator last, const Compare& comp)
-    : t(comp) { t.insert_equal(first, last); }
-#else
-  multiset(const value_type* first, const value_type* last)
-    : t(Compare()) { t.insert_equal(first, last); }
-  multiset(const value_type* first, const value_type* last,
-           const Compare& comp)
-    : t(comp) { t.insert_equal(first, last); }
-
-  multiset(const_iterator first, const_iterator last)
-    : t(Compare()) { t.insert_equal(first, last); }
-  multiset(const_iterator first, const_iterator last, const Compare& comp)
-    : t(comp) { t.insert_equal(first, last); }
-#endif /* __STL_MEMBER_TEMPLATES */
-
-  multiset(const multiset<Key, Compare, Alloc>& x) : t(x.t) {}
-  multiset<Key, Compare, Alloc>&
-  operator=(const multiset<Key, Compare, Alloc>& x) {
-    t = x.t; 
-    return *this;
-  }
-
-  // accessors:
-
-  key_compare key_comp() const { return t.key_comp(); }
-  value_compare value_comp() const { return t.key_comp(); }
-  iterator begin() const { return t.begin(); }
-  iterator end() const { return t.end(); }
-  reverse_iterator rbegin() const { return t.rbegin(); } 
-  reverse_iterator rend() const { return t.rend(); }
-  bool empty() const { return t.empty(); }
-  size_type size() const { return t.size(); }
-  size_type max_size() const { return t.max_size(); }
-  void swap(multiset<Key, Compare, Alloc>& x) { t.swap(x.t); }
-
-  // insert/erase
-  iterator insert(const value_type& x) { 
-    return t.insert_equal(x);
-  }
-  iterator insert(iterator position, const value_type& x) {
-    return t.insert_equal((rep_type::iterator&)position, x);
-  }
-
-#ifdef __STL_MEMBER_TEMPLATES  
-  template <class InputIterator>
-  void insert(InputIterator first, InputIterator last) {
-    t.insert_equal(first, last);
-  }
-#else
-  void insert(const value_type* first, const value_type* last) {
-    t.insert_equal(first, last);
-  }
-  void insert(const_iterator first, const_iterator last) {
-    t.insert_equal(first, last);
-  }
-#endif /* __STL_MEMBER_TEMPLATES */
-  void erase(iterator position) { 
-    t.erase((rep_type::iterator&)position); 
-  }
-  size_type erase(const key_type& x) { 
-    return t.erase(x); 
-  }
-  void erase(iterator first, iterator last) { 
-    t.erase((rep_type::iterator&)first, 
-            (rep_type::iterator&)last); 
-  }
-  void clear() { t.clear(); }
-
-  // multiset operations:
-
-  iterator find(const key_type& x) const { return t.find(x); }
-  size_type count(const key_type& x) const { return t.count(x); }
-  iterator lower_bound(const key_type& x) const {
-    return t.lower_bound(x);
-  }
-  iterator upper_bound(const key_type& x) const {
-    return t.upper_bound(x); 
-  }
-  pair<iterator,iterator> equal_range(const key_type& x) const {
-    return t.equal_range(x);
-  }
-  friend bool operator==(const multiset&, const multiset&);
-  friend bool operator<(const multiset&, const multiset&);
-};
-
-template <class Key, class Compare, class Alloc>
-inline bool operator==(const multiset<Key, Compare, Alloc>& x, 
-                       const multiset<Key, Compare, Alloc>& y) {
-  return x.t == y.t;
-}
-
-template <class Key, class Compare, class Alloc>
-inline bool operator<(const multiset<Key, Compare, Alloc>& x, 
-                      const multiset<Key, Compare, Alloc>& y) {
-  return x.t < y.t;
-}
+#ifdef __STL_USE_NAMESPACES
+using __STD::multiset;
+#endif /* __STL_USE_NAMESPACES */
 
 #endif /* __SGI_STL_MULTISET_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/numeric b/libstdc++/stl/numeric
new file mode 100644 (file)
index 0000000..7f048e1
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __SGI_STL_NUMERIC
+#define __SGI_STL_NUMERIC
+
+#include <stl_config.h>
+#include <stl_relops.h>
+#include <stddef.h>
+#include <iostream.h>
+#include <stl_iterator.h>
+#include <stl_function.h>
+#include <stl_numeric.h>
+
+#endif /* __SGI_STL_NUMERIC */
+
+// Local Variables:
+// mode:C++
+// End:
index ca20d8b..00f5cad 100644 (file)
@@ -12,7 +12,7 @@
  * purpose.  It is provided "as is" without express or implied warranty.
  *
  *
- * Copyright (c) 1996
+ * Copyright (c) 1996,1997
  * Silicon Graphics Computer Systems, Inc.
  *
  * Permission to use, copy, modify, distribute and sell this software
  * purpose.  It is provided "as is" without express or implied warranty.
  */
 
-#ifndef PAIR_H
-#define PAIR_H
+#ifndef __SGI_STL_PAIR_H
+#define __SGI_STL_PAIR_H
 
+#ifndef __STL_CONFIG_H
 #include <stl_config.h>
-
-template <class T1, class T2>
-struct pair {
-    typedef T1 first_type;
-    typedef T2 second_type;
-
-    T1 first;
-    T2 second;
-    pair() : first(T1()), second(T2()) {}
-    pair(const T1& a, const T2& b) : first(a), second(b) {}
-
-#ifdef __STL_MEMBER_TEMPLATES
-    template <class U1, class U2>
-    pair(const pair<U1, U2>& p) : first(p.first), second(p.second) {}
 #endif
-};
+#ifndef __SGI_STL_INTERNAL_RELOPS
+#include <stl_relops.h>
+#endif
+#ifndef __SGI_STL_INTERNAL_PAIR_H
+#include <stl_pair.h>
+#endif
 
-template <class T1, class T2>
-inline bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y) { 
-    return x.first == y.first && x.second == y.second; 
-}
+#ifdef __STL_USE_NAMESPACES
 
-template <class T1, class T2>
-inline bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y) { 
-    return x.first < y.first || (!(y.first < x.first) && x.second < y.second); 
-}
+using __STD::pair;
+using __STD::make_pair;
 
-template <class T1, class T2>
-inline pair<T1, T2> make_pair(const T1& x, const T2& y) {
-    return pair<T1, T2>(x, y);
-}
+#endif /* __STL_USE_NAMESPACES */
 
-#endif
+#endif /* __SGI_STL_PAIR_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/pthread_alloc b/libstdc++/stl/pthread_alloc
new file mode 100644 (file)
index 0000000..71df3d3
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __SGI_STL_PTHREAD_ALLOC
+#define __SGI_STL_PTHREAD_ALLOC
+
+// Pthread-specific node allocator.
+// This is similar to the default allocator, except that free-list
+// information is kept separately for each thread, avoiding locking.
+// This should be reasonably fast even in the presence of threads.
+// The down side is that storage may not be well-utilized.
+// It is not an error to allocate memory in thread A and deallocate
+// it n thread B.  But this effectively transfers ownership of the memory,
+// so that it can only be reallocated by thread B.  Thus this can effectively
+// result in a storage leak if it's done on a regular basis.
+// It can also result in frequent sharing of
+// cache lines among processors, with potentially serious performance
+// consequences.
+
+#include <stl_config.h>
+#include <stl_alloc.h>
+#ifndef __RESTRICT
+#  define __RESTRICT
+#endif
+
+__STL_BEGIN_NAMESPACE
+
+// Note that this class has nonstatic members.  We instantiate it once
+// per thread.
+template <bool dummy>
+class __pthread_alloc_template {
+
+private:
+  enum {ALIGN = 8};
+  enum {MAX_BYTES = 128};  // power of 2
+  enum {NFREELISTS = MAX_BYTES/ALIGN};
+
+  union obj {
+        union obj * free_list_link;
+        char client_data[ALIGN];    /* The client sees this.        */
+  };
+
+  // Per instance state
+  obj* volatile free_list[NFREELISTS]; 
+  __pthread_alloc_template<dummy>* next;       // Free list link
+
+  static size_t ROUND_UP(size_t bytes) {
+       return (((bytes) + ALIGN-1) & ~(ALIGN - 1));
+  }
+  static size_t FREELIST_INDEX(size_t bytes) {
+       return (((bytes) + ALIGN-1)/ALIGN - 1);
+  }
+
+  // Returns an object of size n, and optionally adds to size n free list.
+  void *refill(size_t n);
+  // Allocates a chunk for nobjs of size size.  nobjs may be reduced
+  // if it is inconvenient to allocate the requested number.
+  static char *chunk_alloc(size_t size, int &nobjs);
+
+  // Chunk allocation state. And other shared state.
+  // Protected by chunk_allocator_lock.
+  static pthread_mutex_t chunk_allocator_lock;
+  static char *start_free;
+  static char *end_free;
+  static size_t heap_size;
+  static __pthread_alloc_template<dummy>* free_allocators;
+  static pthread_key_t key;
+  static bool key_initialized;
+       // Pthread key under which allocator is stored. 
+       // Allocator instances that are currently unclaimed by any thread.
+  static void destructor(void *instance);
+       // Function to be called on thread exit to reclaim allocator
+       // instance.
+  static __pthread_alloc_template<dummy> *new_allocator();
+       // Return a recycled or new allocator instance.
+  static __pthread_alloc_template<dummy> *get_allocator_instance();
+       // ensure that the current thread has an associated
+       // allocator instance.
+  class lock {
+      public:
+       lock () { pthread_mutex_lock(&chunk_allocator_lock); }
+       ~lock () { pthread_mutex_unlock(&chunk_allocator_lock); }
+  };
+  friend class lock;
+
+
+public:
+
+  __pthread_alloc_template() : next(0)
+  {
+    memset((void *)free_list, 0, NFREELISTS * sizeof(obj *));
+  }
+
+  /* n must be > 0     */
+  static void * allocate(size_t n)
+  {
+    obj * volatile * my_free_list;
+    obj * __RESTRICT result;
+    __pthread_alloc_template<dummy>* a;
+
+    if (n > MAX_BYTES) {
+       return(malloc(n));
+    }
+    if (!key_initialized ||
+        !(a = (__pthread_alloc_template<dummy>*)
+               pthread_getspecific(key))) {
+       a = get_allocator_instance();
+    }
+    my_free_list = a -> free_list + FREELIST_INDEX(n);
+    result = *my_free_list;
+    if (result == 0) {
+       void *r = a -> refill(ROUND_UP(n));
+       return r;
+    }
+    *my_free_list = result -> free_list_link;
+    return (result);
+  };
+
+  /* p may not be 0 */
+  static void deallocate(void *p, size_t n)
+  {
+    obj *q = (obj *)p;
+    obj * volatile * my_free_list;
+    __pthread_alloc_template<dummy>* a;
+
+    if (n > MAX_BYTES) {
+       free(p);
+       return;
+    }
+    if (!key_initialized ||
+        !(a = (__pthread_alloc_template<dummy>*)
+               pthread_getspecific(key))) {
+       a = get_allocator_instance();
+    }
+    my_free_list = a->free_list + FREELIST_INDEX(n);
+    q -> free_list_link = *my_free_list;
+    *my_free_list = q;
+  }
+
+  static void * reallocate(void *p, size_t old_sz, size_t new_sz);
+
+} ;
+
+typedef __pthread_alloc_template<false> pthread_alloc;
+
+
+template <bool dummy>
+void __pthread_alloc_template<dummy>::destructor(void * instance)
+{
+    __pthread_alloc_template<dummy>* a =
+       (__pthread_alloc_template<dummy>*)instance;
+    a -> next = free_allocators;
+    free_allocators = a;
+}
+
+template <bool dummy>
+__pthread_alloc_template<dummy>*
+__pthread_alloc_template<dummy>::new_allocator()
+{
+    if (0 != free_allocators) {
+       __pthread_alloc_template<dummy>* result = free_allocators;
+       free_allocators = free_allocators -> next;
+       return result;
+    } else {
+       return new __pthread_alloc_template<dummy>;
+    }
+}
+
+template <bool dummy>
+__pthread_alloc_template<dummy>*
+__pthread_alloc_template<dummy>::get_allocator_instance()
+{
+    __pthread_alloc_template<dummy>* result;
+    if (!key_initialized) {
+       /*REFERENCED*/
+       lock lock_instance;
+       if (!key_initialized) {
+           if (pthread_key_create(&key, destructor)) {
+               abort();  // failed
+           }
+           key_initialized = true;
+       }
+    }
+    result = new_allocator();
+    if (pthread_setspecific(key, result)) abort();
+    return result;
+}
+
+/* We allocate memory in large chunks in order to avoid fragmenting    */
+/* the malloc heap too much.                                           */
+/* We assume that size is properly aligned.                            */
+template <bool dummy>
+char *__pthread_alloc_template<dummy>
+::chunk_alloc(size_t size, int &nobjs)
+{
+  {
+    char * result;
+    size_t total_bytes;
+    size_t bytes_left;
+    /*REFERENCED*/
+    lock lock_instance;                // Acquire lock for this routine
+
+    total_bytes = size * nobjs;
+    bytes_left = end_free - start_free;
+    if (bytes_left >= total_bytes) {
+       result = start_free;
+       start_free += total_bytes;
+       return(result);
+    } else if (bytes_left >= size) {
+       nobjs = bytes_left/size;
+       total_bytes = size * nobjs;
+       result = start_free;
+       start_free += total_bytes;
+       return(result);
+    } else {
+       size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);
+       // Try to make use of the left-over piece.
+       if (bytes_left > 0) {
+           __pthread_alloc_template<dummy>* a = 
+               (__pthread_alloc_template<dummy>*)pthread_getspecific(key);
+           obj * volatile * my_free_list =
+                       a->free_list + FREELIST_INDEX(bytes_left);
+
+            ((obj *)start_free) -> free_list_link = *my_free_list;
+            *my_free_list = (obj *)start_free;
+       }
+#      ifdef _SGI_SOURCE
+         // Try to get memory that's aligned on something like a
+         // cache line boundary, so as to avoid parceling out
+         // parts of the same line to different threads and thus
+         // possibly different processors.
+         {
+           const int cache_line_size = 128;  // probable upper bound
+           bytes_to_get &= ~(cache_line_size-1);
+           start_free = (char *)memalign(cache_line_size, bytes_to_get); 
+           if (0 == start_free) {
+             start_free = (char *)malloc_alloc::allocate(bytes_to_get);
+           }
+         }
+#      else  /* !SGI_SOURCE */
+         start_free = (char *)malloc_alloc::allocate(bytes_to_get);
+#       endif
+       heap_size += bytes_to_get;
+       end_free = start_free + bytes_to_get;
+    }
+  }
+  // lock is released here
+  return(chunk_alloc(size, nobjs));
+}
+
+
+/* Returns an object of size n, and optionally adds to size n free list.*/
+/* We assume that n is properly aligned.                               */
+/* We hold the allocation lock.                                                */
+template <bool dummy>
+void *__pthread_alloc_template<dummy>
+::refill(size_t n)
+{
+    int nobjs = 128;
+    char * chunk = chunk_alloc(n, nobjs);
+    obj * volatile * my_free_list;
+    obj * result;
+    obj * current_obj, * next_obj;
+    int i;
+
+    if (1 == nobjs)  {
+       return(chunk);
+    }
+    my_free_list = free_list + FREELIST_INDEX(n);
+
+    /* Build free list in chunk */
+      result = (obj *)chunk;
+      *my_free_list = next_obj = (obj *)(chunk + n);
+      for (i = 1; ; i++) {
+       current_obj = next_obj;
+       next_obj = (obj *)((char *)next_obj + n);
+       if (nobjs - 1 == i) {
+           current_obj -> free_list_link = 0;
+           break;
+       } else {
+           current_obj -> free_list_link = next_obj;
+       }
+      }
+    return(result);
+}
+
+template <bool dummy>
+void *__pthread_alloc_template<dummy>
+::reallocate(void *p, size_t old_sz, size_t new_sz)
+{
+    void * result;
+    size_t copy_sz;
+
+    if (old_sz > MAX_BYTES && new_sz > MAX_BYTES) {
+       return(realloc(p, new_sz));
+    }
+    if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return(p);
+    result = allocate(new_sz);
+    copy_sz = new_sz > old_sz? old_sz : new_sz;
+    memcpy(result, p, copy_sz);
+    deallocate(p, old_sz);
+    return(result);
+}
+
+template <bool dummy>
+__pthread_alloc_template<dummy> *
+__pthread_alloc_template<dummy>::free_allocators = 0;
+
+template <bool dummy>
+pthread_key_t __pthread_alloc_template<dummy>::key;
+
+template <bool dummy>
+bool __pthread_alloc_template<dummy>::key_initialized = false;
+
+template <bool dummy>
+pthread_mutex_t __pthread_alloc_template<dummy>::chunk_allocator_lock
+= PTHREAD_MUTEX_INITIALIZER;
+
+template <bool dummy>
+char *__pthread_alloc_template<dummy>
+::start_free = 0;
+
+template <bool dummy>
+char *__pthread_alloc_template<dummy>
+::end_free = 0;
+
+template <bool dummy>
+size_t __pthread_alloc_template<dummy>
+::heap_size = 0;
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_PTHREAD_ALLOC */
+
+// Local Variables:
+// mode:C++
+// End:
index a2aeaa1..0a2debb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996
+ * Copyright (c) 1996-1997
  * Silicon Graphics Computer Systems, Inc.
  *
  * Permission to use, copy, modify, distribute and sell this software
  * purpose.  It is provided "as is" without express or implied warranty.
  */
 
-#ifndef __PTHREAD_ALLOC_H
-#define __PTHREAD_ALLOC_H
+#ifndef __SGI_STL_PTHREAD_ALLOC_H
+#define __SGI_STL_PTHREAD_ALLOC_H
 
-// Pthread-specific node allocator.
-// This is similar to the default allocator, except that free-list
-// information is kept separately for each thread, avoiding locking.
-// This should be reasonably fast even in the presence of threads.
-// The down side is that storage may not be well-utilized.
-// It is not an error to allocate memory in thread A and deallocate
-// it n thread B.  But this effectively transfers ownership of the memory,
-// so that it can only be reallocated by thread B.  Thus this can effectively
-// result in a storage leak if it's done on a regular basis.
-// It can also result in frequent sharing of
-// cache lines among processors, with potentially serious performance
-// consequences.
+#include <pthread_alloc>
 
+#ifdef __STL_USE_NAMESPACES
 
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pthread.h>
-#include <alloc.h>
-#ifndef __RESTRICT
-#  define __RESTRICT
-#endif
+using __STD::__pthread_alloc_template;
+using __STL::pthread_alloc;
 
-// Note that this class has nonstatic members.  We instantiate it once
-// per thread.
-template <bool dummy>
-class __pthread_alloc_template {
+#endif /* __STL_USE_NAMESPACES */
 
-private:
-  enum {ALIGN = 8};
-  enum {MAX_BYTES = 128};  // power of 2
-  enum {NFREELISTS = MAX_BYTES/ALIGN};
 
-  union obj {
-        union obj * free_list_link;
-        char client_data[ALIGN];    /* The client sees this.        */
-  };
+#endif /* __SGI_STL_PTHREAD_ALLOC_H */
 
-  // Per instance state
-  obj* volatile free_list[NFREELISTS]; 
-  __pthread_alloc_template<dummy>* next;       // Free list link
-
-  static size_t ROUND_UP(size_t bytes) {
-       return (((bytes) + ALIGN-1) & ~(ALIGN - 1));
-  }
-  static size_t FREELIST_INDEX(size_t bytes) {
-       return (((bytes) + ALIGN-1)/ALIGN - 1);
-  }
-
-  // Returns an object of size n, and optionally adds to size n free list.
-  void *refill(size_t n);
-  // Allocates a chunk for nobjs of size size.  nobjs may be reduced
-  // if it is inconvenient to allocate the requested number.
-  static char *chunk_alloc(size_t size, int &nobjs);
-
-  // Chunk allocation state. And other shared state.
-  // Protected by chunk_allocator_lock.
-  static pthread_mutex_t chunk_allocator_lock;
-  static char *start_free;
-  static char *end_free;
-  static size_t heap_size;
-  static __pthread_alloc_template<dummy>* free_allocators;
-  static pthread_key_t key;
-  static bool key_initialized;
-       // Pthread key under which allocator is stored. 
-       // Allocator instances that are currently unclaimed by any thread.
-  static void destructor(void *instance);
-       // Function to be called on thread exit to reclaim allocator
-       // instance.
-  static __pthread_alloc_template<dummy> *new_allocator();
-       // Return a recycled or new allocator instance.
-  static __pthread_alloc_template<dummy> *get_allocator_instance();
-       // ensure that the current thread has an associated
-       // allocator instance.
-  class lock {
-      public:
-       lock () { pthread_mutex_lock(&chunk_allocator_lock); }
-       ~lock () { pthread_mutex_unlock(&chunk_allocator_lock); }
-  };
-  friend class lock;
-
-
-public:
-
-  __pthread_alloc_template() : next(0)
-  {
-    memset((void *)free_list, 0, NFREELISTS * sizeof(obj *));
-  }
-
-  /* n must be > 0     */
-  static void * allocate(size_t n)
-  {
-    obj * volatile * my_free_list;
-    obj * __RESTRICT result;
-    __pthread_alloc_template<dummy>* a;
-
-    if (n > MAX_BYTES) {
-       return(malloc(n));
-    }
-    if (!key_initialized ||
-        !(a = (__pthread_alloc_template<dummy>*)
-               pthread_getspecific(key))) {
-       a = get_allocator_instance();
-    }
-    my_free_list = a -> free_list + FREELIST_INDEX(n);
-    result = *my_free_list;
-    if (result == 0) {
-       void *r = a -> refill(ROUND_UP(n));
-       return r;
-    }
-    *my_free_list = result -> free_list_link;
-    return (result);
-  };
-
-  /* p may not be 0 */
-  static void deallocate(void *p, size_t n)
-  {
-    obj *q = (obj *)p;
-    obj * volatile * my_free_list;
-    __pthread_alloc_template<dummy>* a;
-
-    if (n > MAX_BYTES) {
-       free(p);
-       return;
-    }
-    if (!key_initialized ||
-        !(a = (__pthread_alloc_template<dummy>*)
-               pthread_getspecific(key))) {
-       a = get_allocator_instance();
-    }
-    my_free_list = a->free_list + FREELIST_INDEX(n);
-    q -> free_list_link = *my_free_list;
-    *my_free_list = q;
-  }
-
-  static void * reallocate(void *p, size_t old_sz, size_t new_sz);
-
-} ;
-
-typedef __pthread_alloc_template<false> pthread_alloc;
-
-
-template <bool dummy>
-void __pthread_alloc_template<dummy>::destructor(void * instance)
-{
-    __pthread_alloc_template<dummy>* a =
-       (__pthread_alloc_template<dummy>*)instance;
-    a -> next = free_allocators;
-    free_allocators = a;
-}
-
-template <bool dummy>
-__pthread_alloc_template<dummy>*
-__pthread_alloc_template<dummy>::new_allocator()
-{
-    if (0 != free_allocators) {
-       __pthread_alloc_template<dummy>* result = free_allocators;
-       free_allocators = free_allocators -> next;
-       return result;
-    } else {
-       return new __pthread_alloc_template<dummy>;
-    }
-}
-
-template <bool dummy>
-__pthread_alloc_template<dummy>*
-__pthread_alloc_template<dummy>::get_allocator_instance()
-{
-    __pthread_alloc_template<dummy>* result;
-    if (!key_initialized) {
-       /*REFERENCED*/
-       lock lock_instance;
-       if (!key_initialized) {
-           if (pthread_key_create(&key, destructor)) {
-               abort();  // failed
-           }
-           key_initialized = true;
-       }
-    }
-    result = new_allocator();
-    if (pthread_setspecific(key, result)) abort();
-    return result;
-}
-
-/* We allocate memory in large chunks in order to avoid fragmenting    */
-/* the malloc heap too much.                                           */
-/* We assume that size is properly aligned.                            */
-template <bool dummy>
-char *__pthread_alloc_template<dummy>
-::chunk_alloc(size_t size, int &nobjs)
-{
-  {
-    char * result;
-    size_t total_bytes;
-    size_t bytes_left;
-    /*REFERENCED*/
-    lock lock_instance;                // Acquire lock for this routine
-
-    total_bytes = size * nobjs;
-    bytes_left = end_free - start_free;
-    if (bytes_left >= total_bytes) {
-       result = start_free;
-       start_free += total_bytes;
-       return(result);
-    } else if (bytes_left >= size) {
-       nobjs = bytes_left/size;
-       total_bytes = size * nobjs;
-       result = start_free;
-       start_free += total_bytes;
-       return(result);
-    } else {
-       size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);
-       // Try to make use of the left-over piece.
-       if (bytes_left > 0) {
-           __pthread_alloc_template<dummy>* a = 
-               (__pthread_alloc_template<dummy>*)pthread_getspecific(key);
-           obj * volatile * my_free_list =
-                       a->free_list + FREELIST_INDEX(bytes_left);
-
-            ((obj *)start_free) -> free_list_link = *my_free_list;
-            *my_free_list = (obj *)start_free;
-       }
-#      ifdef _SGI_SOURCE
-         // Try to get memory that's aligned on something like a
-         // cache line boundary, so as to avoid parceling out
-         // parts of the same line to different threads and thus
-         // possibly different processors.
-         {
-           const int cache_line_size = 128;  // probable upper bound
-           bytes_to_get &= ~(cache_line_size-1);
-           start_free = (char *)memalign(cache_line_size, bytes_to_get); 
-           if (0 == start_free) {
-             start_free = (char *)malloc_alloc::allocate(bytes_to_get);
-           }
-         }
-#      else  /* !SGI_SOURCE */
-         start_free = (char *)malloc_alloc::allocate(bytes_to_get);
-#       endif
-       heap_size += bytes_to_get;
-       end_free = start_free + bytes_to_get;
-    }
-  }
-  // lock is released here
-  return(chunk_alloc(size, nobjs));
-}
-
-
-/* Returns an object of size n, and optionally adds to size n free list.*/
-/* We assume that n is properly aligned.                               */
-/* We hold the allocation lock.                                                */
-template <bool dummy>
-void *__pthread_alloc_template<dummy>
-::refill(size_t n)
-{
-    int nobjs = 128;
-    char * chunk = chunk_alloc(n, nobjs);
-    obj * volatile * my_free_list;
-    obj * result;
-    obj * current_obj, * next_obj;
-    int i;
-
-    if (1 == nobjs)  {
-       return(chunk);
-    }
-    my_free_list = free_list + FREELIST_INDEX(n);
-
-    /* Build free list in chunk */
-      result = (obj *)chunk;
-      *my_free_list = next_obj = (obj *)(chunk + n);
-      for (i = 1; ; i++) {
-       current_obj = next_obj;
-       next_obj = (obj *)((char *)next_obj + n);
-       if (nobjs - 1 == i) {
-           current_obj -> free_list_link = 0;
-           break;
-       } else {
-           current_obj -> free_list_link = next_obj;
-       }
-      }
-    return(result);
-}
-
-template <bool dummy>
-void *__pthread_alloc_template<dummy>
-::reallocate(void *p, size_t old_sz, size_t new_sz)
-{
-    void * result;
-    size_t copy_sz;
-
-    if (old_sz > MAX_BYTES && new_sz > MAX_BYTES) {
-       return(realloc(p, new_sz));
-    }
-    if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return(p);
-    result = allocate(new_sz);
-    copy_sz = new_sz > old_sz? old_sz : new_sz;
-    memcpy(result, p, copy_sz);
-    deallocate(p, old_sz);
-    return(result);
-}
-
-template <bool dummy>
-__pthread_alloc_template<dummy> *
-__pthread_alloc_template<dummy>::free_allocators = 0;
-
-template <bool dummy>
-pthread_key_t __pthread_alloc_template<dummy>::key;
-
-template <bool dummy>
-bool __pthread_alloc_template<dummy>::key_initialized = false;
-
-template <bool dummy>
-pthread_mutex_t __pthread_alloc_template<dummy>::chunk_allocator_lock
-= PTHREAD_MUTEX_INITIALIZER;
-
-template <bool dummy>
-char *__pthread_alloc_template<dummy>
-::start_free = 0;
-
-template <bool dummy>
-char *__pthread_alloc_template<dummy>
-::end_free = 0;
-
-template <bool dummy>
-size_t __pthread_alloc_template<dummy>
-::heap_size = 0;
-
-
-#endif /* __NODE_ALLOC_H */
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/queue b/libstdc++/stl/queue
new file mode 100644 (file)
index 0000000..f9417fb
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __SGI_STL_QUEUE
+#define __SGI_STL_QUEUE
+
+#include <stl_algobase.h>
+#include <stl_alloc.h>
+#include <stl_construct.h>
+#include <stl_uninitialized.h>
+#include <stl_vector.h>
+#include <stl_bvector.h>
+#include <stl_heap.h>
+#include <stl_deque.h>
+#include <stl_function.h>
+#include <stl_queue.h>
+
+#endif /* __SGI_STL_QUEUE */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/rope b/libstdc++/stl/rope
new file mode 100644 (file)
index 0000000..9ef7382
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __SGI_STL_ROPE
+#define __SGI_STL_ROPE
+
+#include <stl_algobase.h>
+#include <tempbuf.h>
+#include <stl_algo.h>
+#include <stl_function.h>
+#include <stl_numeric.h>
+#include <stl_alloc.h>
+#include <stl_construct.h>
+#include <stl_uninitialized.h>
+#include <stl_hash_fun.h>
+#include <stl_rope.h>
+
+#endif /* __SGI_STL_ROPE */
+
+// Local Variables:
+// mode:C++
+// End:
index 399352f..d767fa3 100644 (file)
  * purpose.  It is provided "as is" without express or implied warranty.
  */
 
-#ifndef _ROPE_H
-# define _ROPE_H
+#ifndef __SGI_STL_ROPE_H
+#define __SGI_STL_ROPE_H
 
-# include <iterator.h>
-# include <algobase.h>
-# include <algo.h>
-# include <function.h>
-# include <stddef.h>
-# include <alloc.h>
-# include <hashtable.h>
-# ifdef __GC
-#   define __GC_CONST const
-# else
-#   define __GC_CONST   // constant except for deallocation
-# endif
-# ifdef __STL_SGI_THREADS
-#    include <mutex.h>
-# endif
+#include <hashtable.h>
+#include <stl_rope.h>
 
-// The end-of-C-string character.
-// This is what the draft standard says it should be.
-template <class charT>
-inline charT __eos(charT*) { return charT(); }
+#ifdef __STL_USE_NAMESPACES
 
-// Test for basic character types.
-// For basic character types leaves having a trailing eos.
-template <class charT>
-inline bool __is_basic_char_type(charT *) { return false; }
-template <class charT>
-inline bool __is_one_byte_char_type(charT *) { return false; }
+using __STD::char_producer; 
+using __STD::sequence_buffer; 
+using __STD::rope; 
+using __STD::crope; 
+using __STD::wrope; 
 
-inline bool __is_basic_char_type(char *) { return true; }
-inline bool __is_one_byte_char_type(char *) { return true; }
-inline bool __is_basic_char_type(wchar_t *) { return true; }
+#endif /* __STL_USE_NAMESPACES */
 
-// Store an eos iff charT is a basic character type.
-// Do not reference __eos if it isn't.
-template <class charT>
-inline void __cond_store_eos(charT&) {}
+#endif /* __SGI_STL_ROPE_H */
 
-inline void __cond_store_eos(char& c) { c = 0; }
-inline void __cond_store_eos(wchar_t& c) { c = 0; }
-       
-
-// rope<charT,Alloc> is a sequence of charT.
-// Ropes appear to be mutable, but update operations
-// really copy enough of the data structure to leave the original
-// valid.  Thus ropes can be logically copied by just copying
-// a pointer value.
-// The __eos function is used for those functions that
-// convert to/from C-like strings to detect the end of the string.
-// __compare is used as the character comparison function.
-template <class charT>
-class char_producer {
-    public:
-       virtual ~char_producer() {};
-       virtual void operator()(size_t start_pos, size_t len, charT* buffer)
-               = 0;
-       // Buffer should really be an arbitrary output iterator.
-       // That way we could flatten directly into an ostream, etc.
-       // This is thoroughly impossible, since iterator types don't
-       // have runtime descriptions.
-};
-
-// Sequence buffers:
-//
-// Sequence must provide an append operation that appends an
-// array to the sequence.  Sequence buffers are useful only if
-// appending an entire array is cheaper than appending element by element.
-// This is true for many string representations.
-// This should  perhaps inherit from ostream<sequence::value_type>
-// and be implemented correspondingly, so that they can be used
-// for formatted.  For the sake of portability, we don't do this yet.
-//
-// For now, sequence buffers behave as output iterators.  But they also
-// behave a little like basic_ostringstream<sequence::value_type> and a
-// little like containers.
-
-template<class sequence, size_t buf_sz = 100
-#   if defined(__sgi) && !defined(__GNUC__)
-#       define __TYPEDEF_WORKAROUND
-         ,class v = typename sequence::value_type
-#   endif
-        >
-// The 3rd parameter works around a common compiler bug.
-class sequence_buffer : public output_iterator {
-    public:
-#       ifndef __TYPEDEF_WORKAROUND
-           typedef typename sequence::value_type value_type;
-#      else
-           typedef v value_type;
-#      endif
-    protected:
-       sequence *prefix;
-       value_type buffer[buf_sz];
-       size_t buf_count;
-    public:
-       void flush() {
-           prefix->append(buffer, buffer + buf_count);
-           buf_count = 0;
-       }
-       ~sequence_buffer() { flush(); }
-       sequence_buffer() : prefix(0), buf_count(0) {}
-       sequence_buffer(const sequence_buffer & x) {
-           prefix = x.prefix;
-            buf_count = x.buf_count;
-            copy(x.buffer, x.buffer + x.buf_count, buffer);
-       }
-       sequence_buffer(sequence_buffer & x) {
-           x.flush();
-           prefix = x.prefix;
-           buf_count = 0;
-       }
-       sequence_buffer(sequence& s) : prefix(&s), buf_count(0) {}
-       sequence_buffer& operator= (sequence_buffer& x) {
-           x.flush();
-           prefix = x.prefix;
-           buf_count = 0;
-           return *this;
-       }
-       sequence_buffer& operator= (const sequence_buffer& x) {
-           prefix = x.prefix;
-           buf_count = x.buf_count;
-           copy(x.buffer, x.buffer + x.buf_count, buffer);
-           return *this;
-       }
-       void push_back(value_type x)
-       {
-           if (buf_count < buf_sz) {
-               buffer[buf_count] = x;
-               ++buf_count;
-           } else {
-               flush();
-               buffer[0] = x;
-               buf_count = 1;
-           }
-       }
-       void append(value_type *s, size_t len)
-       {
-           if (len + buf_count <= buf_sz) {
-               size_t i, j;
-               for (i = buf_count, j = 0; j < len; i++, j++) {
-                   buffer[i] = s[j];
-               }
-               buf_count += len;
-           } else if (0 == buf_count) {
-               prefix->append(s, s + len);
-           } else {
-               flush();
-               append(s, len);
-           }
-       }
-       sequence_buffer& write(value_type *s, size_t len)
-       {
-           append(s, len);
-           return *this;
-       }
-       sequence_buffer& put(value_type x)
-       {
-           push_back(x);
-           return *this;
-       }
-       sequence_buffer& operator=(const value_type& rhs)
-       {
-           push_back(rhs);
-           return *this;
-       }
-       sequence_buffer& operator*() { return *this; }
-       sequence_buffer& operator++() { return *this; }
-       sequence_buffer& operator++(int) { return *this; }
-};
-
-// The following should be treated as private, at least for now.
-template<class charT>
-class __rope_char_consumer {
-    public:
-       // If we had member templates, these should not be virtual.
-       // For now we need to use run-time parametrization where
-       // compile-time would do.  Hence this should all be private
-       // for now.
-       // The symmetry with char_producer is accidental and temporary.
-       virtual ~__rope_char_consumer() {};
-       virtual bool operator()(const charT* buffer, size_t len) = 0;
-};
-
-//
-// What follows should really be local to rope.  Unfortunately,
-// that doesn't work, since it makes it impossible to define generic
-// equality on rope iterators.  According to the draft standard, the
-// template parameters for such an equality operator cannot be inferred
-// from the occurence of a member class as a parameter.
-// (SGI compilers in fact allow this, but the result wouldn't be
-// portable.)
-// Similarly, some of the static member functions are member functions
-// only to avoid polluting the global namespace, and to circumvent
-// restrictions on type inference for template functions.
-//
-
-template<class CharT, class Alloc=__ALLOC> class rope;
-template<class CharT, class Alloc> struct __rope_RopeConcatenation;
-template<class CharT, class Alloc> struct __rope_RopeLeaf;
-template<class CharT, class Alloc> struct __rope_RopeFunction;
-template<class CharT, class Alloc> struct __rope_RopeSubstring;
-template<class CharT, class Alloc> class __rope_iterator;
-template<class CharT, class Alloc> class __rope_const_iterator;
-template<class CharT, class Alloc> class __rope_charT_ref_proxy;
-template<class CharT, class Alloc> class __rope_charT_ptr_proxy;
-
-//
-// The internal data structure for representing a rope.  This is
-// private to the implementation.  A rope is really just a pointer
-// to one of these.
-//
-// A few basic functions for manipulating this data structure
-// are members of RopeBase.  Most of the more complex algorithms
-// are implemented as rope members.
-//
-// Some of the static member functions of RopeBase have identically
-// named functions in rope that simply invoke the RopeBase versions.
-//
-
-template<class charT, class Alloc>
-struct __rope_RopeBase {
-    typedef rope<charT,Alloc> my_rope;
-    typedef simple_alloc<charT, Alloc> DataAlloc;
-    typedef simple_alloc<__rope_RopeConcatenation<charT,Alloc>, Alloc> CAlloc;
-    typedef simple_alloc<__rope_RopeLeaf<charT,Alloc>, Alloc> LAlloc;
-    typedef simple_alloc<__rope_RopeFunction<charT,Alloc>, Alloc> FAlloc;
-    typedef simple_alloc<__rope_RopeSubstring<charT,Alloc>, Alloc> SAlloc;
-    public:
-    enum { max_rope_depth = 45 };
-    enum {leaf, concat, substringfn, function} tag:8;
-    bool is_balanced:8;
-    unsigned char depth;
-    size_t size;
-    __GC_CONST charT * c_string;
-                       /* Flattened version of string, if needed.  */
-                       /* typically 0.                             */
-                       /* If it's not 0, then the memory is owned  */
-                       /* by this node.                            */
-                       /* In the case of a leaf, this may point to */
-                       /* the same memory as the data field.       */
-#   ifndef __GC
-#       if defined(__STL_WIN32THREADS)
-           long refcount;      // InterlockedIncrement wants a long *
-#      else
-           size_t refcount;
-#      endif
-       // We count references from rope instances
-       // and references from other rope nodes.  We
-       // do not count const_iterator references.
-       // Iterator references are counted so that rope modifications
-       // can be detected after the fact.
-       // Generally function results are counted, i.e.
-       // a pointer returned by a function is included at the
-       // point at which the pointer is returned.
-       // The recipient should decrement the count if the
-       // result is not needed.
-       // Generally function arguments are not reflected
-       // in the reference count.  The callee should increment
-       // the count before saving the argument someplace that
-       // will outlive the call.
-#   endif
-#   ifndef __GC
-#       ifdef __STL_SGI_THREADS
-           // Reference counting with multiple threads and no
-           // hardware or thread package support is pretty awful.
-           // Mutexes are normally too expensive.
-           // We'll assume a COMPARE_AND_SWAP(destp, old, new)
-           // operation, which might be cheaper.
-#           if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64))
-#               define __add_and_fetch(l,v) add_then_test((unsigned long *)l,v)
-#           endif
-           void init_refcount_lock() {}
-           void incr_refcount ()
-           {
-               __add_and_fetch(&refcount, 1);
-           }
-           size_t decr_refcount ()
-           {
-               return __add_and_fetch(&refcount, (size_t)(-1));
-           }
-#       elif defined(__STL_WIN32THREADS)
-           void init_refcount_lock() {}
-            void incr_refcount ()
-            {
-                InterlockedIncrement(&refcount);
-            }
-            size_t decr_refcount ()
-            {
-                return InterlockedDecrement(&refcount);
-            }
-#      elif defined(_PTHREADS)
-           // This should be portable, but performance is expected
-           // to be quite awful.  This really needs platform specific
-           // code.
-           pthread_mutex_t refcount_lock;
-           void init_refcount_lock() {
-               pthread_mutex_init(&refcount_lock, 0);
-           }
-           void incr_refcount ()
-            {   
-               pthread_mutex_lock(&refcount_lock);
-                ++refcount;
-               pthread_mutex_unlock(&refcount_lock);
-            }
-            size_t decr_refcount ()
-            {   
-               size_t result;
-               pthread_mutex_lock(&refcount_lock);
-                result = --refcount;
-               pthread_mutex_unlock(&refcount_lock);
-                return result;
-            }
-#      else
-           void init_refcount_lock() {}
-           void incr_refcount ()
-           {
-               ++refcount;
-           }
-           size_t decr_refcount ()
-           {
-               --refcount;
-               return refcount;
-           }
-#       endif
-#   else
-       void incr_refcount () {}
-#   endif
-       static void free_string(charT *, size_t len);
-                       // Deallocate data section of a leaf.
-                       // This shouldn't be a member function.
-                       // But its hard to do anything else at the
-                       // moment, because it's templatized w.r.t.
-                       // an allocator.
-                       // Does nothing if __GC is defined.
-#   ifndef __GC
-         void free_c_string();
-         void free_tree();
-                       // Deallocate t. Assumes t is not 0.
-         void unref_nonnil()
-         {
-             if (0 == decr_refcount()) free_tree();
-         }
-         void ref_nonnil()
-         {
-             incr_refcount();
-         }
-         static void unref(__rope_RopeBase* t)
-         {
-             if (0 != t) {
-                 t -> unref_nonnil();
-             }
-         }
-         static void ref(__rope_RopeBase* t)
-         {
-             if (0 != t) t -> incr_refcount();
-         }
-         static void free_if_unref(__rope_RopeBase* t)
-         {
-             if (0 != t && 0 == t -> refcount) t -> free_tree();
-         }
-#   else /* __GC */
-         void unref_nonnil() {}
-         void ref_nonnil() {}
-         static void unref(__rope_RopeBase* t) {}
-         static void ref(__rope_RopeBase* t) {}
-         static void fn_finalization_proc(void * tree, void *);
-         static void free_if_unref(__rope_RopeBase* t) {}
-#   endif
-
-    // The data fields of leaves are allocated with some
-    // extra space, to accomodate future growth and for basic
-    // character types, to hold a trailing eos character.
-    enum { alloc_granularity = 8 };
-    static size_t rounded_up_size(size_t n) {
-        size_t size_with_eos;
-            
-        if (__is_basic_char_type((charT *)0)) {
-           size_with_eos = n + 1;
-       } else {
-           size_with_eos = n;
-       }
-#       ifdef __GC
-          return size_with_eos;
-#      else
-          // Allow slop for in-place expansion.
-          return (size_with_eos + alloc_granularity-1)
-                       &~ (alloc_granularity-1);
-#      endif
-    }
-};
-
-template<class charT, class Alloc>
-struct __rope_RopeLeaf : public __rope_RopeBase<charT,Alloc> {
-  public:  // Apparently needed by VC++
-    __GC_CONST charT* data;     /* Not necessarily 0 terminated. */
-                               /* The allocated size is         */
-                               /* rounded_up_size(size), except */
-                               /* in the GC case, in which it   */
-                               /* doesn't matter.               */
-};
-
-template<class charT, class Alloc>
-struct __rope_RopeConcatenation : public __rope_RopeBase<charT,Alloc> {
-  public:
-    __rope_RopeBase<charT,Alloc>* left;
-    __rope_RopeBase<charT,Alloc>* right;
-};
-
-template<class charT, class Alloc>
-struct __rope_RopeFunction : public __rope_RopeBase<charT,Alloc> {
-  public:
-    char_producer<charT>* fn;
-#   ifndef __GC
-      bool delete_when_done;   // Char_producer is owned by the
-                               // rope and should be explicitly
-                               // deleted when the rope becomes
-                               // inaccessible.
-#   else
-      // In the GC case, we either register the rope for
-      // finalization, or not.  Thus the field is unnecessary;
-      // the information is stored in the collector data structures.
-#   endif
-};
-// Substring results are usually represented using just
-// concatenation nodes.  But in the case of very long flat ropes
-// or ropes with a functional representation that isn't practical.
-// In that case, we represent the result as a special case of
-// RopeFunction, whose char_producer points back to the rope itself.
-// In all cases except repeated substring operations and
-// deallocation, we treat the result as a RopeFunction.
-template<class charT, class Alloc>
-struct __rope_RopeSubstring: public __rope_RopeFunction<charT,Alloc>,
-                            public char_producer<charT> {
-  public:
-    __rope_RopeBase<charT,Alloc> * base;       // not 0
-    size_t start;
-    virtual ~__rope_RopeSubstring() {}
-    virtual void operator()(size_t start_pos, size_t req_len,
-                           charT *buffer) {
-       switch(base -> tag) {
-           case function:
-           case substringfn:
-             {
-               char_producer<charT> *fn =
-                       ((__rope_RopeFunction<charT,Alloc> *)base) -> fn;
-               __stl_assert(start_pos + req_len <= size);
-               __stl_assert(start + size <= base -> size);
-               (*fn)(start_pos + start, req_len, buffer);
-             }
-             break;
-           case leaf:
-             {
-               __GC_CONST charT * s =
-                       ((__rope_RopeLeaf<charT,Alloc> *)base) -> data;
-               uninitialized_copy_n(s + start_pos + start, req_len,
-                                    buffer);
-             }
-             break;
-           default:
-             __stl_assert(false);
-       }
-    }
-    __rope_RopeSubstring(__rope_RopeBase<charT,Alloc> * b, size_t s, size_t l) :
-       base(b), start(s) {
-#       ifndef __GC
-           refcount = 1;
-           init_refcount_lock();
-           base -> ref_nonnil();
-#       endif
-       size = l;
-       tag = substringfn;
-       depth = 0;
-       c_string = 0;
-       fn = this;
-    }
-};
-
-
-// Self-destructing pointers to RopeBase.
-// These are not conventional smart pointers.  Their
-// only purpose in life is to ensure that unref is called
-// on the pointer either at normal exit or if an exception
-// is raised.  It is the caller's responsibility to
-// adjust reference counts when these pointers are initialized
-// or assigned to.  (This convention significantly reduces
-// the number of potentially expensive reference count
-// updates.)
-#ifndef __GC
-  template<class charT, class Alloc>
-  struct __rope_self_destruct_ptr {
-    __rope_RopeBase<charT,Alloc> * ptr;
-    ~__rope_self_destruct_ptr() { __rope_RopeBase<charT,Alloc>::unref(ptr); }
-#   ifdef __STL_USE_EXCEPTIONS
-       __rope_self_destruct_ptr() : ptr(0) {};
-#   else
-       __rope_self_destruct_ptr() {};
-#   endif
-    __rope_self_destruct_ptr(__rope_RopeBase<charT,Alloc> * p) : ptr(p) {}
-    __rope_RopeBase<charT,Alloc> & operator*() { return *ptr; }
-    __rope_RopeBase<charT,Alloc> * operator->() { return ptr; }
-    operator __rope_RopeBase<charT,Alloc> *() { return ptr; }
-    __rope_self_destruct_ptr & operator= (__rope_RopeBase<charT,Alloc> * x)
-       { ptr = x; return *this; }
-  };
-#endif
-
-// unwind-protect
-#      ifdef __STL_USE_EXCEPTIONS
-#          define __STL_TRY try {
-#          define __STL_UNWIND(action) } catch(...) { action; throw; }
-#           define __STL_ALWAYS(action) action; } catch(...) { action; throw; }
-#       else
-#          define __STL_TRY {
-#          define __STL_UNWIND(action) }
-#           define __STL_ALWAYS(action) action; }
-#      endif
-// Dereferencing a nonconst iterator has to return something
-// that behaves almost like a reference.  It's not possible to
-// return an actual reference since assignment requires extra
-// work.  And we would get into the same problems as with the
-// CD2 version of basic_string.
-template<class charT, class Alloc>
-class __rope_charT_ref_proxy {
-    friend class rope<charT,Alloc>;
-    friend class __rope_iterator<charT,Alloc>;
-    friend class __rope_charT_ptr_proxy<charT,Alloc>;
-#   ifdef __GC
-       typedef __rope_RopeBase<charT,Alloc> * self_destruct_ptr;
-#   else
-       typedef __rope_self_destruct_ptr<charT,Alloc> self_destruct_ptr;
-#   endif
-    typedef __rope_RopeBase<charT,Alloc> RopeBase;
-    typedef rope<charT,Alloc> my_rope;
-    size_t pos;
-    charT current;
-    bool current_valid;
-    my_rope * root;     // The whole rope.
-  public:
-    __rope_charT_ref_proxy(my_rope * r, size_t p) :
-       pos(p), root(r), current_valid(false) {}
-    __rope_charT_ref_proxy(my_rope * r, size_t p,
-                   charT c) :
-       pos(p), root(r), current(c), current_valid(true) {}
-    operator charT () const;
-    __rope_charT_ref_proxy& operator= (charT c);
-    __rope_charT_ptr_proxy<charT,Alloc> operator& () const;
-    __rope_charT_ref_proxy& operator= (const __rope_charT_ref_proxy& c) {
-       return operator=((charT)c); 
-    }
-};
-
-template<class charT, class Alloc>
-class __rope_charT_ptr_proxy {
-    friend class __rope_charT_ref_proxy<charT,Alloc>;
-    size_t pos;
-    charT current;
-    bool current_valid;
-    rope<charT,Alloc> * root;     // The whole rope.
-  public:
-    __rope_charT_ptr_proxy(const __rope_charT_ref_proxy<charT,Alloc> & x) :
-       pos(x.pos), root(x.root), current_valid(x.current_valid),
-       current(x.current) {}
-    __rope_charT_ptr_proxy(const __rope_charT_ptr_proxy & x) :
-       pos(x.pos), root(x.root), current_valid(x.current_valid),
-       current(x.current) {}
-    __rope_charT_ptr_proxy() {}
-    __rope_charT_ptr_proxy(charT * x) : root(0), pos(0) {
-       __stl_assert(0 == x);
-    }
-    __rope_charT_ptr_proxy& operator= (const __rope_charT_ptr_proxy& x) {
-       pos = x.pos;
-       current = x.current;
-       current_valid = x.current_valid;
-       root = x.root;
-       return *this;
-    }
-    friend bool operator==
-                (const __rope_charT_ptr_proxy<charT,Alloc> & x,
-                 const __rope_charT_ptr_proxy<charT,Alloc> & y);
-    __rope_charT_ref_proxy<charT,Alloc> operator *() const {
-       if (current_valid) {
-           return __rope_charT_ref_proxy<charT,Alloc>(root, pos, current);
-       } else {
-           return __rope_charT_ref_proxy<charT,Alloc>(root, pos);
-       }
-    }
-};
-
-// Rope iterators:
-// Unlike in the C version, we cache only part of the stack
-// for rope iterators, since they must be efficiently copyable.
-// When we run out of cache, we have to reconstruct the iterator
-// value.
-// Pointers from iterators are not included in reference counts.
-// Iterators are assumed to be thread private.  Ropes can
-// be shared.
-
-template<class charT, class Alloc>
-class __rope_iterator_base:
-  public random_access_iterator<charT, ptrdiff_t> {
-  friend class rope<charT, Alloc>;
-  public:
-    typedef __rope_RopeBase<charT,Alloc> RopeBase;
-       // Borland doesnt want this to be protected.
-  protected:
-    enum { path_cache_len = 4 }; // Must be <= 9.
-    enum { iterator_buf_len = 15 };
-    size_t current_pos;
-    RopeBase * root;     // The whole rope.
-    size_t leaf_pos;    // Starting position for current leaf
-    __GC_CONST charT * buf_start;
-                       // Buffer possibly
-                       // containing current char.
-    __GC_CONST charT * buf_ptr;
-                       // Pointer to current char in buffer.
-                       // != 0 ==> buffer valid.
-    __GC_CONST charT * buf_end;
-                       // One past last valid char in buffer.
-    // What follows is the path cache.  We go out of our
-    // way to make this compact.
-    // Path_end contains the bottom section of the path from
-    // the root to the current leaf.
-    const RopeBase * path_end[path_cache_len];
-    int leaf_index;     // Last valid pos in path_end;
-                       // path_end[0] ... path_end[leaf_index-1]
-                       // point to concatenation nodes.
-    unsigned char path_directions;
-                         // (path_directions >> i) & 1 is 1
-                         // iff we got from path_end[leaf_index - i - 1]
-                         // to path_end[leaf_index - i] by going to the
-                         // right. Assumes path_cache_len <= 9.
-    charT tmp_buf[iterator_buf_len];
-                       // Short buffer for surrounding chars.
-                       // This is useful primarily for 
-                       // RopeFunctions.  We put the buffer
-                       // here to avoid locking in the
-                       // multithreaded case.
-    // The cached path is generally assumed to be valid
-    // only if the buffer is valid.
-    static void setbuf(__rope_iterator_base &x);
-                                       // Set buffer contents given
-                                       // path cache.
-    static void setcache(__rope_iterator_base &x);
-                                       // Set buffer contents and
-                                       // path cache.
-    static void setcache_for_incr(__rope_iterator_base &x);
-                                       // As above, but assumes path
-                                       // cache is valid for previous posn.
-    __rope_iterator_base() {}
-    __rope_iterator_base(RopeBase * root, size_t pos):
-                  root(root), current_pos(pos), buf_ptr(0) {}
-    __rope_iterator_base(const __rope_iterator_base& x) {
-       if (0 != x.buf_ptr) {
-           *this = x;
-       } else {
-           current_pos = x.current_pos;
-           root = x.root;
-           buf_ptr = 0;
-       }
-    }
-    void incr(size_t n);
-    void decr(size_t n);
-  public:
-    size_t index() const { return current_pos; }
-};
-
-template<class charT, class Alloc> class __rope_iterator;
-
-template<class charT, class Alloc>
-class __rope_const_iterator : public __rope_iterator_base<charT,Alloc> {
-    friend class rope<charT,Alloc>;
-  protected:
-    __rope_const_iterator(const RopeBase * root, size_t pos):
-                  __rope_iterator_base<charT,Alloc>(
-                    const_cast<RopeBase *>(root), pos)
-                  // Only nonconst iterators modify root ref count
-    {}
-  public:
-    typedef charT reference;    // Really a value.  Returning a reference
-                               // Would be a mess, since it would have
-                               // to be included in refcount.
-    typedef const charT* pointer;
-
-  public:
-    __rope_const_iterator() {};
-    __rope_const_iterator(const __rope_const_iterator & x) :
-                               __rope_iterator_base<charT,Alloc>(x) { }
-    __rope_const_iterator(const __rope_iterator<charT,Alloc> & x);
-    __rope_const_iterator(const rope<charT,Alloc> &r, size_t pos) :
-       __rope_iterator_base<charT,Alloc>(r.tree_ptr, pos) {}
-    __rope_const_iterator& operator= (const __rope_const_iterator & x) {
-       if (0 != x.buf_ptr) {
-           *this = x;
-       } else {
-           current_pos = x.current_pos;
-           root = x.root;
-           buf_ptr = 0;
-       }
-       return(*this);
-    }
-    reference operator*() {
-       if (0 == buf_ptr) setcache(*this);
-       return *buf_ptr;
-    }
-    __rope_const_iterator& operator++() {
-       __GC_CONST charT * next;
-       if (0 != buf_ptr && (next = buf_ptr + 1) < buf_end) {
-           buf_ptr = next;
-           ++current_pos;
-       } else {
-           incr(1);
-       }
-       return *this;
-    }
-    __rope_const_iterator& operator+=(ptrdiff_t n) {
-       if (n >= 0) {
-           incr(n);
-       } else {
-           decr(-n);
-       }
-       return *this;
-    }
-    __rope_const_iterator& operator--() {
-       decr(1);
-       return *this;
-    }
-    __rope_const_iterator& operator-=(ptrdiff_t n) {
-       if (n >= 0) {
-           decr(n);
-       } else {
-           incr(-n);
-       }
-       return *this;
-    }
-    __rope_const_iterator operator++(int) {
-       size_t old_pos = current_pos;
-       incr(1);
-       return __rope_const_iterator<charT,Alloc>(root, old_pos);
-       // This makes a subsequent dereference expensive.
-       // Perhaps we should instead copy the iterator
-       // if it has a valid cache?
-    }
-    __rope_const_iterator operator--(int) {
-       size_t old_pos = current_pos;
-       decr(1);
-       return __rope_const_iterator<charT,Alloc>(root, old_pos);
-    }
-    friend __rope_const_iterator<charT,Alloc> operator-
-       (const __rope_const_iterator<charT,Alloc> & x,
-        ptrdiff_t n);
-    friend __rope_const_iterator<charT,Alloc> operator+
-       (const __rope_const_iterator<charT,Alloc> & x,
-        ptrdiff_t n);
-    friend __rope_const_iterator<charT,Alloc> operator+
-       (ptrdiff_t n,
-        const __rope_const_iterator<charT,Alloc> & x);
-    reference operator[](size_t n) {
-       return rope<charT,Alloc>::fetch(root, current_pos + n);
-    }
-    friend bool operator==
-       (const __rope_const_iterator<charT,Alloc> & x,
-        const __rope_const_iterator<charT,Alloc> & y);
-    friend bool operator<
-       (const __rope_const_iterator<charT,Alloc> & x,
-        const __rope_const_iterator<charT,Alloc> & y);
-    friend ptrdiff_t operator-
-       (const __rope_const_iterator<charT,Alloc> & x,
-        const __rope_const_iterator<charT,Alloc> & y);
-};
-
-template<class charT, class Alloc>
-class __rope_iterator : public __rope_iterator_base<charT,Alloc> {
-    friend class rope<charT,Alloc>;
-  protected:
-    rope<charT,Alloc> * root_rope;
-       // root is treated as a cached version of this,
-       // and is used to detect changes to the underlying
-       // rope.
-       // Root is included in the reference count.
-       // This is necessary so that we can detect changes reliably.
-       // Unfortunately, it requires careful bookkeeping for the
-       // nonGC case.
-    __rope_iterator(rope<charT,Alloc> * r, size_t pos):
-            __rope_iterator_base<charT,Alloc>(r -> tree_ptr, pos),
-            root_rope(r) {
-               RopeBase::ref(root);
-            }
-    void check();
-  public:
-    typedef __rope_charT_ref_proxy<charT,Alloc>  reference;
-    typedef __rope_charT_ref_proxy<charT,Alloc>* pointer;
-
-  public:
-    rope<charT,Alloc>& container() { return *root_rope; }
-    __rope_iterator() {
-       root = 0;  // Needed for reference counting.
-    };
-    __rope_iterator(const __rope_iterator & x) :
-       __rope_iterator_base<charT,Alloc>(x) {
-       root_rope = x.root_rope;
-       RopeBase::ref(root);
-    }
-    __rope_iterator(rope<charT,Alloc>& r, size_t pos);
-    ~__rope_iterator() {
-       RopeBase::unref(root);
-    }
-    __rope_iterator& operator= (const __rope_iterator & x) {
-       RopeBase *old = root;
-
-       RopeBase::ref(x.root);
-       if (0 != x.buf_ptr) {
-           *this = x;
-       } else {
-           current_pos = x.current_pos;
-           root = x.root;
-           root_rope = x.root_rope;
-           buf_ptr = 0;
-       }
-       RopeBase::unref(old);
-       return(*this);
-    }
-    reference operator*() {
-       check();
-       if (0 == buf_ptr) {
-           return __rope_charT_ref_proxy<charT,Alloc>(root_rope, current_pos);
-       } else {
-           return __rope_charT_ref_proxy<charT,Alloc>(root_rope,
-                                                      current_pos, *buf_ptr);
-       }
-    }
-    __rope_iterator& operator++() {
-       incr(1);
-       return *this;
-    }
-    __rope_iterator& operator+=(difference_type n) {
-       if (n >= 0) {
-           incr(n);
-       } else {
-           decr(-n);
-       }
-       return *this;
-    }
-    __rope_iterator& operator--() {
-       decr(1);
-       return *this;
-    }
-    __rope_iterator& operator-=(difference_type n) {
-       if (n >= 0) {
-           decr(n);
-       } else {
-           incr(-n);
-       }
-       return *this;
-    }
-    __rope_iterator operator++(int) {
-       size_t old_pos = current_pos;
-       incr(1);
-       return __rope_iterator<charT,Alloc>(root_rope, old_pos);
-    }
-    __rope_iterator operator--(int) {
-       size_t old_pos = current_pos;
-       decr(1);
-       return __rope_iterator<charT,Alloc>(root_rope, old_pos);
-    }
-    reference operator[](ptrdiff_t n) {
-       return __rope_charT_ref_proxy<charT,Alloc>(root_rope, current_pos + n);
-    }
-    friend bool operator==
-       (const __rope_iterator<charT,Alloc> & x,
-        const __rope_iterator<charT,Alloc> & y);
-    friend bool operator<
-       (const __rope_iterator<charT,Alloc> & x,
-        const __rope_iterator<charT,Alloc> & y);
-    friend ptrdiff_t operator-
-       (const __rope_iterator<charT,Alloc> & x,
-        const __rope_iterator<charT,Alloc> & y);
-    friend __rope_iterator<charT,Alloc> operator-
-       (const __rope_iterator<charT,Alloc> & x,
-        ptrdiff_t n);
-    friend __rope_iterator<charT,Alloc> operator+
-       (const __rope_iterator<charT,Alloc> & x,
-        ptrdiff_t n);
-    friend __rope_iterator<charT,Alloc> operator+
-       (ptrdiff_t n,
-        const __rope_iterator<charT,Alloc> & x);
-
-};
-
-template <class charT, class Alloc>
-class rope {
-    public:
-       typedef charT value_type;
-       typedef ptrdiff_t difference_type;
-       typedef size_t size_type;
-       typedef charT const_reference;
-       typedef const charT* const_pointer;
-       typedef __rope_iterator<charT,Alloc> iterator;
-       typedef __rope_const_iterator<charT,Alloc> const_iterator;
-       typedef __rope_charT_ref_proxy<charT,Alloc> reference;
-       typedef __rope_charT_ptr_proxy<charT,Alloc> pointer;
-
-       friend class __rope_iterator<charT,Alloc>;
-       friend class __rope_const_iterator<charT,Alloc>;
-       friend struct __rope_RopeBase<charT,Alloc>;
-       friend class __rope_iterator_base<charT,Alloc>;
-       friend class __rope_charT_ptr_proxy<charT,Alloc>;
-       friend class __rope_charT_ref_proxy<charT,Alloc>;
-       friend struct __rope_RopeSubstring<charT,Alloc>;
-
-    protected:
-       typedef __GC_CONST charT * cstrptr;
-#       ifdef __STL_SGI_THREADS
-           static cstrptr atomic_swap(cstrptr *p, cstrptr q) {
-#               if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64))
-                    return (cstrptr) test_and_set((unsigned long *)p,
-                                                 (unsigned long)q);
-#              else
-                    return (cstrptr) __test_and_set((unsigned long *)p,
-                                                   (unsigned long)q);
-#              endif
-            }
-#       elif defined(__STL_WIN32THREADS)
-           static cstrptr atomic_swap(cstrptr *p, cstrptr q) {
-               return (cstrptr) InterlockedExchange((LPLONG)p, (LONG)q);
-           }
-#      elif defined(_PTHREADS)
-           // This should be portable, but performance is expected
-           // to be quite awful.  This really needs platform specific
-           // code.
-           static pthread_mutex_t swap_lock;
-           static cstrptr atomic_swap(cstrptr *p, cstrptr q) {
-               pthread_mutex_lock(&swap_lock);
-               cstrptr result = *p;
-               *p = q;
-               pthread_mutex_unlock(&swap_lock);
-               return result;
-            }
-#      else
-           static cstrptr atomic_swap(cstrptr *p, cstrptr q) {
-                cstrptr result = *p;
-                *p = q;
-               return result;
-           }
-#       endif
-
-       static charT empty_c_str[1];
-
-       typedef simple_alloc<charT, Alloc> DataAlloc;
-       typedef simple_alloc<__rope_RopeConcatenation<charT,Alloc>, Alloc> CAlloc;
-       typedef simple_alloc<__rope_RopeLeaf<charT,Alloc>, Alloc> LAlloc;
-       typedef simple_alloc<__rope_RopeFunction<charT,Alloc>, Alloc> FAlloc;
-       typedef simple_alloc<__rope_RopeSubstring<charT,Alloc>, Alloc> SAlloc;
-       static bool is0(charT c) { return c == __eos((charT *)0); }
-       enum { copy_max = 23 };
-               // For strings shorter than copy_max, we copy to
-               // concatenate.
-
-       typedef __rope_RopeBase<charT,Alloc> RopeBase;
-       typedef __rope_RopeConcatenation<charT,Alloc> RopeConcatenation;
-       typedef __rope_RopeLeaf<charT,Alloc> RopeLeaf;
-       typedef __rope_RopeFunction<charT,Alloc> RopeFunction;
-       typedef __rope_RopeSubstring<charT,Alloc> RopeSubstring;
-
-       // The only data member of a rope:
-       RopeBase *tree_ptr;
-
-       // Retrieve a character at the indicated position.
-       static charT fetch(RopeBase * r, size_type pos);
-
-#      ifndef __GC
-           // Obtain a pointer to the character at the indicated position.
-           // The pointer can be used to change the character.
-           // If such a pointer cannot be produced, as is frequently the
-           // case, 0 is returned instead.
-           // (Returns nonzero only if all nodes in the path have a refcount
-           // of 1.)
-           static charT * fetch_ptr(RopeBase * r, size_type pos);
-#      endif
-
-       static bool apply_to_pieces(
-                               // should be template parameter
-                               __rope_char_consumer<charT>& c,
-                               const RopeBase * r,
-                               size_t begin, size_t end);
-                               // begin and end are assumed to be in range.
-
-#      ifndef __GC
-         static void unref(RopeBase* t)
-         {
-             RopeBase::unref(t);
-         }
-         static void ref(RopeBase* t)
-         {
-             RopeBase::ref(t);
-         }
-#       else /* __GC */
-         static void unref(RopeBase* t) {}
-         static void ref(RopeBase* t) {}
-#       endif
-
-
-#       ifdef __GC
-           typedef __rope_RopeBase<charT,Alloc> * self_destruct_ptr;
-#      else
-           typedef __rope_self_destruct_ptr<charT,Alloc> self_destruct_ptr;
-#      endif
-
-       // Result is counted in refcount.
-       static RopeBase * substring(RopeBase * base,
-                                   size_t start, size_t endp1);
-
-       static RopeBase * concat_char_iter(RopeBase * r,
-                                         const charT *iter, size_t slen);
-               // Concatenate rope and char ptr, copying s.
-               // Should really take an arbitrary iterator.
-               // Result is counted in refcount.
-       static RopeBase * destr_concat_char_iter(RopeBase * r,
-                                                const charT *iter, size_t slen)
-               // As above, but one reference to r is about to be
-               // destroyed.  Thus the pieces may be recycled if all
-               // relevent reference counts are 1.
-#          ifdef __GC
-               // We can't really do anything since refcounts are unavailable.
-               { return concat_char_iter(r, iter, slen); }
-#          else
-               ;
-#          endif
-
-       static RopeBase * concat(RopeBase *left, RopeBase *right);
-               // General concatenation on RopeBase.  Result
-               // has refcount of 1.  Adjusts argument refcounts.
-
-   public:
-       void apply_to_pieces( size_t begin, size_t end,
-                             __rope_char_consumer<charT>& c) const {
-           apply_to_pieces(c, tree_ptr, begin, end);
-       }
-
-
-   protected:
-
-       static size_t rounded_up_size(size_t n) {
-           return RopeBase::rounded_up_size(n);
-       }
-
-       static size_t allocated_capacity(size_t n) {
-           if (__is_basic_char_type((charT *)0)) {
-               return rounded_up_size(n) - 1;
-           } else {
-               return rounded_up_size(n);
-           }
-       }
-               
-       // s should really be an arbitrary input iterator.
-       // Adds a trailing NULL for basic char types.
-       static charT * alloc_copy(const charT *s, size_t size)
-       {
-           charT * result = DataAlloc::allocate(rounded_up_size(size));
-
-           uninitialized_copy_n(s, size, result);
-           __cond_store_eos(result[size]);
-           return(result);
-       }
-
-       // Basic constructors for rope tree nodes.
-       // These return tree nodes with a 0 reference count.
-       static RopeLeaf * RopeLeaf_from_char_ptr(__GC_CONST charT *s,
-                                                size_t size);
-               // Takes ownership of its argument.
-               // Result has refcount 1.
-               // In the nonGC, basic_char_type  case it assumes that s
-               // is eos-terminated.
-               // In the nonGC case, it was allocated from Alloc with
-               // rounded_up_size(size).
-
-       static RopeLeaf * RopeLeaf_from_unowned_char_ptr(const charT *s,
-                                                        size_t size) {
-           charT * buf = alloc_copy(s, size);
-            __STL_TRY
-              return RopeLeaf_from_char_ptr(buf, size);
-            __STL_UNWIND(RopeBase::free_string(buf, size))
-       }
-           
-
-       // Concatenation of nonempty strings.
-       // Always builds a concatenation node.
-       // Rebalances if the result is too deep.
-       // Result has refcount 1.
-       // Does not increment left and right ref counts even though
-       // they are referenced.
-       static RopeBase * tree_concat(RopeBase * left, RopeBase * right);
-
-       // Result has refcount 1.
-       // If delete_fn is true, then fn is deleted when the rope
-       // becomes inaccessible.
-       static RopeFunction * RopeFunction_from_fn
-                       (char_producer<charT> *fn, size_t size,
-                        bool delete_fn);
-
-       // Concatenation helper functions
-       static RopeLeaf * leaf_concat_char_iter
-                       (RopeLeaf * r, const charT * iter, size_t slen);
-               // Concatenate by copying leaf.
-               // should take an arbitrary iterator
-               // result has refcount 1.
-#      ifndef __GC
-         static RopeLeaf * destr_leaf_concat_char_iter
-                       (RopeLeaf * r, const charT * iter, size_t slen);
-         // A version that potentially clobbers r if r -> refcount == 1.
-#       endif
-
-       // A helper function for exponentiating strings.
-       // This uses a nonstandard refcount convention.
-       // The result has refcount 0.
-       struct concat_fn;
-       friend struct rope<charT,Alloc>::concat_fn;
-
-       struct concat_fn
-               : binary_function<rope<charT,Alloc>, rope<charT,Alloc>,
-                                 rope<charT,Alloc> > {
-               rope operator() (const rope& x, const rope& y) {
-                   return x + y;
-               }
-       };
-
-        friend rope identity_element(concat_fn) { return rope<charT,Alloc>(); }
-
-       static size_t char_ptr_len(const charT * s);
-                       // slightly generalized strlen
-
-       rope(RopeBase *t) : tree_ptr(t) { }
-
-
-       // Copy r to the CharT buffer.
-       // Returns buffer + r -> size.
-       // Assumes that buffer is uninitialized.
-       static charT * flatten(RopeBase * r, charT * buffer);
-
-       // Again, with explicit starting position and length.
-       // Assumes that buffer is uninitialized.
-       static charT * flatten(RopeBase * r,
-                              size_t start, size_t len,
-                              charT * buffer);
-
-       static const unsigned long min_len[RopeBase::max_rope_depth + 1];
-
-       static bool is_balanced(RopeBase *r)
-               { return (r -> size >= min_len[r -> depth]); }
-
-       static bool is_almost_balanced(RopeBase *r)
-               { return (r -> depth == 0 ||
-                         r -> size >= min_len[r -> depth - 1]); }
-
-       static bool is_roughly_balanced(RopeBase *r)
-               { return (r -> depth <= 1 ||
-                         r -> size >= min_len[r -> depth - 2]); }
-
-       // Assumes the result is not empty.
-       static RopeBase * concat_and_set_balanced(RopeBase *left,
-                                                 RopeBase *right)
-       {
-           RopeBase * result = concat(left, right);
-           if (is_balanced(result)) result -> is_balanced = true;
-           return result;
-       }
-
-       // The basic rebalancing operation.  Logically copies the
-       // rope.  The result has refcount of 1.  The client will
-       // usually decrement the reference count of r.
-       // The result isd within height 2 of balanced by the above
-       // definition.
-       static RopeBase * balance(RopeBase * r);
-
-       // Add all unbalanced subtrees to the forest of balanceed trees.
-       // Used only by balance.
-       static void add_to_forest(RopeBase *r, RopeBase **forest);
-       
-       // Add r to forest, assuming r is already balanced.
-       static void add_leaf_to_forest(RopeBase *r, RopeBase **forest);
-
-       // Print to stdout, exposing structure
-       static void dump(RopeBase * r, int indent = 0);
-
-       // Return -1, 0, or 1 if x < y, x == y, or x > y resp.
-       static int compare(const RopeBase *x, const RopeBase *y);
-
-   public:
-       bool empty() const { return 0 == tree_ptr; }
-
-       // Comparison member function.  This is public only for those
-       // clients that need a ternary comparison.  Others
-       // should use the comparison operators below.
-       int compare(const rope &y) const {
-           return compare(tree_ptr, y.tree_ptr);
-       }
-
-       rope(const charT *s)
-       {
-           size_t len = char_ptr_len(s);
-
-           if (0 == len) {
-               tree_ptr = 0;
-           } else {
-               tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len);
-#              ifndef __GC
-                 __stl_assert(1 == tree_ptr -> refcount);
-#              endif
-           }
-       }
-
-       rope(const charT *s, size_t len)
-       {
-           if (0 == len) {
-               tree_ptr = 0;
-           } else {
-               tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len);
-           }
-       }
-
-       rope(const charT *s, charT *e)
-       {
-           size_t len = e - s;
-
-           if (0 == len) {
-               tree_ptr = 0;
-           } else {
-               tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len);
-           }
-       }
-
-       rope(const const_iterator& s, const const_iterator& e)
-       {
-           tree_ptr = substring(s.root, s.current_pos, e.current_pos);
-       }
-
-       rope(const iterator& s, const iterator& e)
-       {
-           tree_ptr = substring(s.root, s.current_pos, e.current_pos);
-       }
-
-       rope(charT c)
-       {
-           charT * buf = DataAlloc::allocate(rounded_up_size(1));
-
-           construct(buf, c);
-           __STL_TRY
-               tree_ptr = RopeLeaf_from_char_ptr(buf, 1);
-            __STL_UNWIND(RopeBase::free_string(buf, 1))
-       }
-
-       rope(size_t n, charT c);
-
-       // Should really be templatized with respect to the iterator type
-       // and use sequence_buffer.  (It should perhaps use sequence_buffer
-       // even now.)
-       rope(const charT *i, const charT *j)
-       {
-           if (i == j) {
-               tree_ptr = 0;
-           } else {
-               size_t len = j - i;
-               tree_ptr = RopeLeaf_from_unowned_char_ptr(i, len);
-           }
-       }
-
-       rope()
-       {
-           tree_ptr = 0;
-       }
-
-       // Construct a rope from a function that can compute its members
-       rope(char_producer<charT> *fn, size_t len, bool delete_fn)
-       {
-           tree_ptr = RopeFunction_from_fn(fn, len, delete_fn);
-       }
-
-       rope(const rope &x)
-       {
-           tree_ptr = x.tree_ptr;
-           ref(tree_ptr);
-       }
-
-       ~rope()
-       {
-           unref(tree_ptr);
-       }
-
-       rope& operator=(const rope& x)
-       {
-           RopeBase *old = tree_ptr;
-           tree_ptr = x.tree_ptr;
-           ref(tree_ptr);
-           unref(old);
-           return(*this);
-       }
-
-       void push_back(charT x)
-       {
-           RopeBase *old = tree_ptr;
-           tree_ptr = concat_char_iter(tree_ptr, &x, 1);
-           unref(old);
-       }
-
-       void pop_back()
-       {
-           RopeBase *old = tree_ptr;
-           tree_ptr = substring(tree_ptr, 0, tree_ptr -> size - 1);
-           unref(old);
-       }
-
-       charT back() const
-       {
-           return fetch(tree_ptr, tree_ptr -> size - 1);
-       }
-
-       void push_front(charT x)
-       {
-           RopeBase *old = tree_ptr;
-           RopeBase *left;
-
-           left = RopeLeaf_from_unowned_char_ptr(&x, 1);
-           __STL_TRY
-             tree_ptr = concat(left, tree_ptr);
-             unref(old);
-           __STL_ALWAYS(unref(left))
-       }
-
-       void pop_front()
-       {
-           RopeBase *old = tree_ptr;
-           tree_ptr = substring(tree_ptr, 1, tree_ptr -> size);
-           unref(old);
-       }
-
-       charT front() const
-       {
-           return fetch(tree_ptr, 0);
-       }
-
-       void balance()
-       {
-           RopeBase *old = tree_ptr;
-           tree_ptr = balance(tree_ptr);
-           unref(old);
-       }
-
-       void copy(charT * buffer) const {
-           destroy(buffer, buffer + size());
-           flatten(tree_ptr, buffer);
-       }
-
-       // This is the copy function from the standard, but
-       // with the arguments reordered to make it consistent with the
-       // rest of the interface.
-       // Note that this guaranteed not to compile if the draft standard
-       // order is assumed.
-       size_type copy(size_type pos, size_type n, charT *buffer) const {
-           size_t sz = size();
-           size_t len = (pos + n > sz? sz - pos : n);
-
-           destroy(buffer, buffer + len);
-           flatten(tree_ptr, pos, len, buffer);
-           return len;
-       }
-
-       // Print to stdout, exposing structure.  May be useful for
-       // performance debugging.
-       void dump() {
-           dump(tree_ptr);
-       }
-
-       // Convert to 0 terminated string in new allocated memory.
-       // Embedded 0s in the input do not terminate the copy.
-       const charT * c_str() const;
-
-       // As above, but lso use the flattened representation as the
-       // the new rope representation.
-       const charT * replace_with_c_str();
-
-       // Reclaim memory for the c_str generated flattened string.
-       // Intentionally undocumented, since it's hard to say when this
-       // is safe for multiple threads.
-       void delete_c_str () {
-           if (0 == tree_ptr) return;
-           if (RopeBase::leaf == tree_ptr -> tag
-               && ((RopeLeaf *)tree_ptr) -> data == tree_ptr -> c_string) {
-               // Representation shared
-               return;
-           }
-#          ifndef __GC
-             tree_ptr -> free_c_string();
-#          endif
-           tree_ptr -> c_string = 0;
-       }
-
-       charT operator[] (size_type pos) const {
-           return fetch(tree_ptr, pos);
-       }
-
-       charT at(size_type pos) const {
-          // if (pos >= size()) throw out_of_range;
-          return (*this)[pos];
-       }
-
-       const_iterator begin() const {
-           return(const_iterator(tree_ptr, 0));
-       }
-
-       // An easy way to get a const iterator from a non-const container.
-       const_iterator const_begin() const {
-           return(const_iterator(tree_ptr, 0));
-       }
-
-       const_iterator end() const {
-           return(const_iterator(tree_ptr, size()));
-       }
-
-       const_iterator const_end() const {
-           return(const_iterator(tree_ptr, size()));
-       }
-
-       size_type size() const { 
-           return(0 == tree_ptr? 0 : tree_ptr -> size);
-       }
-
-       size_type length() const {
-           return size();
-       }
-
-       size_type max_size() const {
-           return min_len[RopeBase::max_rope_depth-1] - 1;
-           //  Guarantees that the result can be sufficirntly
-           //  balanced.  Longer ropes will probably still work,
-           //  but it's harder to make guarantees.
-       }
-
-#     ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
-        typedef reverse_iterator<const_iterator> const_reverse_iterator;
-#     else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-       typedef reverse_iterator<const_iterator, value_type, const_reference,
-                                difference_type>  const_reverse_iterator;
-#     endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 
-
-       const_reverse_iterator rbegin() const {
-           return const_reverse_iterator(end());
-       }
-
-       const_reverse_iterator const_rbegin() const {
-           return const_reverse_iterator(end());
-       }
-
-       const_reverse_iterator rend() const {
-           return const_reverse_iterator(begin());
-       }
-
-       const_reverse_iterator const_rend() const {
-           return const_reverse_iterator(begin());
-       }
-
-       friend rope<charT,Alloc> operator+ (const rope<charT,Alloc> &left,
-                                           const rope<charT,Alloc> &right);
-       
-       friend rope<charT,Alloc> operator+ (const rope<charT,Alloc> &left,
-                                           const charT* right);
-       
-       friend rope<charT,Alloc> operator+ (const rope<charT,Alloc> &left,
-                                           charT right);
-       
-       // The symmetric cases are intentionally omitted, since they're presumed
-       // to be less common, and we don't handle them as well.
-
-       // The following should really be templatized.
-       // The first argument should be an input iterator or
-       // forward iterator with value_type charT.
-       rope& append(const charT* iter, size_t n) {
-           RopeBase* result = destr_concat_char_iter(tree_ptr, iter, n);
-           unref(tree_ptr);
-           tree_ptr = result;
-           return *this;
-       }
-
-       rope& append(const charT* c_string) {
-           size_t len = char_ptr_len(c_string);
-           append(c_string, len);
-           return(*this);
-       }
-
-       rope& append(const charT* s, const charT* e) {
-           RopeBase* result =
-                       destr_concat_char_iter(tree_ptr, s, e - s);
-           unref(tree_ptr);
-           tree_ptr = result;
-           return *this;
-       }
-
-       rope& append(const_iterator s, const_iterator e) {
-           __stl_assert(s.root == e.root);
-           self_destruct_ptr appendee(substring(s.root, s.current_pos,
-                                                e.current_pos));
-           RopeBase* result = concat(tree_ptr, (RopeBase *)appendee);
-           unref(tree_ptr);
-           tree_ptr = result;
-           return *this;
-       }
-
-       rope& append(charT c) {
-           RopeBase* result = destr_concat_char_iter(tree_ptr, &c, 1);
-           unref(tree_ptr);
-           tree_ptr = result;
-           return *this;
-       }
-
-       rope& append() { return append(charT()); }
-
-       rope& append(const rope& y) {
-           RopeBase* result = concat(tree_ptr, y.tree_ptr);
-           unref(tree_ptr);
-           tree_ptr = result;
-           return *this;
-       }
-
-       rope& append(size_t n, charT c) {
-           rope<charT,Alloc> last(n, c);
-           return append(last);
-       }
-
-       void swap(rope& b) {
-           RopeBase * tmp = tree_ptr;
-           tree_ptr = b.tree_ptr;
-           b.tree_ptr = tmp;
-       }
-
-
-    protected:
-       // Result is included in refcount.
-       static RopeBase * replace(RopeBase *old, size_t pos1,
-                                 size_t pos2, RopeBase *r) {
-           if (0 == old) { ref(r); return r; }
-           self_destruct_ptr left(substring(old, 0, pos1));
-           self_destruct_ptr right(substring(old, pos2, old -> size));
-           RopeBase * result;
-
-           if (0 == r) {
-               result = concat(left, right);
-           } else {
-               self_destruct_ptr left_result(concat(left, r));
-               result = concat(left_result, right);
-           }
-           return result;
-       }
-
-    public:
-       void insert(size_t p, const rope& r) {
-           RopeBase * result = replace(tree_ptr, p, p,
-                                              r.tree_ptr);
-           unref(tree_ptr);
-           tree_ptr = result;
-       }
-
-       void insert(size_t p, size_t n, charT c) {
-           rope<charT,Alloc> r(n,c);
-           insert(p, r);
-       }
-
-       void insert(size_t p, const charT * i, size_t n) {
-           self_destruct_ptr left(substring(tree_ptr, 0, p));
-           self_destruct_ptr right(substring(tree_ptr, p, size()));
-           self_destruct_ptr left_result(concat_char_iter(left, i, n));
-           RopeBase * result =
-                               concat(left_result, right);
-           unref(tree_ptr);
-           tree_ptr = result;
-       }
-
-       void insert(size_t p, const charT * c_string) {
-           insert(p, c_string, char_ptr_len(c_string));
-       }
-
-       void insert(size_t p, charT c) {
-           insert(p, &c, 1);
-       }
-
-       void insert(size_t p) {
-           charT c = charT();
-           insert(p, &c, 1);
-       }
-
-       void insert(size_t p, const charT *i, const charT *j) {
-           rope r(i, j);
-           insert(p, r);
-       }
-
-       void insert(size_t p, const const_iterator& i,
-                             const const_iterator& j) {
-           rope r(i, j);
-           insert(p, r);
-       }
-
-       void insert(size_t p, const iterator& i,
-                             const iterator& j) {
-           rope r(i, j);
-           insert(p, r);
-       }
-
-       // (position, length) versions of replace operations:
-
-       void replace(size_t p, size_t n, const rope& r) {
-           RopeBase * result = replace(tree_ptr, p, p + n,
-                                              r.tree_ptr);
-           unref(tree_ptr);
-           tree_ptr = result;
-       }
-
-       void replace(size_t p, size_t n, const charT *i, size_t i_len) {
-           rope r(i, i_len);
-           replace(p, n, r);
-       }
-
-       void replace(size_t p, size_t n, charT c) {
-           rope r(c);
-           replace(p, n, r);
-       }
-
-       void replace(size_t p, size_t n, const charT *c_string) {
-           rope r(c_string);
-           replace(p, n, r);
-       }
-
-       void replace(size_t p, size_t n, const charT *i, const charT *j) {
-           rope r(i, j);
-           replace(p, n, r);
-       }
-
-       void replace(size_t p, size_t n,
-                    const const_iterator& i, const const_iterator& j) {
-           rope r(i, j);
-           replace(p, n, r);
-       }
-
-       void replace(size_t p, size_t n,
-                    const iterator& i, const iterator& j) {
-           rope r(i, j);
-           replace(p, n, r);
-       }
-
-       // Single character variants:
-       void replace(size_t p, charT c) {
-           iterator i(this, p);
-           *i = c;
-       }
-
-       void replace(size_t p, const rope& r) {
-           replace(p, 1, r);
-       }
-
-       void replace(size_t p, const charT *i, size_t i_len) {
-           replace(p, 1, i, i_len);
-       }
-
-       void replace(size_t p, const charT *c_string) {
-           replace(p, 1, c_string);
-       }
-
-       void replace(size_t p, const charT *i, const charT *j) {
-           replace(p, 1, i, j);
-       }
-
-       void replace(size_t p, const const_iterator& i,
-                              const const_iterator& j) {
-           replace(p, 1, i, j);
-       }
-
-       void replace(size_t p, const iterator& i,
-                              const iterator& j) {
-           replace(p, 1, i, j);
-       }
-
-       // Erase, (position, size) variant.
-       void erase(size_t p, size_t n) {
-           RopeBase * result = replace(tree_ptr, p, p + n, 0);
-           unref(tree_ptr);
-           tree_ptr = result;
-       }
-
-       // Erase, single character
-       void erase(size_t p) {
-           erase(p, p + 1);
-       }
-
-       // Insert, iterator variants.  
-       iterator insert(const iterator& p, const rope& r)
-               { insert(p.index(), r); return p; }
-       iterator insert(const iterator& p, size_t n, charT c)
-               { insert(p.index(), n, c); return p; }
-       iterator insert(const iterator& p, charT c) 
-               { insert(p.index(), c); return p; }
-       iterator insert(const iterator& p ) 
-               { insert(p.index()); return p; }
-       iterator insert(const iterator& p, const charT *c_string) 
-               { insert(p.index(), c_string); return p; }
-       iterator insert(const iterator& p, const charT *i, size_t n)
-               { insert(p.index(), i, n); return p; }
-       iterator insert(const iterator& p, const charT *i, const charT *j)
-               { insert(p.index(), i, j);  return p; }
-       iterator insert(const iterator& p,
-                       const const_iterator& i, const const_iterator& j)
-               { insert(p.index(), i, j); return p; }
-       iterator insert(const iterator& p,
-                       const iterator& i, const iterator& j)
-               { insert(p.index(), i, j); return p; }
-
-       // Replace, range variants.
-       void replace(const iterator& p, const iterator& q,
-                    const rope& r)
-               { replace(p.index(), q.index() - p.index(), r); }
-       void replace(const iterator& p, const iterator& q, charT c)
-               { replace(p.index(), q.index() - p.index(), c); }
-       void replace(const iterator& p, const iterator& q,
-                    const charT * c_string)
-               { replace(p.index(), q.index() - p.index(), c_string); }
-       void replace(const iterator& p, const iterator& q,
-                    const charT *i, size_t n)
-               { replace(p.index(), q.index() - p.index(), i, n); }
-       void replace(const iterator& p, const iterator& q,
-                    const charT *i, const charT *j)
-               { replace(p.index(), q.index() - p.index(), i, j); }
-       void replace(const iterator& p, const iterator& q,
-                    const const_iterator& i, const const_iterator& j)
-               { replace(p.index(), q.index() - p.index(), i, j); }
-       void replace(const iterator& p, const iterator& q,
-                    const iterator& i, const iterator& j)
-               { replace(p.index(), q.index() - p.index(), i, j); }
-
-       // Replace, iterator variants.
-       void replace(const iterator& p, const rope& r)
-               { replace(p.index(), r); }
-       void replace(const iterator& p, charT c)
-               { replace(p.index(), c); }
-       void replace(const iterator& p, const charT * c_string)
-               { replace(p.index(), c_string); }
-       void replace(const iterator& p, const charT *i, size_t n)
-               { replace(p.index(), i, n); }
-       void replace(const iterator& p, const charT *i, const charT *j)
-               { replace(p.index(), i, j); }
-       void replace(const iterator& p, const_iterator i, const_iterator j)
-               { replace(p.index(), i, j); }
-       void replace(const iterator& p, iterator i, iterator j)
-               { replace(p.index(), i, j); }
-
-       // Iterator and range variants of erase
-       void erase(const iterator &p, const iterator &q)
-               { erase(p.index(), q.index() - p.index()); }
-       void erase(const iterator &p)
-               { erase(p.index(), 1); }
-
-       rope substr(size_t start, size_t len = 1) const {
-           return rope<charT,Alloc>(
-                       substring(tree_ptr, start, start + len));
-       }
-
-       rope substr(iterator start, iterator end) const {
-           return rope<charT,Alloc>(
-                       substring(tree_ptr, start.index(), end.index()));
-       }
-       
-       rope substr(iterator start) const {
-           size_t pos = start.index();
-           return rope<charT,Alloc>(
-                       substring(tree_ptr, pos, pos + 1));
-       }
-       
-       rope substr(const_iterator start, const_iterator end) const {
-           // This might eventually take advantage of the cache in the
-           // iterator.
-           return rope<charT,Alloc>
-               (substring(tree_ptr, start.index(), end.index()));
-       }
-
-       rope<charT,Alloc> substr(const_iterator start) {
-           size_t pos = start.index();
-           return rope<charT,Alloc>(substring(tree_ptr, pos, pos + 1));
-       }
-
-       size_type find(charT c, size_type pos = 0) const;
-       size_type find(charT *s, size_type pos = 0) const {
-           const_iterator result = search(const_begin() + pos, const_end(),
-                                          s, s + char_ptr_len(s));
-           return result.index();
-       }
-
-       iterator mutable_begin() {
-           return(iterator(this, 0));
-       }
-
-       iterator mutable_end() {
-           return(iterator(this, size()));
-       }
-
-#     ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
-        typedef reverse_iterator<iterator> reverse_iterator;
-#     else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-       typedef reverse_iterator<iterator, value_type, reference,
-                                difference_type>  reverse_iterator;
-#     endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 
-
-       reverse_iterator mutable_rbegin() {
-           return reverse_iterator(mutable_end());
-       }
-
-       reverse_iterator mutable_rend() {
-           return reverse_iterator(mutable_begin());
-       }
-
-       reference mutable_reference_at(size_type pos) {
-           return reference(this, pos);
-       }
-
-#      ifdef __STD_STUFF
-           reference operator[] (size_type pos) {
-               return charT_ref_proxy(this, pos);
-           }
-
-           reference at(size_type pos) {
-               // if (pos >= size()) throw out_of_range;
-               return (*this)[pos];
-           }
-
-           void resize(size_type n, charT c) {}
-           void resize(size_type n) {}
-           void reserve(size_type res_arg = 0) {}
-           size_type capacity() const {
-               return max_size();
-           }
-
-         // Stuff below this line is dangerous because it's error prone.
-         // I would really like to get rid of it.
-           // copy function with funny arg ordering.
-             size_type copy(charT *buffer, size_type n, size_type pos = 0)
-                                                               const {
-               return copy(pos, n, buffer);
-             }
-
-           iterator end() { return mutable_end(); }
-
-           iterator begin() { return mutable_begin(); }
-
-           reverse_iterator rend() { return mutable_rend(); }
-
-           reverse_iterator rbegin() { return mutable_rbegin(); }
-
-#      else
-
-           const_iterator end() { return const_end(); }
-
-           const_iterator begin() { return const_begin(); }
-
-           const_reverse_iterator rend() { return const_rend(); }
-  
-           const_reverse_iterator rbegin() { return const_rbegin(); }
-
-#      endif
-       
-};
-
-template <class charT, class Alloc>
-inline bool operator== (const __rope_const_iterator<charT,Alloc> & x,
-                       const __rope_const_iterator<charT,Alloc> & y) {
-       return (x.current_pos == y.current_pos && x.root == y.root);
-}
-
-template <class charT, class Alloc>
-inline bool operator< (const __rope_const_iterator<charT,Alloc> & x,
-                      const __rope_const_iterator<charT,Alloc> & y) {
-       return (x.current_pos < y.current_pos);
-}
-
-template <class charT, class Alloc>
-inline ptrdiff_t operator-(const __rope_const_iterator<charT,Alloc> & x,
-                          const __rope_const_iterator<charT,Alloc> & y) {
-       return x.current_pos - y.current_pos;
-}
-
-template <class charT, class Alloc>
-inline __rope_const_iterator<charT,Alloc>
-operator-(const __rope_const_iterator<charT,Alloc> & x,
-         ptrdiff_t n) {
-       return __rope_const_iterator<charT,Alloc>(x.root, x.current_pos - n);
-}
-
-template <class charT, class Alloc>
-inline __rope_const_iterator<charT,Alloc>
-operator+(const __rope_const_iterator<charT,Alloc> & x,
-         ptrdiff_t n) {
-       return __rope_const_iterator<charT,Alloc>(x.root, x.current_pos + n);
-}
-
-template <class charT, class Alloc>
-inline __rope_const_iterator<charT,Alloc>
-operator+(ptrdiff_t n,
-         const __rope_const_iterator<charT,Alloc> & x) {
-       return __rope_const_iterator<charT,Alloc>(x.root, x.current_pos + n);
-}
-
-template <class charT, class Alloc>
-inline bool operator== (const __rope_iterator<charT,Alloc> & x,
-                       const __rope_iterator<charT,Alloc> & y) {
-       return (x.current_pos == y.current_pos && x.root_rope == y.root_rope);
-}
-
-template <class charT, class Alloc>
-inline bool operator< (const __rope_iterator<charT,Alloc> & x,
-                       const __rope_iterator<charT,Alloc> & y) {
-       return (x.current_pos < y.current_pos);
-}
-
-template <class charT, class Alloc>
-inline ptrdiff_t operator-(const __rope_iterator<charT,Alloc> & x,
-                          const __rope_iterator<charT,Alloc> & y) {
-       return x.current_pos - y.current_pos;
-}
-
-template <class charT, class Alloc>
-inline __rope_iterator<charT,Alloc>
-operator-(const __rope_iterator<charT,Alloc> & x,
-         ptrdiff_t n) {
-       return __rope_iterator<charT,Alloc>(x.root_rope, x.current_pos - n);
-}
-
-template <class charT, class Alloc>
-inline __rope_iterator<charT,Alloc>
-operator+(const __rope_iterator<charT,Alloc> & x,
-         ptrdiff_t n) {
-       return __rope_iterator<charT,Alloc>(x.root_rope, x.current_pos + n);
-}
-
-template <class charT, class Alloc>
-inline __rope_iterator<charT,Alloc>
-operator+(ptrdiff_t n,
-         const __rope_iterator<charT,Alloc> & x) {
-       return __rope_iterator<charT,Alloc>(x.root_rope, x.current_pos + n);
-}
-
-template <class charT, class Alloc>
-inline
-rope<charT,Alloc>
-operator+ (const rope<charT,Alloc> &left,
-          const rope<charT,Alloc> &right)
-{
-    return rope<charT,Alloc>
-               (rope<charT,Alloc>::concat(left.tree_ptr, right.tree_ptr));
-    // Inlining this should make it possible to keep left and
-    // right in registers.
-}
-
-template <class charT, class Alloc>
-inline
-rope<charT,Alloc>&
-operator+= (rope<charT,Alloc> &left,
-           const rope<charT,Alloc> &right)
-{
-    left.append(right);
-    return left;
-}
-
-template <class charT, class Alloc>
-inline
-rope<charT,Alloc>
-operator+ (const rope<charT,Alloc> &left,
-          const charT* right) {
-    size_t rlen = rope<charT,Alloc>::char_ptr_len(right);
-    return rope<charT,Alloc>
-          (rope<charT,Alloc>::concat_char_iter(left.tree_ptr, right, rlen)); 
-}
-
-template <class charT, class Alloc>
-inline
-rope<charT,Alloc>&
-operator+= (rope<charT,Alloc> &left,
-           const charT* right) {
-    left.append(right);
-    return left;
-}
-
-template <class charT, class Alloc>
-inline
-rope<charT,Alloc>
-operator+ (const rope<charT,Alloc> &left, charT right) {
-    return rope<charT,Alloc>
-               (rope<charT,Alloc>::concat_char_iter(left.tree_ptr, &right, 1));
-}
-
-template <class charT, class Alloc>
-inline
-rope<charT,Alloc>&
-operator+= (rope<charT,Alloc> &left, charT right) {
-    left.append(right);
-    return left;
-}
-
-template <class charT, class Alloc>
-bool
-operator< (const rope<charT,Alloc> &left, const rope<charT,Alloc> &right) {
-    return left.compare(right) < 0;
-}
-       
-template <class charT, class Alloc>
-bool
-operator== (const rope<charT,Alloc> &left, const rope<charT,Alloc> &right) {
-    return left.compare(right) == 0;
-}
-
-template <class charT, class Alloc>
-inline bool operator== (const __rope_charT_ptr_proxy<charT,Alloc> & x,
-                       const __rope_charT_ptr_proxy<charT,Alloc> & y) {
-       return (x.pos == y.pos && x.root == y.root);
-}
-
-template<class charT, class Alloc>
-ostream& operator<< (ostream& o, const rope<charT, Alloc>& r);        
-       
-typedef rope<char, __ALLOC> crope;
-typedef rope<wchar_t, __ALLOC> wrope;
-
-inline crope::reference __mutable_reference_at(crope& c, size_t i)
-{
-    return c.mutable_reference_at(i);
-}
-
-inline wrope::reference __mutable_reference_at(wrope& c, size_t i)
-{
-    return c.mutable_reference_at(i);
-}
-
-inline void swap(crope x, crope y) { x.swap(y); }
-inline void swap(wrope x, wrope y) { x.swap(y); }
-
-// Hash functions should probably be revisited later:
-struct hash<crope>
-{
-  size_t operator()(const crope& str) const
-  {
-    size_t sz = str.size();
-
-    if (0 == sz) return 0;
-    return 13*str[0] + 5*str[sz - 1] + sz;
-  }
-};
-
-struct hash<wrope>
-{
-  size_t operator()(const wrope& str) const
-  {
-    size_t sz = str.size();
-
-    if (0 == sz) return 0;
-    return 13*str[0] + 5*str[sz - 1] + sz;
-  }
-};
-
-# include <ropeimpl.h>
-# endif /* _ROPE_H */
+// Local Variables:
+// mode:C++
+// End:
index d1c1ed4..dcd6bfd 100644 (file)
  * purpose.  It is provided "as is" without express or implied warranty.
  */
 
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
 # include <stdio.h>
 # include <iostream.h>
 
+__STL_BEGIN_NAMESPACE
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1174
+#endif
+
 // Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf
 // if necessary.  Assumes path_end[leaf_index] and leaf_pos are correct.
 // Results in a valid buf_ptr if the iterator can be legitimately
@@ -416,8 +426,9 @@ rope<charT,Alloc>::leaf_concat_char_iter
     uninitialized_copy_n(r -> data, old_len, new_data);
     uninitialized_copy_n(iter, len, new_data + old_len);
     __cond_store_eos(new_data[old_len + len]);
-    __STL_TRY
+    __STL_TRY {
        result = RopeLeaf_from_char_ptr(new_data, old_len + len);
+    }
     __STL_UNWIND(RopeBase::free_string(new_data, old_len + len));
     return result;
 }
@@ -482,7 +493,7 @@ rope<charT,Alloc>::tree_concat (RopeBase * left, RopeBase * right)
     if (depth > 20 && (rsize < 1000 || depth > RopeBase::max_rope_depth)) {
        RopeBase * balanced;
 
-       __STL_TRY
+       __STL_TRY {
           balanced = balance(result);
 #          ifndef __GC
             if (result != balanced) {
@@ -491,6 +502,7 @@ rope<charT,Alloc>::tree_concat (RopeBase * left, RopeBase * right)
             }
 #          endif
           result -> unref_nonnil();
+        }
        __STL_UNWIND(CAlloc::deallocate(result));
                // In case of exception, we need to deallocate
                // otherwise dangling result node.  But caller
@@ -526,8 +538,9 @@ rope<charT,Alloc>::RopeBase * rope<charT,Alloc>::concat_char_iter
          RopeBase * left = ((RopeConcatenation *)r) -> left;
          RopeBase * nright = leaf_concat_char_iter((RopeLeaf *)right, s, slen);
          left -> ref_nonnil();
-         __STL_TRY
+         __STL_TRY {
            result = tree_concat(left, nright);
+          }
          __STL_UNWIND(unref(left); unref(nright));
 #         ifndef __GC
            __stl_assert(1 == result -> refcount);
@@ -536,9 +549,10 @@ rope<charT,Alloc>::RopeBase * rope<charT,Alloc>::concat_char_iter
        }
     }
     RopeBase * nright = RopeLeaf_from_unowned_char_ptr(s, slen);
-    __STL_TRY
+    __STL_TRY {
       r -> ref_nonnil();
       result = tree_concat(r, nright);
+    }
     __STL_UNWIND(unref(r); unref(nright));
 #   ifndef __GC
       __stl_assert(1 == result -> refcount);
@@ -591,8 +605,9 @@ rope<charT,Alloc>::RopeBase * rope<charT,Alloc>
     }
     RopeBase *right = RopeLeaf_from_unowned_char_ptr(s, slen);
     r -> ref_nonnil();
-    __STL_TRY
+    __STL_TRY {
       result = tree_concat(r, right);
+    }
     __STL_UNWIND(unref(r); unref(right))
     __stl_assert(1 == result -> refcount);
     return result;
@@ -629,16 +644,18 @@ rope<charT,Alloc>::concat(RopeBase * left, RopeBase * right)
                                           ((RopeLeaf *)right) -> data,
                                           right -> size);
            leftleft -> ref_nonnil();
-           __STL_TRY
+           __STL_TRY {
              return(tree_concat(leftleft, rest));
+            }
            __STL_UNWIND(unref(leftleft); unref(rest))
          }
        }
     }
     left -> ref_nonnil();
     right -> ref_nonnil();
-    __STL_TRY
+    __STL_TRY {
       return(tree_concat(left, right));
+    }
     __STL_UNWIND(unref(left); unref(right));
 }
 
@@ -732,8 +749,9 @@ rope<charT,Alloc>::substring(RopeBase * base, size_t start, size_t endp1)
                if (result_len > lazy_threshold) goto lazy;
                section = (charT *)
                        DataAlloc::allocate(rounded_up_size(result_len));
-               __STL_TRY
+               __STL_TRY {
                  (*(f -> fn))(start, result_len, section);
+                }
                __STL_UNWIND(RopeBase::free_string(section, result_len));
                __cond_store_eos(section[result_len]);
                return RopeLeaf_from_char_ptr(section, result_len);
@@ -872,10 +890,12 @@ bool rope<charT, Alloc>::apply_to_pieces(
                size_t len = end - begin;
                bool result;
                charT * buffer = DataAlloc::allocate(len);
-               __STL_TRY
+               __STL_TRY {
                  (*(f -> fn))(begin, end, buffer);
                  result = c(buffer, len);
-               __STL_ALWAYS(DataAlloc::deallocate(buffer, len))
+                  DataAlloc::deallocate(buffer, len);
+                }
+               __STL_UNWIND(DataAlloc::deallocate(buffer, len))
                return result;
            }
        default:
@@ -915,7 +935,7 @@ ostream& operator<< (ostream& o, const rope<charT, Alloc>& r)
        pad_len = 0;
     }
     if (!is_simple) o.width(w/rope_len);
-    __STL_TRY
+    __STL_TRY {
       if (is_simple && !left && pad_len > 0) {
        __rope_fill(o, pad_len);
       }
@@ -923,7 +943,10 @@ ostream& operator<< (ostream& o, const rope<charT, Alloc>& r)
       if (is_simple && left && pad_len > 0) {
        __rope_fill(o, pad_len);
       }
-    __STL_ALWAYS(if (!is_simple) o.width(w))
+      if (!is_simple)
+        o.width(w);
+    }
+    __STL_UNWIND(if (!is_simple) o.width(w))
     return o;
 }
 
@@ -964,7 +987,7 @@ rope<charT,Alloc>::flatten(RopeBase * r, charT * buffer)
        case RopeBase::leaf:
            {
                RopeLeaf * l = (RopeLeaf *)r;
-               return copy_n(l -> data, l -> size, buffer);
+               return copy_n(l -> data, l -> size, buffer).second;
            }
        case RopeBase::function:
        case RopeBase::substringfn:
@@ -1076,7 +1099,7 @@ rope<charT,Alloc>::balance(RopeBase *r)
     // References from forest are included in refcount.
 
     for (i = 0; i <= RopeBase::max_rope_depth; ++i) forest[i] = 0;
-    __STL_TRY
+    __STL_TRY {
       add_to_forest(r, forest);
       for (i = 0; i <= RopeBase::max_rope_depth; ++i) if (0 != forest[i]) {
 #      ifndef __GC
@@ -1088,6 +1111,7 @@ rope<charT,Alloc>::balance(RopeBase *r)
          forest[i] = 0;
 #      endif
       }
+    }
     __STL_UNWIND(for(i = 0; i <= RopeBase::max_rope_depth; i++)
                 unref(forest[i]))
     if (result -> depth > RopeBase::max_rope_depth) abort();
@@ -1366,8 +1390,9 @@ rope<charT, Alloc>::rope(size_t n, charT c)
        rest_buffer = DataAlloc::allocate(rounded_up_size(rest));
        uninitialized_fill_n(rest_buffer, rest, c);
        __cond_store_eos(rest_buffer[rest]);
-       __STL_TRY
+       __STL_TRY {
            remainder = RopeLeaf_from_char_ptr(rest_buffer, rest);
+        }
        __STL_UNWIND(RopeBase::free_string(rest_buffer, rest))
     }
     remainder_rope.tree_ptr = remainder;
@@ -1378,9 +1403,10 @@ rope<charT, Alloc>::rope(size_t n, charT c)
        rope base_rope;
        uninitialized_fill_n(base_buffer, exponentiate_threshold, c);
        __cond_store_eos(base_buffer[exponentiate_threshold]);
-       __STL_TRY
-       base_leaf = RopeLeaf_from_char_ptr(base_buffer,
-                                          exponentiate_threshold);
+       __STL_TRY {
+          base_leaf = RopeLeaf_from_char_ptr(base_buffer,
+                                             exponentiate_threshold);
+        }
        __STL_UNWIND(RopeBase::free_string(base_buffer, exponentiate_threshold))
        base_rope.tree_ptr = base_leaf;
        if (1 == exponent) {
@@ -1499,3 +1525,13 @@ inline void rotate(__rope_iterator<wchar_t,__ALLOC> first,
 }
 # endif
 #endif /* _MSC_VER */
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1174
+#endif
+
+__STL_END_NAMESPACE
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/set b/libstdc++/stl/set
new file mode 100644 (file)
index 0000000..c836c45
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __SGI_STL_SET
+#define __SGI_STL_SET
+
+#ifndef __SGI_STL_INTERNAL_TREE_H
+#include <stl_tree.h>
+#endif
+#include <stl_set.h>
+#include <stl_multiset.h>
+
+#endif /* __SGI_STL_SET */
+
+// Local Variables:
+// mode:C++
+// End:
index 6a79a62..9004d2e 100644 (file)
@@ -12,7 +12,7 @@
  * purpose.  It is provided "as is" without express or implied warranty.
  *
  *
- * Copyright (c) 1996
+ * Copyright (c) 1996,1997
  * Silicon Graphics Computer Systems, Inc.
  *
  * Permission to use, copy, modify, distribute and sell this software
 #define __SGI_STL_SET_H
 
 #include <tree.h>
+#include <stl_set.h>
 
-#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
-template <class Key, class Compare = less<Key>, class Alloc = alloc>
-#else
-template <class Key, class Compare, class Alloc = alloc>
-#endif
-class set {
-public:
-  // typedefs:
-
-  typedef Key key_type;
-  typedef Key value_type;
-  typedef Compare key_compare;
-  typedef Compare value_compare;
-private:
-  typedef rb_tree<key_type, value_type, 
-                  identity<value_type>, key_compare, Alloc> rep_type;
-  rep_type t;  // red-black tree representing set
-public:
-  typedef rep_type::const_pointer pointer;
-  typedef rep_type::const_reference reference;
-  typedef rep_type::const_reference const_reference;
-  typedef rep_type::const_iterator iterator;
-  typedef rep_type::const_iterator const_iterator;
-  typedef rep_type::const_reverse_iterator reverse_iterator;
-  typedef rep_type::const_reverse_iterator const_reverse_iterator;
-  typedef rep_type::size_type size_type;
-  typedef rep_type::difference_type difference_type;
-
-  // allocation/deallocation
-
-  set() : t(Compare()) {}
-  explicit set(const Compare& comp) : t(comp) {}
-
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  set(InputIterator first, InputIterator last)
-    : t(Compare()) { t.insert_unique(first, last); }
-
-  template <class InputIterator>
-  set(InputIterator first, InputIterator last, const Compare& comp)
-    : t(comp) { t.insert_unique(first, last); }
-#else
-  set(const value_type* first, const value_type* last) 
-    : t(Compare()) { t.insert_unique(first, last); }
-  set(const value_type* first, const value_type* last, const Compare& comp)
-    : t(comp) { t.insert_unique(first, last); }
-
-  set(const_iterator first, const_iterator last)
-    : t(Compare()) { t.insert_unique(first, last); }
-  set(const_iterator first, const_iterator last, const Compare& comp)
-    : t(comp) { t.insert_unique(first, last); }
-#endif /* __STL_MEMBER_TEMPLATES */
-
-  set(const set<Key, Compare, Alloc>& x) : t(x.t) {}
-  set<Key, Compare, Alloc>& operator=(const set<Key, Compare, Alloc>& x) { 
-    t = x.t; 
-    return *this;
-  }
-
-  // accessors:
-
-  key_compare key_comp() const { return t.key_comp(); }
-  value_compare value_comp() const { return t.key_comp(); }
-  iterator begin() const { return t.begin(); }
-  iterator end() const { return t.end(); }
-  reverse_iterator rbegin() const { return t.rbegin(); } 
-  reverse_iterator rend() const { return t.rend(); }
-  bool empty() const { return t.empty(); }
-  size_type size() const { return t.size(); }
-  size_type max_size() const { return t.max_size(); }
-  void swap(set<Key, Compare, Alloc>& x) { t.swap(x.t); }
-
-  // insert/erase
-  typedef  pair<iterator, bool> pair_iterator_bool; 
-  pair<iterator,bool> insert(const value_type& x) { 
-    pair<rep_type::iterator, bool> p = t.insert_unique(x); 
-    return pair<iterator, bool>(p.first, p.second);
-  }
-  iterator insert(iterator position, const value_type& x) {
-    return t.insert_unique((rep_type::iterator&)position, x);
-  }
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  void insert(InputIterator first, InputIterator last) {
-    t.insert_unique(first, last);
-  }
-#else
-  void insert(const_iterator first, const_iterator last) {
-    t.insert_unique(first, last);
-  }
-  void insert(const value_type* first, const value_type* last) {
-    t.insert_unique(first, last);
-  }
-#endif /* __STL_MEMBER_TEMPLATES */
-  void erase(iterator position) { 
-    t.erase((rep_type::iterator&)position); 
-  }
-  size_type erase(const key_type& x) { 
-    return t.erase(x); 
-  }
-  void erase(iterator first, iterator last) { 
-    t.erase((rep_type::iterator&)first, 
-            (rep_type::iterator&)last); 
-  }
-  void clear() { t.clear(); }
-
-  // set operations:
-
-  iterator find(const key_type& x) const { return t.find(x); }
-  size_type count(const key_type& x) const { return t.count(x); }
-  iterator lower_bound(const key_type& x) const {
-    return t.lower_bound(x);
-  }
-  iterator upper_bound(const key_type& x) const {
-    return t.upper_bound(x); 
-  }
-  pair<iterator,iterator> equal_range(const key_type& x) const {
-    return t.equal_range(x);
-  }
-  friend bool operator==(const set&, const set&);
-  friend bool operator<(const set&, const set&);
-};
-
-template <class Key, class Compare, class Alloc>
-inline bool operator==(const set<Key, Compare, Alloc>& x, 
-                       const set<Key, Compare, Alloc>& y) {
-  return x.t == y.t;
-}
-
-template <class Key, class Compare, class Alloc>
-inline bool operator<(const set<Key, Compare, Alloc>& x, 
-                      const set<Key, Compare, Alloc>& y) {
-  return x.t < y.t;
-}
+#ifdef __STL_USE_NAMESPACES
+using __STD::set;
+#endif /* __STL_USE_NAMESPACES */
 
 #endif /* __SGI_STL_SET_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/slist b/libstdc++/stl/slist
new file mode 100644 (file)
index 0000000..c3ec742
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef __SGI_STL_SLIST
+#define __SGI_STL_SLIST
+
+#include <stl_algobase.h>
+#include <stl_alloc.h>
+#include <stl_construct.h>
+#include <stl_uninitialized.h>
+#include <stl_slist.h>
+
+#endif /* __SGI_STL_SLIST */
+
+// Local Variables:
+// mode:C++
+// End:
index 9ae6e11..d2377b0 100644 (file)
 
 #include <algobase.h>
 #include <alloc.h>
+#include <stl_slist.h>
 
-struct __slist_node_base
-{
-  __slist_node_base* next;
-};
-
-inline __slist_node_base* __slist_make_link(__slist_node_base* prev_node,
-                                            __slist_node_base* new_node)
-{
-  new_node->next = prev_node->next;
-  prev_node->next = new_node;
-  return new_node;
-}
-
-inline __slist_node_base* __slist_previous(__slist_node_base* head,
-                                           const __slist_node_base* node)
-{
-  while (head && head->next != node)
-    head = head->next;
-  return head;
-}
-
-inline const __slist_node_base* __slist_previous(const __slist_node_base* head,
-                                                 const __slist_node_base* node)
-{
-  while (head && head->next != node)
-    head = head->next;
-  return head;
-}
-
-inline void __slist_splice_after(__slist_node_base* pos,
-                                 __slist_node_base* before_first,
-                                 __slist_node_base* before_last)
-{
-  if (pos != before_first && pos != before_last) {
-    __slist_node_base* first = before_first->next;
-    __slist_node_base* after = pos->next;
-    before_first->next = before_last->next;
-    pos->next = first;
-    before_last->next = after;
-  }
-}
-
-inline __slist_node_base* __slist_reverse(__slist_node_base* node)
-{
-  __slist_node_base* result = node;
-  node = node->next;
-  result->next = 0;
-  while(node) {
-    __slist_node_base* next = node->next;
-    node->next = result;
-    result = node;
-    node = next;
-  }
-  return result;
-}
-
-template <class T>
-struct __slist_node : public __slist_node_base
-{
-  T data;
-};
-
-struct __slist_iterator_base
-{
-  typedef size_t size_type;
-  typedef ptrdiff_t difference_type;
-  typedef forward_iterator_tag iterator_category;
-
-  __slist_node_base* node;
-
-  __slist_iterator_base(__slist_node_base* x) : node(x) {}
-  void incr() { node = node->next; }
-
-  bool operator==(const __slist_iterator_base& x) const {
-    return node == x.node;
-  }
-  bool operator!=(const __slist_iterator_base& x) const {
-    return node != x.node;
-  }
-};
-
-template <class T, class Ref, class Ptr>
-struct __slist_iterator : public __slist_iterator_base
-{
-  typedef __slist_iterator<T, T&, T*>             iterator;
-  typedef __slist_iterator<T, const T&, const T*> const_iterator;
-  typedef __slist_iterator<T, Ref, Ptr>           self;
-
-  typedef T value_type;
-  typedef Ptr pointer;
-  typedef Ref reference;
-  typedef __slist_node<T> list_node;
-
-  __slist_iterator(list_node* x) : __slist_iterator_base(x) {}
-  __slist_iterator() : __slist_iterator_base(0) {}
-  __slist_iterator(const iterator& x) : __slist_iterator_base(x.node) {}
-
-  reference operator*() const { return ((list_node*) node)->data; }
-#ifndef __SGI_STL_NO_ARROW_OPERATOR
-  pointer operator->() const { return &(operator*()); }
-#endif /* __SGI_STL_NO_ARROW_OPERATOR */
-
-  self& operator++()
-  {
-    incr();
-    return *this;
-  }
-  self operator++(int)
-  {
-    self tmp = *this;
-    incr();
-    return tmp;
-  }
-};
-
-#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-inline ptrdiff_t*
-distance_type(const __slist_iterator_base&)
-{
-  return 0;
-}
-
-inline forward_iterator_tag
-iterator_category(const __slist_iterator_base&)
-{
-  return forward_iterator_tag();
-}
-
-template <class T, class Ref, class Ptr> 
-inline T* 
-value_type(const __slist_iterator<T, Ref, Ptr>&) {
-  return 0;
-}
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-inline size_t __slist_size(__slist_node_base* node)
-{
-  size_t result = 0;
-  for ( ; node != 0; node = node->next)
-    ++result;
-  return result;
-}
-
-template <class T, class Alloc = alloc>
-class slist
-{
-public:
-  typedef T value_type;
-  typedef value_type* pointer;
-  typedef value_type& reference;
-  typedef const value_type& const_reference;
-  typedef size_t size_type;
-  typedef ptrdiff_t difference_type;
-
-  typedef __slist_iterator<T, T&, T*>             iterator;
-  typedef __slist_iterator<T, const T&, const T*> const_iterator;
-
-private:
-  typedef __slist_node<T> list_node;
-  typedef __slist_node_base list_node_base;
-  typedef __slist_iterator_base iterator_base;
-  typedef simple_alloc<list_node, Alloc> list_node_allocator;
-
-  static list_node* create_node(const value_type& x) {
-    list_node* node = list_node_allocator::allocate();
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      construct(&node->data, x);
-      node->next = 0;
-      return node;
-#       ifdef __STL_USE_EXCEPTIONS 
-    }
-    catch(...) {
-      list_node_allocator::deallocate(node);
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */
-  }
-  
-  static void destroy_node(list_node* node) {
-    destroy(&node->data);
-    list_node_allocator::deallocate(node);
-  }
-
-  void fill_initialize(size_type n, const value_type& x) {
-    head.next = 0;
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      _insert_after_fill(&head, n, x);
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      clear();
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */ 
-  }    
-
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  void range_initialize(InputIterator first, InputIterator last) {
-    head.next = 0;
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      _insert_after_range(&head, first, last);
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      clear();
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */ 
-  } 
-#else /* __STL_MEMBER_TEMPLATES */
-  void range_initialize(const value_type* first, const value_type* last) {
-    head.next = 0;
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      _insert_after_range(&head, first, last);
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      clear();
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */ 
-  } 
-  void range_initialize(const_iterator first, const_iterator last) {
-    head.next = 0;
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      _insert_after_range(&head, first, last);
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      clear();
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */ 
-  } 
-#endif /* __STL_MEMBER_TEMPLATES */
-
-private:
-  list_node_base head;
-
-public:
-  slist() { head.next = 0; }
-
-  slist(size_type n, const value_type& x) { fill_initialize(n, x); }
-  slist(int n, const value_type& x) { fill_initialize(n, x); }
-  slist(long n, const value_type& x) { fill_initialize(n, x); }
-  explicit slist(size_type n) { fill_initialize(n, value_type()); }
-
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InputIterator>
-  slist(InputIterator first, InputIterator last) {
-    range_initialize(first, last);
-  }
-
-#else /* __STL_MEMBER_TEMPLATES */
-  slist(const_iterator first, const_iterator last) {
-    range_initialize(first, last);
-  }
-  slist(const value_type* first, const value_type* last) {
-    range_initialize(first, last);
-  }
-#endif /* __STL_MEMBER_TEMPLATES */
-
-  slist(const slist& L) { range_initialize(L.begin(), L.end()); }
-
-  slist& operator= (const slist& L);
-
-  ~slist() { clear(); }
-
-public:
-
-  iterator begin() { return iterator((list_node*)head.next); }
-  const_iterator begin() const { return const_iterator((list_node*)head.next);}
-
-  iterator end() { return iterator(0); }
-  const_iterator end() const { return const_iterator(0); }
-
-  size_type size() const { return __slist_size(head.next); }
-  
-  size_type max_size() const { return size_type(-1); }
-
-  bool empty() const { return head.next == 0; }
-
-  void swap(slist& L)
-  {
-    list_node_base* tmp = head.next;
-    head.next = L.head.next;
-    L.head.next = tmp;
-  }
-
-public:
-  friend bool operator==(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2);
-
-public:
-
-  reference front() { return ((list_node*) head.next)->data; }
-  const_reference front() const { return ((list_node*) head.next)->data; }
-  void push_front(const value_type& x)   {
-    __slist_make_link(&head, create_node(x));
-  }
-  void pop_front() {
-    list_node* node = (list_node*) head.next;
-    head.next = node->next;
-    destroy_node(node);
-  }
-
-  iterator previous(const_iterator pos) {
-    return iterator((list_node*) __slist_previous(&head, pos.node));
-  }
-  const_iterator previous(const_iterator pos) const {
-    return const_iterator((list_node*) __slist_previous(&head, pos.node));
-  }
-
-private:
-  list_node* _insert_after(list_node_base* pos, const value_type& x) {
-    return (list_node*) (__slist_make_link(pos, create_node(x)));
-  }
-
-  void _insert_after_fill(list_node_base* pos,
-                          size_type n, const value_type& x) {
-    for (size_type i = 0; i < n; ++i)
-      pos = __slist_make_link(pos, create_node(x));
-  }
-
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InIter>
-  void _insert_after_range(list_node_base* pos, InIter first, InIter last) {
-    while (first != last) {
-      pos = __slist_make_link(pos, create_node(*first));
-      ++first;
-    }
-  }
-#else /* __STL_MEMBER_TEMPLATES */
-  void _insert_after_range(list_node_base* pos,
-                           const_iterator first, const_iterator last) {
-    while (first != last) {
-      pos = __slist_make_link(pos, create_node(*first));
-      ++first;
-    }
-  }
-  void _insert_after_range(list_node_base* pos,
-                           const value_type* first, const value_type* last) {
-    while (first != last) {
-      pos = __slist_make_link(pos, create_node(*first));
-      ++first;
-    }
-  }
-#endif /* __STL_MEMBER_TEMPLATES */
-
-  void erase_after(list_node_base* pos) {
-    list_node* next = (list_node*) (pos->next);
-    pos->next = next->next;
-    destroy_node(next);
-  }
-   
-  void erase_after(list_node_base* before_first, list_node_base* last_node) {
-    list_node* cur = (list_node*) (before_first->next);
-    while (cur != last_node) {
-      list_node* tmp = cur;
-      cur = (list_node*) cur->next;
-      destroy_node(tmp);
-    }
-    before_first->next = last_node;
-  }
-
-
-public:
-
-  iterator insert_after(iterator pos, const value_type& x) {
-    return iterator(_insert_after(pos.node, x));
-  }
-
-  iterator insert_after(iterator pos) {
-    return insert_after(pos, value_type());
-  }
-
-  void insert_after(iterator pos, size_type n, const value_type& x) {
-    _insert_after_fill(pos.node, n, x);
-  }
-  void insert_after(iterator pos, int n, const value_type& x) {
-    _insert_after_fill(pos.node, (size_type) n, x);
-  }
-  void insert_after(iterator pos, long n, const value_type& x) {
-    _insert_after_fill(pos.node, (size_type) n, x);
-  }
-
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InIter>
-  void insert_after(iterator pos, InIter first, InIter last) {
-    _insert_after_range(pos.node, first, last);
-  }
-#else /* __STL_MEMBER_TEMPLATES */
-  void insert_after(iterator pos, const_iterator first, const_iterator last) {
-    _insert_after_range(pos.node, first, last);
-  }
-  void insert_after(iterator pos,
-                    const value_type* first, const value_type* last) {
-    _insert_after_range(pos.node, first, last);
-  }
-#endif /* __STL_MEMBER_TEMPLATES */
-
-  iterator insert(iterator pos, const value_type& x) {
-    return iterator(_insert_after(__slist_previous(&head, pos.node), x));
-  }
-
-  iterator insert(iterator pos) {
-    return iterator(_insert_after(__slist_previous(&head, pos.node),
-                                  value_type()));
-  }
-
-  void insert(iterator pos, size_type n, const value_type& x) {
-    _insert_after_fill(__slist_previous(&head, pos.node), n, x);
-  } 
-  void insert(iterator pos, int n, const value_type& x) {
-    _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x);
-  } 
-  void insert(iterator pos, long n, const value_type& x) {
-    _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x);
-  } 
-    
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class InIter>
-  void insert(iterator pos, InIter first, InIter last) {
-    _insert_after_range(__slist_previous(&head, pos.node), first, last);
-  }
-#else /* __STL_MEMBER_TEMPLATES */
-  void insert(iterator pos, const_iterator first, const_iterator last) {
-    _insert_after_range(__slist_previous(&head, pos.node), first, last);
-  }
-  void insert(iterator pos, const value_type* first, const value_type* last) {
-    _insert_after_range(__slist_previous(&head, pos.node), first, last);
-  }
-#endif /* __STL_MEMBER_TEMPLATES */
-
-
-public:
-  void erase_after(iterator pos) { erase_after(pos.node); }
-  void erase_after(iterator before_first, iterator last) {
-    erase_after(before_first.node, last.node);
-  }
-
-  void erase(iterator pos) { erase_after(__slist_previous(&head, pos.node)); }
-  void erase(iterator first, iterator last) {
-    erase_after(__slist_previous(&head, first.node), last.node);
-  }
-
-  void resize(size_type new_size, const T& x);
-  void resize(size_type new_size) { resize(new_size, T()); }
-  void clear() { erase_after(&head, 0); }
-
-public:
-  // Moves the range [before_first + 1, before_last + 1) to *this,
-  //  inserting it immediately after pos.  This is constant time.
-  void splice_after(iterator pos, 
-                    iterator before_first, iterator before_last)
-  {
-    if (before_first != before_last) 
-      __slist_splice_after(pos.node, before_first.node, before_last.node);
-  }
-
-  // Moves the element that follows prev to *this, inserting it immediately
-  //  after pos.  This is constant time.
-  void splice_after(iterator pos, iterator prev)
-  {
-    __slist_splice_after(pos.node, prev.node, prev.node->next);
-  }
-
-
-  // Linear in distance(begin(), pos), and linear in L.size().
-  void splice(iterator pos, slist& L) {
-    if (L.head.next)
-      __slist_splice_after(__slist_previous(&head, pos.node),
-                           &L.head,
-                           __slist_previous(&L.head, 0));
-  }
-
-  // Linear in distance(begin(), pos), and in distance(L.begin(), i).
-  void splice(iterator pos, slist& L, iterator i) {
-    __slist_splice_after(__slist_previous(&head, pos.node),
-                         __slist_previous(&L.head, i.node),
-                         i.node);
-  }
-
-  // Linear in distance(begin(), pos), in distance(L.begin(), first),
-  // and in distance(first, last).
-  void splice(iterator pos, slist& L, iterator first, iterator last)
-  {
-    if (first != last)
-      __slist_splice_after(__slist_previous(&head, pos.node),
-                           __slist_previous(&L.head, first.node),
-                           __slist_previous(first.node, last.node));
-  }
-
-public:
-  void reverse() { if (head.next) head.next = __slist_reverse(head.next); }
-
-  void remove(const T& val); 
-  void unique(); 
-  void merge(slist& L);
-  void sort();     
-
-#ifdef __STL_MEMBER_TEMPLATES
-  template <class Predicate> void remove_if(Predicate pred);
-  template <class BinaryPredicate> void unique(BinaryPredicate pred); 
-  template <class StrictWeakOrdering> void merge(slist&, StrictWeakOrdering); 
-  template <class StrictWeakOrdering> void sort(StrictWeakOrdering comp); 
-#endif /* __STL_MEMBER_TEMPLATES */
-};
-
-template <class T, class Alloc>
-slist<T, Alloc>& slist<T,Alloc>::operator=(const slist<T, Alloc>& L)
-{
-  if (&L != this) {
-    list_node_base* p1 = &head;
-    list_node* n1 = (list_node*) head.next;
-    const list_node* n2 = (const list_node*) L.head.next;
-    while (n1 && n2) {
-      n1->data = n2->data;
-      p1 = n1;
-      n1 = (list_node*) n1->next;
-      n2 = (const list_node*) n2->next;
-    }
-    if (n2 == 0)
-      erase_after(p1, 0);
-    else
-      _insert_after_range(p1,
-                          const_iterator((list_node*)n2), const_iterator(0));
-  }
-  return *this;
-} 
-
-template <class T, class Alloc>
-bool operator==(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2)
-{
-  typedef typename slist<T,Alloc>::list_node list_node;
-  list_node* n1 = (list_node*) L1.head.next;
-  list_node* n2 = (list_node*) L2.head.next;
-  while (n1 && n2 && n1->data == n2->data) {
-    n1 = (list_node*) n1->next;
-    n2 = (list_node*) n2->next;
-  }
-  return n1 == 0 && n2 == 0;
-}
-
-template <class T, class Alloc>
-inline bool operator<(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2)
-{
-  return lexicographical_compare(L1.begin(), L1.end(), L2.begin(), L2.end());
-}
-
-template <class T, class Alloc>
-void slist<T, Alloc>::resize(size_type len, const T& x)
-{
-  list_node_base* cur = &head;
-  while (cur->next != 0 && len > 0) {
-    --len;
-    cur = cur->next;
-  }
-  if (cur->next) 
-    erase_after(cur, 0);
-  else
-    _insert_after_fill(cur, len, x);
-}
-
-template <class T, class Alloc>
-void slist<T,Alloc>::remove(const T& val)
-{
-  list_node_base* cur = &head;
-  while (cur && cur->next) {
-    if (((list_node*) cur->next)->data == val)
-      erase_after(cur);
-    else
-      cur = cur->next;
-  }
-}
-
-template <class T, class Alloc> 
-void slist<T,Alloc>::unique()
-{
-  list_node_base* cur = head.next;
-  if (cur) {
-    while (cur->next) {
-      if (((list_node*)cur)->data == ((list_node*)(cur->next))->data)
-        erase_after(cur);
-      else
-        cur = cur->next;
-    }
-  }
-}
-
-template <class T, class Alloc>
-void slist<T,Alloc>::merge(slist<T,Alloc>& L)
-{
-  list_node_base* n1 = &head;
-  while (n1->next && L.head.next) {
-    if (((list_node*) L.head.next)->data < ((list_node*) n1->next)->data) 
-      __slist_splice_after(n1, &L.head, L.head.next);
-    n1 = n1->next;
-  }
-  if (L.head.next) {
-    n1->next = L.head.next;
-    L.head.next = 0;
-  }
-}
-
-template <class T, class Alloc>
-void slist<T,Alloc>::sort()
-{
-  if (head.next && head.next->next) {
-    slist carry;
-    slist counter[64];
-    int fill = 0;
-    while (!empty()) {
-      __slist_splice_after(&carry.head, &head, head.next);
-      int i = 0;
-      while (i < fill && !counter[i].empty()) {
-        counter[i].merge(carry);
-        carry.swap(counter[i]);
-        ++i;
-      }
-      carry.swap(counter[i]);
-      if (i == fill)
-        ++fill;
-    }
-
-    for (int i = 1; i < fill; ++i)
-      counter[i].merge(counter[i-1]);
-    this->swap(counter[fill-1]);
-  }
-}
-
-#ifdef __STL_MEMBER_TEMPLATES
-
-template <class T, class Alloc> 
-template <class Predicate> void slist<T,Alloc>::remove_if(Predicate pred)
-{
-  list_node_base* cur = &head;
-  while (cur->next) {
-    if (pred(((list_node*) cur->next)->data))
-      erase_after(cur);
-    else
-      cur = cur->next;
-  }
-}
-
-template <class T, class Alloc> template <class BinaryPredicate> 
-void slist<T,Alloc>::unique(BinaryPredicate pred)
-{
-  list_node* cur = (list_node*) head.next;
-  if (cur) {
-    while (cur->next) {
-      if (pred(((list_node*)cur)->data, ((list_node*)(cur->next))->data))
-        erase_after(cur);
-      else
-        cur = (list_node*) cur->next;
-    }
-  }
-}
-
-template <class T, class Alloc> template <class StrictWeakOrdering>
-void slist<T,Alloc>::merge(slist<T,Alloc>& L, StrictWeakOrdering comp)
-{
-  list_node_base* n1 = &head;
-  while (n1->next && L.head.next) {
-    if (comp(((list_node*) L.head.next)->data,
-             ((list_node*) n1->next)->data))
-      __slist_splice_after(n1, &L.head, L.head.next);
-    n1 = n1->next;
-  }
-  if (L.head.next) {
-    n1->next = L.head.next;
-    L.head.next = 0;
-  }
-}
-
-template <class T, class Alloc> template <class StrictWeakOrdering> 
-void slist<T,Alloc>::sort(StrictWeakOrdering comp)
-{
-  if (head.next && head.next->next) {
-    slist carry;
-    slist counter[64];
-    int fill = 0;
-    while (!empty()) {
-      __slist_splice_after(&carry.head, &head, head.next);
-      int i = 0;
-      while (i < fill && !counter[i].empty()) {
-        counter[i].merge(carry, comp);
-        carry.swap(counter[i]);
-        ++i;
-      }
-      carry.swap(counter[i]);
-      if (i == fill)
-        ++fill;
-    }
-
-    for (int i = 1; i < fill; ++i)
-      counter[i].merge(counter[i-1], comp);
-    this->swap(counter[fill-1]);
-  }
-}
-
-#endif /* __STL_MEMBER_TEMPLATES */
+#ifdef __STL_USE_NAMESPACES
+using __STD::slist;
+#endif /* __STL_USE_NAMESPACES */
 
 #endif /* __SGI_STL_SLIST_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stack b/libstdc++/stl/stack
new file mode 100644 (file)
index 0000000..36461d9
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __SGI_STL_STACK
+#define __SGI_STL_STACK
+
+#include <stl_algobase.h>
+#include <stl_alloc.h>
+#include <stl_construct.h>
+#include <stl_uninitialized.h>
+#include <stl_deque.h>
+#include <stl_stack.h>
+
+#endif /* __SGI_STL_STACK */
+
+// Local Variables:
+// mode:C++
+// End:
index cc025bb..89beca8 100644 (file)
@@ -12,7 +12,7 @@
  * purpose.  It is provided "as is" without express or implied warranty.
  *
  *
- * Copyright (c) 1996
+ * Copyright (c) 1996,1997
  * Silicon Graphics Computer Systems, Inc.
  *
  * Permission to use, copy, modify, distribute and sell this software
  * purpose.  It is provided "as is" without express or implied warranty.
  */
 
-#ifndef STACK_H
-#define STACK_H
+#ifndef __SGI_STL_STACK_H
+#define __SGI_STL_STACK_H
 
-#include <function.h>
-#include <heap.h>
 #include <vector.h>
 #include <deque.h>
+#include <heap.h>
+#include <stl_stack.h>
+#include <stl_queue.h>
 
-#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
-template <class T, class Sequence = deque<T> >
-#else
-template <class T, class Sequence>
-#endif
-class stack {
-  friend bool operator==(const stack<T, Sequence>& x,
-                         const stack<T, Sequence>& y);
-  friend bool operator<(const stack<T, Sequence>& x,
-                        const stack<T, Sequence>& y);
-public:
-    typedef typename Sequence::value_type value_type;
-    typedef typename Sequence::size_type size_type;
-protected:
-    Sequence c;
-public:
-    bool empty() const { return c.empty(); }
-    size_type size() const { return c.size(); }
-    value_type& top() { return c.back(); }
-    const value_type& top() const { return c.back(); }
-    void push(const value_type& x) { c.push_back(x); }
-    void pop() { c.pop_back(); }
-};
-
-template <class T, class Sequence>
-bool operator==(const stack<T, Sequence>& x, const stack<T, Sequence>& y) {
-    return x.c == y.c;
-}
-
-template <class T, class Sequence>
-bool operator<(const stack<T, Sequence>& x, const stack<T, Sequence>& y) {
-    return x.c < y.c;
-}
-
-#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
-template <class T, class Sequence = deque<T> >
-#else
-template <class T, class Sequence>
-#endif
-class queue {
-friend bool operator==(const queue<T, Sequence>& x, const queue<T, Sequence>& y);
-friend bool operator<(const queue<T, Sequence>& x, const queue<T, Sequence>& y);
-public:
-    typedef typename Sequence::value_type value_type;
-    typedef typename Sequence::size_type size_type;
-protected:
-    Sequence c;
-public:
-    bool empty() const { return c.empty(); }
-    size_type size() const { return c.size(); }
-    value_type& front() { return c.front(); }
-    const value_type& front() const { return c.front(); }
-    value_type& back() { return c.back(); }
-    const value_type& back() const { return c.back(); }
-    void push(const value_type& x) { c.push_back(x); }
-    void pop() { c.pop_front(); }
-};
-
-template <class T, class Sequence>
-bool operator==(const queue<T, Sequence>& x, const queue<T, Sequence>& y) {
-    return x.c == y.c;
-}
-
-template <class T, class Sequence>
-bool operator<(const queue<T, Sequence>& x, const queue<T, Sequence>& y) {
-    return x.c < y.c;
-}
-
-#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
-template <class T, class Sequence = vector<T>, 
-          class Compare = less<typename Sequence::value_type> >
-#else
-template <class T, class Sequence, class Compare>
-#endif
-class  priority_queue {
-public:
-    typedef typename Sequence::value_type value_type;
-    typedef typename Sequence::size_type size_type;
-protected:
-    Sequence c;
-    Compare comp;
-public:
-    priority_queue() : c() {}
-    explicit priority_queue(const Compare& x) :  c(), comp(x) {}
-
-#ifdef __STL_MEMBER_TEMPLATES
-    template <class InputIterator>
-    priority_queue(InputIterator first, InputIterator last, const Compare& x)
-      : c(first, last), comp(x) { make_heap(c.begin(), c.end(), comp); }
-    template <class InputIterator>
-    priority_queue(InputIterator first, InputIterator last) 
-      : c(first, last) { make_heap(c.begin(), c.end(), comp); }
-#else /* __STL_MEMBER_TEMPLATES */
-    priority_queue(const value_type* first, const value_type* last, 
-                   const Compare& x) : c(first, last), comp(x) {
-        make_heap(c.begin(), c.end(), comp);
-    }
-    priority_queue(const value_type* first, const value_type* last) 
-      : c(first, last) { make_heap(c.begin(), c.end(), comp); }
-#endif /* __STL_MEMBER_TEMPLATES */
-
-    bool empty() const { return c.empty(); }
-    size_type size() const { return c.size(); }
-    const value_type& top() const { return c.front(); }
-    void push(const value_type& x) {
-#         ifdef __STL_USE_EXCEPTIONS
-      try {
-#         endif /* __STL_USE_EXCEPTIONS */
-        c.push_back(x); 
-        push_heap(c.begin(), c.end(), comp);
-#         ifdef __STL_USE_EXCEPTIONS
-      }
-      catch(...) {
-        c.clear();
-        throw;
-      }
-#         endif /* __STL_USE_EXCEPTIONS */
-    }
-    void pop() {
-#         ifdef __STL_USE_EXCEPTIONS
-      try {
-#         endif /* __STL_USE_EXCEPTIONS */
-        pop_heap(c.begin(), c.end(), comp);
-        c.pop_back();
-#         ifdef __STL_USE_EXCEPTIONS
-      }
-      catch(...) {
-        c.clear();
-        throw;
-      }
-#         endif /* __STL_USE_EXCEPTIONS */
-    }
-};
+#ifdef __STL_USE_NAMESPACES
+using __STD::stack;
+using __STD::queue;
+using __STD::priority_queue;
+#endif /* __STL_USE_NAMESPACES */
 
-// no equality is provided
+#endif /* __SGI_STL_STACK_H */
 
-#endif
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_algo.h b/libstdc++/stl/stl_algo.h
new file mode 100644 (file)
index 0000000..6703c2a
--- /dev/null
@@ -0,0 +1,2674 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_ALGO_H
+#define __SGI_STL_INTERNAL_ALGO_H
+
+#include <stl_heap.h>
+
+__STL_BEGIN_NAMESPACE
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1209
+#endif
+
+template <class T>
+inline const T& __median(const T& a, const T& b, const T& c) {
+  if (a < b)
+    if (b < c)
+      return b;
+    else if (a < c)
+      return c;
+    else
+      return a;
+  else if (a < c)
+    return a;
+  else if (b < c)
+    return c;
+  else
+    return b;
+}
+
+template <class T, class Compare>
+inline const T& __median(const T& a, const T& b, const T& c, Compare comp) {
+  if (comp(a, b))
+    if (comp(b, c))
+      return b;
+    else if (comp(a, c))
+      return c;
+    else
+      return a;
+  else if (comp(a, c))
+    return a;
+  else if (comp(b, c))
+    return c;
+  else
+    return b;
+}
+
+template <class InputIterator, class Function>
+Function for_each(InputIterator first, InputIterator last, Function f) {
+  for ( ; first != last; ++first)
+    f(*first);
+  return f;
+}
+
+template <class InputIterator, class T>
+InputIterator find(InputIterator first, InputIterator last, const T& value) {
+  while (first != last && *first != value) ++first;
+  return first;
+}
+
+template <class InputIterator, class Predicate>
+InputIterator find_if(InputIterator first, InputIterator last,
+                      Predicate pred) {
+  while (first != last && !pred(*first)) ++first;
+  return first;
+}
+
+template <class ForwardIterator>
+ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last) {
+  if (first == last) return last;
+  ForwardIterator next = first;
+  while(++next != last) {
+    if (*first == *next) return first;
+    first = next;
+  }
+  return last;
+}
+
+template <class ForwardIterator, class BinaryPredicate>
+ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last,
+                              BinaryPredicate binary_pred) {
+  if (first == last) return last;
+  ForwardIterator next = first;
+  while(++next != last) {
+    if (binary_pred(*first, *next)) return first;
+    first = next;
+  }
+  return last;
+}
+
+template <class InputIterator, class T, class Size>
+void count(InputIterator first, InputIterator last, const T& value,
+           Size& n) {
+  for ( ; first != last; ++first)
+    if (*first == value)
+      ++n;
+}
+
+template <class InputIterator, class Predicate, class Size>
+void count_if(InputIterator first, InputIterator last, Predicate pred,
+              Size& n) {
+  for ( ; first != last; ++first)
+    if (pred(*first))
+      ++n;
+}
+
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+template <class InputIterator, class T>
+typename iterator_traits<InputIterator>::difference_type
+count(InputIterator first, InputIterator last, const T& value) {
+  typename iterator_traits<InputIterator>::difference_type n = 0;
+  for ( ; first != last; ++first)
+    if (*first == value)
+      ++n;
+  return n;
+}
+
+template <class InputIterator, class Predicate>
+typename iterator_traits<InputIterator>::difference_type
+count_if(InputIterator first, InputIterator last, Predicate pred) {
+  typename iterator_traits<InputIterator>::difference_type n = 0;
+  for ( ; first != last; ++first)
+    if (pred(*first))
+      ++n;
+  return n;
+}
+
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+template <class ForwardIterator1, class ForwardIterator2, class Distance1,
+          class Distance2>
+ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1,
+                          ForwardIterator2 first2, ForwardIterator2 last2,
+                          Distance1*, Distance2*) {
+  Distance1 d1 = 0;
+  distance(first1, last1, d1);
+  Distance2 d2 = 0;
+  distance(first2, last2, d2);
+
+  if (d1 < d2) return last1;
+
+  ForwardIterator1 current1 = first1;
+  ForwardIterator2 current2 = first2;
+
+  while (current2 != last2) 
+    if (*current1 == *current2) {
+      ++current1;
+      ++current2;
+    }
+    else {
+      if (d1 == d2)
+        return last1;
+      else {
+        current1 = ++first1;
+        current2 = first2;
+        --d1;
+      }
+    }
+  return first1;
+}
+
+template <class ForwardIterator1, class ForwardIterator2>
+inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
+                               ForwardIterator2 first2, ForwardIterator2 last2)
+{
+  return __search(first1, last1, first2, last2, distance_type(first1),
+                  distance_type(first2));
+}
+
+template <class ForwardIterator1, class ForwardIterator2,
+          class BinaryPredicate, class Distance1, class Distance2>
+ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1,
+                          ForwardIterator2 first2, ForwardIterator2 last2,
+                          BinaryPredicate binary_pred, Distance1*, Distance2*) {
+  Distance1 d1 = 0;
+  distance(first1, last1, d1);
+  Distance2 d2 = 0;
+  distance(first2, last2, d2);
+
+  if (d1 < d2) return last1;
+
+  ForwardIterator1 current1 = first1;
+  ForwardIterator2 current2 = first2;
+
+  while (current2 != last2)
+    if (binary_pred(*current1, *current2)) {
+      ++current1;
+      ++current2;
+    }
+    else {
+      if (d1 == d2)
+        return last1;
+      else {
+        current1 = ++first1;
+        current2 = first2;
+        --d1;
+      }
+    }
+  return first1;
+}
+
+template <class ForwardIterator1, class ForwardIterator2,
+          class BinaryPredicate>
+inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1,
+                               ForwardIterator2 first2, ForwardIterator2 last2,
+                               BinaryPredicate binary_pred) {
+  return __search(first1, last1, first2, last2, binary_pred,
+                  distance_type(first1), distance_type(first2));
+}
+
+template <class ForwardIterator, class Integer, class T>
+ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
+                         Integer count, const T& value) {
+  if (count <= 0)
+    return first;
+  else {
+    first = find(first, last, value);
+    while (first != last) {
+      Integer n = count - 1;
+      ForwardIterator i = first;
+      ++i;
+      while (i != last && n != 0 && *i == value) {
+        ++i;
+        --n;
+      }
+      if (n == 0)
+        return first;
+      else
+        first = find(i, last, value);
+    }
+    return last;
+  }
+}
+
+template <class ForwardIterator, class Integer, class T, class BinaryPredicate>
+ForwardIterator search_n(ForwardIterator first, ForwardIterator last,
+                         Integer count, const T& value,
+                         BinaryPredicate binary_pred) {
+  if (count <= 0)
+    return first;
+  else {
+    while (first != last) {
+      if (binary_pred(*first, value)) break;
+      ++first;
+    }
+    while (first != last) {
+      Integer n = count - 1;
+      ForwardIterator i = first;
+      ++i;
+      while (i != last && n != 0 && binary_pred(*i, value)) {
+        ++i;
+        --n;
+      }
+      if (n == 0)
+        return first;
+      else {
+        while (i != last) {
+          if (binary_pred(*i, value)) break;
+          ++i;
+        }
+        first = i;
+      }
+    }
+    return last;
+  }
+} 
+
+template <class ForwardIterator1, class ForwardIterator2>
+ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1,
+                             ForwardIterator2 first2) {
+  for ( ; first1 != last1; ++first1, ++first2)
+    iter_swap(first1, first2);
+  return first2;
+}
+
+template <class InputIterator, class OutputIterator, class UnaryOperation>
+OutputIterator transform(InputIterator first, InputIterator last,
+                         OutputIterator result, UnaryOperation op) {
+  for ( ; first != last; ++first, ++result)
+    *result = op(*first);
+  return result;
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator,
+          class BinaryOperation>
+OutputIterator transform(InputIterator1 first1, InputIterator1 last1,
+                         InputIterator2 first2, OutputIterator result,
+                         BinaryOperation binary_op) {
+  for ( ; first1 != last1; ++first1, ++first2, ++result)
+    *result = binary_op(*first1, *first2);
+  return result;
+}
+
+template <class ForwardIterator, class T>
+void replace(ForwardIterator first, ForwardIterator last, const T& old_value,
+             const T& new_value) {
+  for ( ; first != last; ++first)
+    if (*first == old_value) *first = new_value;
+}
+
+template <class ForwardIterator, class Predicate, class T>
+void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred,
+                const T& new_value) {
+  for ( ; first != last; ++first)
+    if (pred(*first)) *first = new_value;
+}
+
+template <class InputIterator, class OutputIterator, class T>
+OutputIterator replace_copy(InputIterator first, InputIterator last,
+                            OutputIterator result, const T& old_value,
+                            const T& new_value) {
+  for ( ; first != last; ++first, ++result)
+    *result = *first == old_value ? new_value : *first;
+  return result;
+}
+
+template <class Iterator, class OutputIterator, class Predicate, class T>
+OutputIterator replace_copy_if(Iterator first, Iterator last,
+                               OutputIterator result, Predicate pred,
+                               const T& new_value) {
+  for ( ; first != last; ++first, ++result)
+    *result = pred(*first) ? new_value : *first;
+  return result;
+}
+
+template <class ForwardIterator, class Generator>
+void generate(ForwardIterator first, ForwardIterator last, Generator gen) {
+  for ( ; first != last; ++first)
+    *first = gen();
+}
+
+template <class OutputIterator, class Size, class Generator>
+OutputIterator generate_n(OutputIterator first, Size n, Generator gen) {
+  for ( ; n > 0; --n, ++first)
+    *first = gen();
+  return first;
+}
+
+template <class InputIterator, class OutputIterator, class T>
+OutputIterator remove_copy(InputIterator first, InputIterator last,
+                           OutputIterator result, const T& value) {
+  for ( ; first != last; ++first)
+    if (*first != value) {
+      *result = *first;
+      ++result;
+    }
+  return result;
+}
+
+template <class InputIterator, class OutputIterator, class Predicate>
+OutputIterator remove_copy_if(InputIterator first, InputIterator last,
+                              OutputIterator result, Predicate pred) {
+  for ( ; first != last; ++first)
+    if (!pred(*first)) {
+      *result = *first;
+      ++result;
+    }
+  return result;
+}
+
+template <class ForwardIterator, class T>
+ForwardIterator remove(ForwardIterator first, ForwardIterator last,
+                       const T& value) {
+  first = find(first, last, value);
+  ForwardIterator next = first;
+  return first == last ? first : remove_copy(++next, last, first, value);
+}
+
+template <class ForwardIterator, class Predicate>
+ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
+                          Predicate pred) {
+  first = find_if(first, last, pred);
+  ForwardIterator next = first;
+  return first == last ? first : remove_copy_if(++next, last, first, pred);
+}
+
+template <class InputIterator, class ForwardIterator>
+ForwardIterator __unique_copy(InputIterator first, InputIterator last,
+                              ForwardIterator result, forward_iterator_tag) {
+  *result = *first;
+  while (++first != last)
+    if (*result != *first) *++result = *first;
+  return ++result;
+}
+
+
+template <class InputIterator, class OutputIterator, class T>
+OutputIterator __unique_copy(InputIterator first, InputIterator last,
+                             OutputIterator result, T*) {
+  T value = *first;
+  *result = value;
+  while (++first != last)
+    if (value != *first) {
+      value = *first;
+      *++result = value;
+    }
+  return ++result;
+}
+
+template <class InputIterator, class OutputIterator>
+inline OutputIterator __unique_copy(InputIterator first, InputIterator last,
+                                    OutputIterator result, 
+                                    output_iterator_tag) {
+  return __unique_copy(first, last, result, value_type(first));
+}
+
+template <class InputIterator, class OutputIterator>
+inline OutputIterator unique_copy(InputIterator first, InputIterator last,
+                                  OutputIterator result) {
+  if (first == last) return result;
+  return __unique_copy(first, last, result, iterator_category(result));
+}
+template <class InputIterator, class ForwardIterator, class BinaryPredicate>
+ForwardIterator __unique_copy(InputIterator first, InputIterator last,
+                              ForwardIterator result, 
+                              BinaryPredicate binary_pred,
+                              forward_iterator_tag) {
+  *result = *first;
+  while (++first != last)
+    if (!binary_pred(*result, *first)) *++result = *first;
+  return ++result;
+}
+
+template <class InputIterator, class OutputIterator, class BinaryPredicate,
+          class T>
+OutputIterator __unique_copy(InputIterator first, InputIterator last,
+                             OutputIterator result,
+                             BinaryPredicate binary_pred, T*) {
+  T value = *first;
+  *result = value;
+  while (++first != last)
+    if (!binary_pred(value, *first)) {
+      value = *first;
+      *++result = value;
+    }
+  return ++result;
+}
+
+template <class InputIterator, class OutputIterator, class BinaryPredicate>
+inline OutputIterator __unique_copy(InputIterator first, InputIterator last,
+                                    OutputIterator result,
+                                    BinaryPredicate binary_pred,
+                                    output_iterator_tag) {
+  return __unique_copy(first, last, result, binary_pred, value_type(first));
+}
+
+template <class InputIterator, class OutputIterator, class BinaryPredicate>
+inline OutputIterator unique_copy(InputIterator first, InputIterator last,
+                                  OutputIterator result,
+                                  BinaryPredicate binary_pred) {
+  if (first == last) return result;
+  return __unique_copy(first, last, result, binary_pred,
+                       iterator_category(result));
+}
+
+template <class ForwardIterator>
+ForwardIterator unique(ForwardIterator first, ForwardIterator last) {
+  first = adjacent_find(first, last);
+  return unique_copy(first, last, first);
+}
+
+template <class ForwardIterator, class BinaryPredicate>
+ForwardIterator unique(ForwardIterator first, ForwardIterator last,
+                       BinaryPredicate binary_pred) {
+  first = adjacent_find(first, last, binary_pred);
+  return unique_copy(first, last, first, binary_pred);
+}
+
+template <class BidirectionalIterator>
+void __reverse(BidirectionalIterator first, BidirectionalIterator last, 
+               bidirectional_iterator_tag) {
+  while (true)
+    if (first == last || first == --last)
+      return;
+    else
+      iter_swap(first++, last);
+}
+
+template <class RandomAccessIterator>
+void __reverse(RandomAccessIterator first, RandomAccessIterator last,
+               random_access_iterator_tag) {
+  while (first < last) iter_swap(first++, --last);
+}
+
+template <class BidirectionalIterator>
+inline void reverse(BidirectionalIterator first, BidirectionalIterator last) {
+  __reverse(first, last, iterator_category(first));
+}
+
+template <class BidirectionalIterator, class OutputIterator>
+OutputIterator reverse_copy(BidirectionalIterator first,
+                            BidirectionalIterator last,
+                            OutputIterator result) {
+  while (first != last) {
+    --last;
+    *result = *last;
+    ++result;
+  }
+  return result;
+}
+
+template <class ForwardIterator, class Distance>
+void __rotate(ForwardIterator first, ForwardIterator middle,
+              ForwardIterator last, Distance*, forward_iterator_tag) {
+  for (ForwardIterator i = middle; ;) {
+    iter_swap(first, i);
+    ++first;
+    ++i;
+    if (first == middle) {
+      if (i == last) return;
+      middle = i;
+    }
+    else if (i == last)
+      i = middle;
+  }
+}
+
+template <class BidirectionalIterator, class Distance>
+void __rotate(BidirectionalIterator first, BidirectionalIterator middle,
+              BidirectionalIterator last, Distance*,
+              bidirectional_iterator_tag) {
+  reverse(first, middle);
+  reverse(middle, last);
+  reverse(first, last);
+}
+
+template <class EuclideanRingElement>
+EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n)
+{
+  while (n != 0) {
+    EuclideanRingElement t = m % n;
+    m = n;
+    n = t;
+  }
+  return m;
+}
+
+template <class RandomAccessIterator, class Distance, class T>
+void __rotate_cycle(RandomAccessIterator first, RandomAccessIterator last,
+                    RandomAccessIterator initial, Distance shift, T*) {
+  T value = *initial;
+  RandomAccessIterator ptr1 = initial;
+  RandomAccessIterator ptr2 = ptr1 + shift;
+  while (ptr2 != initial) {
+    *ptr1 = *ptr2;
+    ptr1 = ptr2;
+    if (last - ptr2 > shift)
+      ptr2 += shift;
+    else
+      ptr2 = first + (shift - (last - ptr2));
+  }
+  *ptr1 = value;
+}
+
+template <class RandomAccessIterator, class Distance>
+void __rotate(RandomAccessIterator first, RandomAccessIterator middle,
+              RandomAccessIterator last, Distance*,
+              random_access_iterator_tag) {
+  Distance n = __gcd(last - first, middle - first);
+  while (n--)
+    __rotate_cycle(first, last, first + n, middle - first,
+                   value_type(first));
+}
+
+template <class ForwardIterator>
+inline void rotate(ForwardIterator first, ForwardIterator middle,
+                   ForwardIterator last) {
+  if (first == middle || middle == last) return;
+  __rotate(first, middle, last, distance_type(first),
+           iterator_category(first));
+}
+
+template <class ForwardIterator, class OutputIterator>
+OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle,
+                           ForwardIterator last, OutputIterator result) {
+  return copy(first, middle, copy(middle, last, result));
+}
+
+template <class RandomAccessIterator, class Distance>
+void __random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
+                      Distance*) {
+  if (first == last) return;
+  for (RandomAccessIterator i = first + 1; i != last; ++i) 
+#ifdef __STL_NO_DRAND48
+    iter_swap(i, first + Distance(rand() % ((i - first) + 1)));
+#else
+  iter_swap(i, first + Distance(lrand48() % ((i - first) + 1)));
+#endif
+}
+
+template <class RandomAccessIterator>
+inline void random_shuffle(RandomAccessIterator first,
+                           RandomAccessIterator last) {
+  __random_shuffle(first, last, distance_type(first));
+}
+
+template <class RandomAccessIterator, class RandomNumberGenerator>
+void random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
+                    RandomNumberGenerator& rand) {
+  if (first == last) return;
+  for (RandomAccessIterator i = first + 1; i != last; ++i)
+    iter_swap(i, first + rand((i - first) + 1));
+}
+
+template <class ForwardIterator, class OutputIterator, class Distance>
+OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last,
+                               OutputIterator out, const Distance n)
+{
+  Distance remaining = 0;
+  distance(first, last, remaining);
+  Distance m = min(n, remaining);
+
+  while (m > 0) {
+#ifdef __STL_NO_DRAND48
+    if (rand() % remaining < m) {
+#else
+    if (lrand48() % remaining < m) {
+#endif
+      *out = *first;
+      ++out;
+      --m;
+    }
+
+    --remaining;
+    ++first;
+  }
+  return out;
+}
+
+template <class ForwardIterator, class OutputIterator, class Distance,
+          class RandomNumberGenerator>
+OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last,
+                               OutputIterator out, const Distance n,
+                               RandomNumberGenerator& rand)
+{
+  Distance remaining = 0;
+  distance(first, last, remaining);
+  Distance m = min(n, remaining);
+
+  while (m > 0) {
+    if (rand(remaining) < m) {
+      *out = *first;
+      ++out;
+      --m;
+    }
+
+    --remaining;
+    ++first;
+  }
+  return out;
+}
+
+template <class InputIterator, class RandomAccessIterator, class Distance>
+RandomAccessIterator __random_sample(InputIterator first, InputIterator last,
+                                     RandomAccessIterator out,
+                                     const Distance n)
+{
+  Distance m = 0;
+  Distance t = n;
+  for ( ; first != last && m < n; ++m, ++first) 
+    out[m] = *first;
+
+  while (first != last) {
+    ++t;
+#ifdef __STL_NO_DRAND48
+    Distance M = rand() % t;
+#else
+    Distance M = lrand48() % t;
+#endif
+    if (M < n)
+      out[M] = *first;
+    ++first;
+  }
+
+  return out + m;
+}
+
+template <class InputIterator, class RandomAccessIterator,
+          class RandomNumberGenerator, class Distance>
+RandomAccessIterator __random_sample(InputIterator first, InputIterator last,
+                                     RandomAccessIterator out,
+                                     RandomNumberGenerator& rand,
+                                     const Distance n)
+{
+  Distance m = 0;
+  Distance t = n;
+  for ( ; first != last && m < n; ++m, ++first)
+    out[m] = *first;
+
+  while (first != last) {
+    ++t;
+    Distance M = rand(t);
+    if (M < n)
+      out[M] = *first;
+    ++first;
+  }
+
+  return out + m;
+}
+
+template <class InputIterator, class RandomAccessIterator>
+inline RandomAccessIterator
+random_sample(InputIterator first, InputIterator last,
+              RandomAccessIterator out_first, RandomAccessIterator out_last) 
+{
+  return __random_sample(first, last, out_first, out_last - out_first);
+}
+
+template <class InputIterator, class RandomAccessIterator, 
+          class RandomNumberGenerator>
+inline RandomAccessIterator
+random_sample(InputIterator first, InputIterator last,
+              RandomAccessIterator out_first, RandomAccessIterator out_last,
+              RandomNumberGenerator& rand) 
+{
+  return __random_sample(first, last, out_first, rand, out_last - out_first);
+}
+
+
+
+template <class BidirectionalIterator, class Predicate>
+BidirectionalIterator partition(BidirectionalIterator first,
+                                BidirectionalIterator last, Predicate pred) {
+  while (true) {
+    while (true)
+      if (first == last)
+        return first;
+      else if (pred(*first))
+        ++first;
+      else
+        break;
+    --last;
+    while (true)
+      if (first == last)
+        return first;
+      else if (!pred(*last))
+        --last;
+      else
+        break;
+    iter_swap(first, last);
+    ++first;
+  }
+}
+
+template <class ForwardIterator, class Predicate, class Distance>
+ForwardIterator __inplace_stable_partition(ForwardIterator first,
+                                           ForwardIterator last,
+                                           Predicate pred, Distance len) {
+  if (len == 1) return pred(*first) ? last : first;
+  ForwardIterator middle = first;
+  advance(middle, len / 2);
+  ForwardIterator 
+    first_cut = __inplace_stable_partition(first, middle, pred, len / 2);
+  ForwardIterator 
+    second_cut = __inplace_stable_partition(middle, last, pred,
+                                            len - len / 2);
+  rotate(first_cut, middle, second_cut);
+  len = 0;
+  distance(middle, second_cut, len);
+  advance(first_cut, len);
+  return first_cut;
+}
+
+template <class ForwardIterator, class Pointer, class Predicate, 
+          class Distance>
+ForwardIterator __stable_partition_adaptive(ForwardIterator first,
+                                            ForwardIterator last,
+                                            Predicate pred, Distance len,
+                                            Pointer buffer,
+                                            Distance buffer_size) {
+  if (len <= buffer_size) {
+    ForwardIterator result1 = first;
+    Pointer result2 = buffer;
+    for ( ; first != last ; ++first)
+      if (pred(*first)) {
+        *result1 = *first;
+        ++result1;
+      }
+      else {
+        *result2 = *first;
+        ++result2;
+      }
+    copy(buffer, result2, result1);
+    return result1;
+  }
+  else {
+    ForwardIterator middle = first;
+    advance(middle, len / 2);
+    ForwardIterator first_cut =
+      __stable_partition_adaptive(first, middle, pred, len / 2,
+                                  buffer, buffer_size);
+    ForwardIterator second_cut =
+      __stable_partition_adaptive(middle, last, pred, len - len / 2,
+                                  buffer, buffer_size);
+
+    rotate(first_cut, middle, second_cut);
+    len = 0;
+    distance(middle, second_cut, len);
+    advance(first_cut, len);
+    return first_cut;
+  }
+}
+
+template <class ForwardIterator, class Predicate, class T, class Distance>
+inline ForwardIterator __stable_partition_aux(ForwardIterator first,
+                                              ForwardIterator last, 
+                                              Predicate pred, T*, Distance*) {
+  temporary_buffer<ForwardIterator, T> buf(first, last);
+  if (buf.size() > 0)
+    return __stable_partition_adaptive(first, last, pred,
+                                       Distance(buf.requested_size()),
+                                       buf.begin(), buf.size());
+  else
+    return __inplace_stable_partition(first, last, pred, 
+                                      Distance(buf.requested_size()));
+}
+
+template <class ForwardIterator, class Predicate>
+inline ForwardIterator stable_partition(ForwardIterator first,
+                                        ForwardIterator last, 
+                                        Predicate pred) {
+  if (first == last)
+    return first;
+  else
+    return __stable_partition_aux(first, last, pred,
+                                  value_type(first), distance_type(first));
+}
+
+template <class RandomAccessIterator, class T>
+RandomAccessIterator __unguarded_partition(RandomAccessIterator first, 
+                                           RandomAccessIterator last, 
+                                           T pivot) {
+  while (true) {
+    while (*first < pivot) ++first;
+    --last;
+    while (pivot < *last) --last;
+    if (!(first < last)) return first;
+    iter_swap(first, last);
+    ++first;
+  }
+}    
+
+template <class RandomAccessIterator, class T, class Compare>
+RandomAccessIterator __unguarded_partition(RandomAccessIterator first, 
+                                           RandomAccessIterator last, 
+                                           T pivot, Compare comp) {
+  while (1) {
+    while (comp(*first, pivot)) ++first;
+    --last;
+    while (comp(pivot, *last)) --last;
+    if (!(first < last)) return first;
+    iter_swap(first, last);
+    ++first;
+  }
+}
+
+const int __stl_threshold = 16;
+
+
+template <class RandomAccessIterator, class T>
+void __unguarded_linear_insert(RandomAccessIterator last, T value) {
+  RandomAccessIterator next = last;
+  --next;
+  while (value < *next) {
+    *last = *next;
+    last = next;
+    --next;
+  }
+  *last = value;
+}
+
+template <class RandomAccessIterator, class T, class Compare>
+void __unguarded_linear_insert(RandomAccessIterator last, T value, 
+                               Compare comp) {
+  RandomAccessIterator next = last;
+  --next;  
+  while (comp(value , *next)) {
+    *last = *next;
+    last = next;
+    --next;
+  }
+  *last = value;
+}
+
+template <class RandomAccessIterator, class T>
+inline void __linear_insert(RandomAccessIterator first, 
+                            RandomAccessIterator last, T*) {
+  T value = *last;
+  if (value < *first) {
+    copy_backward(first, last, last + 1);
+    *first = value;
+  }
+  else
+    __unguarded_linear_insert(last, value);
+}
+
+template <class RandomAccessIterator, class T, class Compare>
+inline void __linear_insert(RandomAccessIterator first, 
+                            RandomAccessIterator last, T*, Compare comp) {
+  T value = *last;
+  if (comp(value, *first)) {
+    copy_backward(first, last, last + 1);
+    *first = value;
+  }
+  else
+    __unguarded_linear_insert(last, value, comp);
+}
+
+template <class RandomAccessIterator>
+void __insertion_sort(RandomAccessIterator first, RandomAccessIterator last) {
+  if (first == last) return; 
+  for (RandomAccessIterator i = first + 1; i != last; ++i)
+    __linear_insert(first, i, value_type(first));
+}
+
+template <class RandomAccessIterator, class Compare>
+void __insertion_sort(RandomAccessIterator first,
+                      RandomAccessIterator last, Compare comp) {
+  if (first == last) return;
+  for (RandomAccessIterator i = first + 1; i != last; ++i)
+    __linear_insert(first, i, value_type(first), comp);
+}
+
+template <class RandomAccessIterator, class T>
+void __unguarded_insertion_sort_aux(RandomAccessIterator first, 
+                                    RandomAccessIterator last, T*) {
+  for (RandomAccessIterator i = first; i != last; ++i)
+    __unguarded_linear_insert(i, T(*i));
+}
+
+template <class RandomAccessIterator>
+inline void __unguarded_insertion_sort(RandomAccessIterator first, 
+                                RandomAccessIterator last) {
+  __unguarded_insertion_sort_aux(first, last, value_type(first));
+}
+
+template <class RandomAccessIterator, class T, class Compare>
+void __unguarded_insertion_sort_aux(RandomAccessIterator first, 
+                                    RandomAccessIterator last,
+                                    T*, Compare comp) {
+  for (RandomAccessIterator i = first; i != last; ++i)
+    __unguarded_linear_insert(i, T(*i), comp);
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void __unguarded_insertion_sort(RandomAccessIterator first, 
+                                       RandomAccessIterator last,
+                                       Compare comp) {
+  __unguarded_insertion_sort_aux(first, last, value_type(first), comp);
+}
+
+template <class RandomAccessIterator>
+void __final_insertion_sort(RandomAccessIterator first, 
+                            RandomAccessIterator last) {
+  if (last - first > __stl_threshold) {
+    __insertion_sort(first, first + __stl_threshold);
+    __unguarded_insertion_sort(first + __stl_threshold, last);
+  }
+  else
+    __insertion_sort(first, last);
+}
+
+template <class RandomAccessIterator, class Compare>
+void __final_insertion_sort(RandomAccessIterator first, 
+                            RandomAccessIterator last, Compare comp) {
+  if (last - first > __stl_threshold) {
+    __insertion_sort(first, first + __stl_threshold, comp);
+    __unguarded_insertion_sort(first + __stl_threshold, last, comp);
+  }
+  else
+    __insertion_sort(first, last, comp);
+}
+
+template <class Size>
+inline Size __lg(Size n) {
+  Size k;
+  for (k = 0; n != 1; n >>= 1) ++k;
+  return k;
+}
+
+template <class RandomAccessIterator, class T, class Size>
+void __introsort_loop(RandomAccessIterator first,
+                      RandomAccessIterator last, T*,
+                      Size depth_limit) {
+  while (last - first > __stl_threshold) {
+    if (depth_limit == 0) {
+      partial_sort(first, last, last);
+      return;
+    }
+    --depth_limit;
+    RandomAccessIterator cut = __unguarded_partition
+      (first, last, T(__median(*first, *(first + (last - first)/2),
+                               *(last - 1))));
+    __introsort_loop(cut, last, value_type(first), depth_limit);
+    last = cut;
+  }
+}
+
+template <class RandomAccessIterator, class T, class Size, class Compare>
+void __introsort_loop(RandomAccessIterator first,
+                      RandomAccessIterator last, T*,
+                      Size depth_limit, Compare comp) {
+  while (last - first > __stl_threshold) {
+    if (depth_limit == 0) {
+      partial_sort(first, last, last, comp);
+      return;
+    }
+    --depth_limit;
+    RandomAccessIterator cut = __unguarded_partition
+      (first, last, T(__median(*first, *(first + (last - first)/2),
+                               *(last - 1), comp)), comp);
+    __introsort_loop(cut, last, value_type(first), depth_limit, comp);
+    last = cut;
+  }
+}
+
+template <class RandomAccessIterator>
+inline void sort(RandomAccessIterator first, RandomAccessIterator last) {
+  if (first != last) {
+    __introsort_loop(first, last, value_type(first), __lg(last - first) * 2);
+    __final_insertion_sort(first, last);
+  }
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void sort(RandomAccessIterator first, RandomAccessIterator last,
+                 Compare comp) {
+  if (first != last) {
+    __introsort_loop(first, last, value_type(first), __lg(last - first) * 2,
+                     comp);
+    __final_insertion_sort(first, last, comp);
+  }
+}
+
+
+template <class RandomAccessIterator>
+void __inplace_stable_sort(RandomAccessIterator first,
+                           RandomAccessIterator last) {
+  if (last - first < 15) {
+    __insertion_sort(first, last);
+    return;
+  }
+  RandomAccessIterator middle = first + (last - first) / 2;
+  __inplace_stable_sort(first, middle);
+  __inplace_stable_sort(middle, last);
+  __merge_without_buffer(first, middle, last, middle - first, last - middle);
+}
+
+template <class RandomAccessIterator, class Compare>
+void __inplace_stable_sort(RandomAccessIterator first,
+                           RandomAccessIterator last, Compare comp) {
+  if (last - first < 15) {
+    __insertion_sort(first, last, comp);
+    return;
+  }
+  RandomAccessIterator middle = first + (last - first) / 2;
+  __inplace_stable_sort(first, middle, comp);
+  __inplace_stable_sort(middle, last, comp);
+  __merge_without_buffer(first, middle, last, middle - first,
+                         last - middle, comp);
+}
+
+template <class RandomAccessIterator1, class RandomAccessIterator2,
+          class Distance>
+void __merge_sort_loop(RandomAccessIterator1 first,
+                       RandomAccessIterator1 last, 
+                       RandomAccessIterator2 result, Distance step_size) {
+  Distance two_step = 2 * step_size;
+
+  while (last - first >= two_step) {
+    result = merge(first, first + step_size,
+                   first + step_size, first + two_step, result);
+    first += two_step;
+  }
+
+  step_size = min(Distance(last - first), step_size);
+  merge(first, first + step_size, first + step_size, last, result);
+}
+
+template <class RandomAccessIterator1, class RandomAccessIterator2,
+          class Distance, class Compare>
+void __merge_sort_loop(RandomAccessIterator1 first,
+                       RandomAccessIterator1 last, 
+                       RandomAccessIterator2 result, Distance step_size,
+                       Compare comp) {
+  Distance two_step = 2 * step_size;
+
+  while (last - first >= two_step) {
+    result = merge(first, first + step_size,
+                   first + step_size, first + two_step, result, comp);
+    first += two_step;
+  }
+  step_size = min(Distance(last - first), step_size);
+
+  merge(first, first + step_size, first + step_size, last, result, comp);
+}
+
+const int __stl_chunk_size = 7;
+        
+template <class RandomAccessIterator, class Distance>
+void __chunk_insertion_sort(RandomAccessIterator first, 
+                            RandomAccessIterator last, Distance chunk_size) {
+  while (last - first >= chunk_size) {
+    __insertion_sort(first, first + chunk_size);
+    first += chunk_size;
+  }
+  __insertion_sort(first, last);
+}
+
+template <class RandomAccessIterator, class Distance, class Compare>
+void __chunk_insertion_sort(RandomAccessIterator first, 
+                            RandomAccessIterator last,
+                            Distance chunk_size, Compare comp) {
+  while (last - first >= chunk_size) {
+    __insertion_sort(first, first + chunk_size, comp);
+    first += chunk_size;
+  }
+  __insertion_sort(first, last, comp);
+}
+
+template <class RandomAccessIterator, class Pointer, class Distance>
+void __merge_sort_with_buffer(RandomAccessIterator first, 
+                              RandomAccessIterator last,
+                              Pointer buffer, Distance*) {
+  Distance len = last - first;
+  Pointer buffer_last = buffer + len;
+
+  Distance step_size = __stl_chunk_size;
+  __chunk_insertion_sort(first, last, step_size);
+
+  while (step_size < len) {
+    __merge_sort_loop(first, last, buffer, step_size);
+    step_size *= 2;
+    __merge_sort_loop(buffer, buffer_last, first, step_size);
+    step_size *= 2;
+  }
+}
+
+template <class RandomAccessIterator, class Pointer, class Distance,
+          class Compare>
+void __merge_sort_with_buffer(RandomAccessIterator first, 
+                              RandomAccessIterator last, Pointer buffer,
+                              Distance*, Compare comp) {
+  Distance len = last - first;
+  Pointer buffer_last = buffer + len;
+
+  Distance step_size = __stl_chunk_size;
+  __chunk_insertion_sort(first, last, step_size, comp);
+
+  while (step_size < len) {
+    __merge_sort_loop(first, last, buffer, step_size, comp);
+    step_size *= 2;
+    __merge_sort_loop(buffer, buffer_last, first, step_size, comp);
+    step_size *= 2;
+  }
+}
+
+template <class RandomAccessIterator, class Pointer, class Distance>
+void __stable_sort_adaptive(RandomAccessIterator first, 
+                            RandomAccessIterator last, Pointer buffer,
+                            Distance buffer_size) {
+  Distance len = (last - first + 1) / 2;
+  RandomAccessIterator middle = first + len;
+  if (len > buffer_size) {
+    __stable_sort_adaptive(first, middle, buffer, buffer_size);
+    __stable_sort_adaptive(middle, last, buffer, buffer_size);
+  } else {
+    __merge_sort_with_buffer(first, middle, buffer, (Distance*)0);
+    __merge_sort_with_buffer(middle, last, buffer, (Distance*)0);
+  }
+  __merge_adaptive(first, middle, last, Distance(middle - first), 
+                   Distance(last - middle), buffer, buffer_size);
+}
+
+template <class RandomAccessIterator, class Pointer, class Distance, 
+          class Compare>
+void __stable_sort_adaptive(RandomAccessIterator first, 
+                            RandomAccessIterator last, Pointer buffer,
+                            Distance buffer_size, Compare comp) {
+  Distance len = (last - first + 1) / 2;
+  RandomAccessIterator middle = first + len;
+  if (len > buffer_size) {
+    __stable_sort_adaptive(first, middle, buffer, buffer_size, 
+                           comp);
+    __stable_sort_adaptive(middle, last, buffer, buffer_size, 
+                           comp);
+  } else {
+    __merge_sort_with_buffer(first, middle, buffer, (Distance*)0, comp);
+    __merge_sort_with_buffer(middle, last, buffer, (Distance*)0, comp);
+  }
+  __merge_adaptive(first, middle, last, Distance(middle - first), 
+                   Distance(last - middle), buffer, buffer_size,
+                   comp);
+}
+
+template <class RandomAccessIterator, class T, class Distance>
+inline void __stable_sort_aux(RandomAccessIterator first,
+                              RandomAccessIterator last, T*, Distance*) {
+  temporary_buffer<RandomAccessIterator, T> buf(first, last);
+  if (buf.begin() == 0)
+    __inplace_stable_sort(first, last);
+  else 
+    __stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size()));
+}
+
+template <class RandomAccessIterator, class T, class Distance, class Compare>
+inline void __stable_sort_aux(RandomAccessIterator first,
+                              RandomAccessIterator last, T*, Distance*,
+                              Compare comp) {
+  temporary_buffer<RandomAccessIterator, T> buf(first, last);
+  if (buf.begin() == 0)
+    __inplace_stable_sort(first, last, comp);
+  else 
+    __stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size()),
+                           comp);
+}
+
+template <class RandomAccessIterator>
+inline void stable_sort(RandomAccessIterator first,
+                        RandomAccessIterator last) {
+  __stable_sort_aux(first, last, value_type(first), distance_type(first));
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void stable_sort(RandomAccessIterator first,
+                        RandomAccessIterator last, Compare comp) {
+  __stable_sort_aux(first, last, value_type(first), distance_type(first), 
+                    comp);
+}
+
+template <class RandomAccessIterator, class T>
+void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,
+                    RandomAccessIterator last, T*) {
+  make_heap(first, middle);
+  for (RandomAccessIterator i = middle; i < last; ++i)
+    if (*i < *first) 
+      __pop_heap(first, middle, i, T(*i), distance_type(first));
+  sort_heap(first, middle);
+}
+
+template <class RandomAccessIterator>
+inline void partial_sort(RandomAccessIterator first,
+                         RandomAccessIterator middle,
+                         RandomAccessIterator last) {
+  __partial_sort(first, middle, last, value_type(first));
+}
+
+template <class RandomAccessIterator, class T, class Compare>
+void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle,
+                    RandomAccessIterator last, T*, Compare comp) {
+  make_heap(first, middle, comp);
+  for (RandomAccessIterator i = middle; i < last; ++i)
+    if (comp(*i, *first))
+      __pop_heap(first, middle, i, T(*i), comp, distance_type(first));
+  sort_heap(first, middle, comp);
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void partial_sort(RandomAccessIterator first,
+                         RandomAccessIterator middle,
+                         RandomAccessIterator last, Compare comp) {
+  __partial_sort(first, middle, last, value_type(first), comp);
+}
+
+template <class InputIterator, class RandomAccessIterator, class Distance,
+          class T>
+RandomAccessIterator __partial_sort_copy(InputIterator first,
+                                         InputIterator last,
+                                         RandomAccessIterator result_first,
+                                         RandomAccessIterator result_last, 
+                                         Distance*, T*) {
+  if (result_first == result_last) return result_last;
+  RandomAccessIterator result_real_last = result_first;
+  while(first != last && result_real_last != result_last) {
+    *result_real_last = *first;
+    ++result_real_last;
+    ++first;
+  }
+  make_heap(result_first, result_real_last);
+  while (first != last) {
+    if (*first < *result_first) 
+      __adjust_heap(result_first, Distance(0),
+                    Distance(result_real_last - result_first), T(*first));
+    ++first;
+  }
+  sort_heap(result_first, result_real_last);
+  return result_real_last;
+}
+
+template <class InputIterator, class RandomAccessIterator>
+inline RandomAccessIterator
+partial_sort_copy(InputIterator first, InputIterator last,
+                  RandomAccessIterator result_first,
+                  RandomAccessIterator result_last) {
+  return __partial_sort_copy(first, last, result_first, result_last, 
+                             distance_type(result_first), value_type(first));
+}
+
+template <class InputIterator, class RandomAccessIterator, class Compare,
+          class Distance, class T>
+RandomAccessIterator __partial_sort_copy(InputIterator first,
+                                         InputIterator last,
+                                         RandomAccessIterator result_first,
+                                         RandomAccessIterator result_last,
+                                         Compare comp, Distance*, T*) {
+  if (result_first == result_last) return result_last;
+  RandomAccessIterator result_real_last = result_first;
+  while(first != last && result_real_last != result_last) {
+    *result_real_last = *first;
+    ++result_real_last;
+    ++first;
+  }
+  make_heap(result_first, result_real_last, comp);
+  while (first != last) {
+    if (comp(*first, *result_first))
+      __adjust_heap(result_first, Distance(0),
+                    Distance(result_real_last - result_first), T(*first),
+                    comp);
+    ++first;
+  }
+  sort_heap(result_first, result_real_last, comp);
+  return result_real_last;
+}
+
+template <class InputIterator, class RandomAccessIterator, class Compare>
+inline RandomAccessIterator
+partial_sort_copy(InputIterator first, InputIterator last,
+                  RandomAccessIterator result_first,
+                  RandomAccessIterator result_last, Compare comp) {
+  return __partial_sort_copy(first, last, result_first, result_last, comp,
+                             distance_type(result_first), value_type(first));
+}
+
+template <class RandomAccessIterator, class T>
+void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,
+                   RandomAccessIterator last, T*) {
+  while (last - first > 3) {
+    RandomAccessIterator cut = __unguarded_partition
+      (first, last, T(__median(*first, *(first + (last - first)/2),
+                               *(last - 1))));
+    if (cut <= nth)
+      first = cut;
+    else 
+      last = cut;
+  }
+  __insertion_sort(first, last);
+}
+
+template <class RandomAccessIterator>
+inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
+                        RandomAccessIterator last) {
+  __nth_element(first, nth, last, value_type(first));
+}
+
+template <class RandomAccessIterator, class T, class Compare>
+void __nth_element(RandomAccessIterator first, RandomAccessIterator nth,
+                   RandomAccessIterator last, T*, Compare comp) {
+  while (last - first > 3) {
+    RandomAccessIterator cut = __unguarded_partition
+      (first, last, T(__median(*first, *(first + (last - first)/2), 
+                               *(last - 1), comp)), comp);
+    if (cut <= nth)
+      first = cut;
+    else 
+      last = cut;
+  }
+  __insertion_sort(first, last, comp);
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth,
+                 RandomAccessIterator last, Compare comp) {
+  __nth_element(first, nth, last, value_type(first), comp);
+}
+
+template <class ForwardIterator, class T, class Distance>
+ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,
+                              const T& value, Distance*,
+                              forward_iterator_tag) {
+  Distance len = 0;
+  distance(first, last, len);
+  Distance half;
+  ForwardIterator middle;
+
+  while (len > 0) {
+    half = len >> 1;
+    middle = first;
+    advance(middle, half);
+    if (*middle < value) {
+      first = middle;
+      ++first;
+      len = len - half - 1;
+    }
+    else
+      len = half;
+  }
+  return first;
+}
+
+template <class RandomAccessIterator, class T, class Distance>
+RandomAccessIterator __lower_bound(RandomAccessIterator first,
+                                   RandomAccessIterator last, const T& value,
+                                   Distance*, random_access_iterator_tag) {
+  Distance len = last - first;
+  Distance half;
+  RandomAccessIterator middle;
+
+  while (len > 0) {
+    half = len >> 1;
+    middle = first + half;
+    if (*middle < value) {
+      first = middle + 1;
+      len = len - half - 1;
+    }
+    else
+      len = half;
+  }
+  return first;
+}
+
+template <class ForwardIterator, class T>
+inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
+                                   const T& value) {
+  return __lower_bound(first, last, value, distance_type(first),
+                       iterator_category(first));
+}
+
+template <class ForwardIterator, class T, class Compare, class Distance>
+ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last,
+                              const T& value, Compare comp, Distance*,
+                              forward_iterator_tag) {
+  Distance len = 0;
+  distance(first, last, len);
+  Distance half;
+  ForwardIterator middle;
+
+  while (len > 0) {
+    half = len >> 1;
+    middle = first;
+    advance(middle, half);
+    if (comp(*middle, value)) {
+      first = middle;
+      ++first;
+      len = len - half - 1;
+    }
+    else
+      len = half;
+  }
+  return first;
+}
+
+template <class RandomAccessIterator, class T, class Compare, class Distance>
+RandomAccessIterator __lower_bound(RandomAccessIterator first,
+                                   RandomAccessIterator last,
+                                   const T& value, Compare comp, Distance*,
+                                   random_access_iterator_tag) {
+  Distance len = last - first;
+  Distance half;
+  RandomAccessIterator middle;
+
+  while (len > 0) {
+    half = len >> 1;
+    middle = first + half;
+    if (comp(*middle, value)) {
+      first = middle + 1;
+      len = len - half - 1;
+    }
+    else
+      len = half;
+  }
+  return first;
+}
+
+template <class ForwardIterator, class T, class Compare>
+inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last,
+                                   const T& value, Compare comp) {
+  return __lower_bound(first, last, value, comp, distance_type(first),
+                       iterator_category(first));
+}
+
+template <class ForwardIterator, class T, class Distance>
+ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
+                              const T& value, Distance*,
+                              forward_iterator_tag) {
+  Distance len = 0;
+  distance(first, last, len);
+  Distance half;
+  ForwardIterator middle;
+
+  while (len > 0) {
+    half = len >> 1;
+    middle = first;
+    advance(middle, half);
+    if (value < *middle)
+      len = half;
+    else {
+      first = middle;
+      ++first;
+      len = len - half - 1;
+    }
+  }
+  return first;
+}
+
+template <class RandomAccessIterator, class T, class Distance>
+RandomAccessIterator __upper_bound(RandomAccessIterator first,
+                                   RandomAccessIterator last, const T& value,
+                                   Distance*, random_access_iterator_tag) {
+  Distance len = last - first;
+  Distance half;
+  RandomAccessIterator middle;
+
+  while (len > 0) {
+    half = len >> 1;
+    middle = first + half;
+    if (value < *middle)
+      len = half;
+    else {
+      first = middle + 1;
+      len = len - half - 1;
+    }
+  }
+  return first;
+}
+
+template <class ForwardIterator, class T>
+inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
+                                   const T& value) {
+  return __upper_bound(first, last, value, distance_type(first),
+                       iterator_category(first));
+}
+
+template <class ForwardIterator, class T, class Compare, class Distance>
+ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
+                              const T& value, Compare comp, Distance*,
+                              forward_iterator_tag) {
+  Distance len = 0;
+  distance(first, last, len);
+  Distance half;
+  ForwardIterator middle;
+
+  while (len > 0) {
+    half = len >> 1;
+    middle = first;
+    advance(middle, half);
+    if (comp(value, *middle))
+      len = half;
+    else {
+      first = middle;
+      ++first;
+      len = len - half - 1;
+    }
+  }
+  return first;
+}
+
+template <class RandomAccessIterator, class T, class Compare, class Distance>
+RandomAccessIterator __upper_bound(RandomAccessIterator first,
+                                   RandomAccessIterator last,
+                                   const T& value, Compare comp, Distance*,
+                                   random_access_iterator_tag) {
+  Distance len = last - first;
+  Distance half;
+  RandomAccessIterator middle;
+
+  while (len > 0) {
+    half = len >> 1;
+    middle = first + half;
+    if (comp(value, *middle))
+      len = half;
+    else {
+      first = middle + 1;
+      len = len - half - 1;
+    }
+  }
+  return first;
+}
+
+template <class ForwardIterator, class T, class Compare>
+inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
+                                   const T& value, Compare comp) {
+  return __upper_bound(first, last, value, comp, distance_type(first),
+                       iterator_category(first));
+}
+
+template <class ForwardIterator, class T, class Distance>
+pair<ForwardIterator, ForwardIterator>
+__equal_range(ForwardIterator first, ForwardIterator last, const T& value,
+              Distance*, forward_iterator_tag) {
+  Distance len = 0;
+  distance(first, last, len);
+  Distance half;
+  ForwardIterator middle, left, right;
+
+  while (len > 0) {
+    half = len >> 1;
+    middle = first;
+    advance(middle, half);
+    if (*middle < value) {
+      first = middle;
+      ++first;
+      len = len - half - 1;
+    }
+    else if (value < *middle)
+      len = half;
+    else {
+      left = lower_bound(first, middle, value);
+      advance(first, len);
+      right = upper_bound(++middle, first, value);
+      return pair<ForwardIterator, ForwardIterator>(left, right);
+    }
+  }
+  return pair<ForwardIterator, ForwardIterator>(first, first);
+}
+
+template <class RandomAccessIterator, class T, class Distance>
+pair<RandomAccessIterator, RandomAccessIterator>
+__equal_range(RandomAccessIterator first, RandomAccessIterator last,
+              const T& value, Distance*, random_access_iterator_tag) {
+  Distance len = last - first;
+  Distance half;
+  RandomAccessIterator middle, left, right;
+
+  while (len > 0) {
+    half = len >> 1;
+    middle = first + half;
+    if (*middle < value) {
+      first = middle + 1;
+      len = len - half - 1;
+    }
+    else if (value < *middle)
+      len = half;
+    else {
+      left = lower_bound(first, middle, value);
+      right = upper_bound(++middle, first + len, value);
+      return pair<RandomAccessIterator, RandomAccessIterator>(left,
+                                                              right);
+    }
+  }
+  return pair<RandomAccessIterator, RandomAccessIterator>(first, first);
+}
+
+template <class ForwardIterator, class T>
+inline pair<ForwardIterator, ForwardIterator>
+equal_range(ForwardIterator first, ForwardIterator last, const T& value) {
+  return __equal_range(first, last, value, distance_type(first),
+                       iterator_category(first));
+}
+
+template <class ForwardIterator, class T, class Compare, class Distance>
+pair<ForwardIterator, ForwardIterator>
+__equal_range(ForwardIterator first, ForwardIterator last, const T& value,
+              Compare comp, Distance*, forward_iterator_tag) {
+  Distance len = 0;
+  distance(first, last, len);
+  Distance half;
+  ForwardIterator middle, left, right;
+
+  while (len > 0) {
+    half = len >> 1;
+    middle = first;
+    advance(middle, half);
+    if (comp(*middle, value)) {
+      first = middle;
+      ++first;
+      len = len - half - 1;
+    }
+    else if (comp(value, *middle))
+      len = half;
+    else {
+      left = lower_bound(first, middle, value, comp);
+      advance(first, len);
+      right = upper_bound(++middle, first, value, comp);
+      return pair<ForwardIterator, ForwardIterator>(left, right);
+    }
+  }
+  return pair<ForwardIterator, ForwardIterator>(first, first);
+}           
+
+template <class RandomAccessIterator, class T, class Compare, class Distance>
+pair<RandomAccessIterator, RandomAccessIterator>
+__equal_range(RandomAccessIterator first, RandomAccessIterator last,
+              const T& value, Compare comp, Distance*,
+              random_access_iterator_tag) {
+  Distance len = last - first;
+  Distance half;
+  RandomAccessIterator middle, left, right;
+
+  while (len > 0) {
+    half = len >> 1;
+    middle = first + half;
+    if (comp(*middle, value)) {
+      first = middle + 1;
+      len = len - half - 1;
+    }
+    else if (comp(value, *middle))
+      len = half;
+    else {
+      left = lower_bound(first, middle, value, comp);
+      right = upper_bound(++middle, first + len, value, comp);
+      return pair<RandomAccessIterator, RandomAccessIterator>(left,
+                                                              right);
+    }
+  }
+  return pair<RandomAccessIterator, RandomAccessIterator>(first, first);
+}           
+
+template <class ForwardIterator, class T, class Compare>
+inline pair<ForwardIterator, ForwardIterator>
+equal_range(ForwardIterator first, ForwardIterator last, const T& value,
+            Compare comp) {
+  return __equal_range(first, last, value, comp, distance_type(first),
+                       iterator_category(first));
+}    
+
+template <class ForwardIterator, class T>
+bool binary_search(ForwardIterator first, ForwardIterator last,
+                   const T& value) {
+  ForwardIterator i = lower_bound(first, last, value);
+  return i != last && !(value < *i);
+}
+
+template <class ForwardIterator, class T, class Compare>
+bool binary_search(ForwardIterator first, ForwardIterator last, const T& value,
+                   Compare comp) {
+  ForwardIterator i = lower_bound(first, last, value, comp);
+  return i != last && !comp(value, *i);
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator>
+OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
+                     InputIterator2 first2, InputIterator2 last2,
+                     OutputIterator result) {
+  while (first1 != last1 && first2 != last2) {
+    if (*first2 < *first1) {
+      *result = *first2;
+      ++first2;
+    }
+    else {
+      *result = *first1;
+      ++first1;
+    }
+    ++result;
+  }
+  return copy(first2, last2, copy(first1, last1, result));
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator,
+          class Compare>
+OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
+                     InputIterator2 first2, InputIterator2 last2,
+                     OutputIterator result, Compare comp) {
+  while (first1 != last1 && first2 != last2) {
+    if (comp(*first2, *first1)) {
+      *result = *first2;
+      ++first2;
+    }
+    else {
+      *result = *first1;
+      ++first1;
+    }
+    ++result;
+  }
+  return copy(first2, last2, copy(first1, last1, result));
+}
+
+template <class BidirectionalIterator, class Distance>
+void __merge_without_buffer(BidirectionalIterator first,
+                            BidirectionalIterator middle,
+                            BidirectionalIterator last,
+                            Distance len1, Distance len2) {
+  if (len1 == 0 || len2 == 0) return;
+  if (len1 + len2 == 2) {
+    if (*middle < *first) iter_swap(first, middle);
+    return;
+  }
+  BidirectionalIterator first_cut = first;
+  BidirectionalIterator second_cut = middle;
+  Distance len11 = 0;
+  Distance len22 = 0;
+  if (len1 > len2) {
+    len11 = len1 / 2;
+    advance(first_cut, len11);
+    second_cut = lower_bound(middle, last, *first_cut);
+    distance(middle, second_cut, len22);
+  }
+  else {
+    len22 = len2 / 2;
+    advance(second_cut, len22);
+    first_cut = upper_bound(first, middle, *second_cut);
+    distance(first, first_cut, len11);
+  }
+  rotate(first_cut, middle, second_cut);
+  BidirectionalIterator new_middle = first_cut;
+  advance(new_middle, len22);
+  __merge_without_buffer(first, first_cut, new_middle, len11, len22);
+  __merge_without_buffer(new_middle, second_cut, last, len1 - len11,
+                         len2 - len22);
+}
+
+template <class BidirectionalIterator, class Distance, class Compare>
+void __merge_without_buffer(BidirectionalIterator first,
+                            BidirectionalIterator middle,
+                            BidirectionalIterator last,
+                            Distance len1, Distance len2, Compare comp) {
+  if (len1 == 0 || len2 == 0) return;
+  if (len1 + len2 == 2) {
+    if (comp(*middle, *first)) iter_swap(first, middle);
+    return;
+  }
+  BidirectionalIterator first_cut = first;
+  BidirectionalIterator second_cut = middle;
+  Distance len11 = 0;
+  Distance len22 = 0;
+  if (len1 > len2) {
+    len11 = len1 / 2;
+    advance(first_cut, len11);
+    second_cut = lower_bound(middle, last, *first_cut, comp);
+    distance(middle, second_cut, len22);
+  }
+  else {
+    len22 = len2 / 2;
+    advance(second_cut, len22);
+    first_cut = upper_bound(first, middle, *second_cut, comp);
+    distance(first, first_cut, len11);
+  }
+  rotate(first_cut, middle, second_cut);
+  BidirectionalIterator new_middle = first_cut;
+  advance(new_middle, len22);
+  __merge_without_buffer(first, first_cut, new_middle, len11, len22, comp);
+  __merge_without_buffer(new_middle, second_cut, last, len1 - len11,
+                         len2 - len22, comp);
+}
+
+template <class BidirectionalIterator1, class BidirectionalIterator2,
+          class Distance>
+BidirectionalIterator1 __rotate_adaptive(BidirectionalIterator1 first,
+                                         BidirectionalIterator1 middle,
+                                         BidirectionalIterator1 last,
+                                         Distance len1, Distance len2,
+                                         BidirectionalIterator2 buffer,
+                                         Distance buffer_size) {
+  BidirectionalIterator2 buffer_end;
+  if (len1 > len2 && len2 <= buffer_size) {
+    buffer_end = copy(middle, last, buffer);
+    copy_backward(first, middle, last);
+    return copy(buffer, buffer_end, first);
+  } else if (len1 <= buffer_size) {
+    buffer_end = copy(first, middle, buffer);
+    copy(middle, last, first);
+    return copy_backward(buffer, buffer_end, last);
+  } else  {
+    rotate(first, middle, last);
+    advance(first, len2);
+    return first;
+  }
+}
+
+template <class BidirectionalIterator1, class BidirectionalIterator2,
+          class BidirectionalIterator3>
+BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,
+                                        BidirectionalIterator1 last1,
+                                        BidirectionalIterator2 first2,
+                                        BidirectionalIterator2 last2,
+                                        BidirectionalIterator3 result) {
+  if (first1 == last1) return copy_backward(first2, last2, result);
+  if (first2 == last2) return copy_backward(first1, last1, result);
+  --last1;
+  --last2;
+  while (true) {
+    if (*last2 < *last1) {
+      *--result = *last1;
+      if (first1 == last1) return copy_backward(first2, ++last2, result);
+      --last1;
+    }
+    else {
+      *--result = *last2;
+      if (first2 == last2) return copy_backward(first1, ++last1, result);
+      --last2;
+    }
+  }
+}
+
+template <class BidirectionalIterator1, class BidirectionalIterator2,
+          class BidirectionalIterator3, class Compare>
+BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1,
+                                        BidirectionalIterator1 last1,
+                                        BidirectionalIterator2 first2,
+                                        BidirectionalIterator2 last2,
+                                        BidirectionalIterator3 result,
+                                        Compare comp) {
+  if (first1 == last1) return copy_backward(first2, last2, result);
+  if (first2 == last2) return copy_backward(first1, last1, result);
+  --last1;
+  --last2;
+  while (true) {
+    if (comp(*last2, *last1)) {
+      *--result = *last1;
+      if (first1 == last1) return copy_backward(first2, ++last2, result);
+      --last1;
+    }
+    else {
+      *--result = *last2;
+      if (first2 == last2) return copy_backward(first1, ++last1, result);
+      --last2;
+    }
+  }
+}
+
+template <class BidirectionalIterator, class Distance, class Pointer>
+void __merge_adaptive(BidirectionalIterator first, 
+                      BidirectionalIterator middle, 
+                      BidirectionalIterator last, Distance len1, Distance len2,
+                      Pointer buffer, Distance buffer_size) {
+  if (len1 <= len2 && len1 <= buffer_size) {
+    Pointer end_buffer = copy(first, middle, buffer);
+    merge(buffer, end_buffer, middle, last, first);
+  }
+  else if (len2 <= buffer_size) {
+    Pointer end_buffer = copy(middle, last, buffer);
+    __merge_backward(first, middle, buffer, end_buffer, last);
+  }
+  else {
+    BidirectionalIterator first_cut = first;
+    BidirectionalIterator second_cut = middle;
+    Distance len11 = 0;
+    Distance len22 = 0;
+    if (len1 > len2) {
+      len11 = len1 / 2;
+      advance(first_cut, len11);
+      second_cut = lower_bound(middle, last, *first_cut);
+      distance(middle, second_cut, len22);   
+    }
+    else {
+      len22 = len2 / 2;
+      advance(second_cut, len22);
+      first_cut = upper_bound(first, middle, *second_cut);
+      distance(first, first_cut, len11);
+    }
+    BidirectionalIterator new_middle =
+      __rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
+                        len22, buffer, buffer_size);
+    __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,
+                     buffer_size);
+    __merge_adaptive(new_middle, second_cut, last, len1 - len11,
+                     len2 - len22, buffer, buffer_size);
+  }
+}
+
+template <class BidirectionalIterator, class Distance, class Pointer,
+          class Compare>
+void __merge_adaptive(BidirectionalIterator first, 
+                      BidirectionalIterator middle, 
+                      BidirectionalIterator last, Distance len1, Distance len2,
+                      Pointer buffer, Distance buffer_size, Compare comp) {
+  if (len1 <= len2 && len1 <= buffer_size) {
+    Pointer end_buffer = copy(first, middle, buffer);
+    merge(buffer, end_buffer, middle, last, first, comp);
+  }
+  else if (len2 <= buffer_size) {
+    Pointer end_buffer = copy(middle, last, buffer);
+    __merge_backward(first, middle, buffer, end_buffer, last, comp);
+  }
+  else {
+    BidirectionalIterator first_cut = first;
+    BidirectionalIterator second_cut = middle;
+    Distance len11 = 0;
+    Distance len22 = 0;
+    if (len1 > len2) {
+      len11 = len1 / 2;
+      advance(first_cut, len11);
+      second_cut = lower_bound(middle, last, *first_cut, comp);
+      distance(middle, second_cut, len22);   
+    }
+    else {
+      len22 = len2 / 2;
+      advance(second_cut, len22);
+      first_cut = upper_bound(first, middle, *second_cut, comp);
+      distance(first, first_cut, len11);
+    }
+    BidirectionalIterator new_middle =
+      __rotate_adaptive(first_cut, middle, second_cut, len1 - len11,
+                        len22, buffer, buffer_size);
+    __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer,
+                     buffer_size, comp);
+    __merge_adaptive(new_middle, second_cut, last, len1 - len11,
+                     len2 - len22, buffer, buffer_size, comp);
+  }
+}
+
+template <class BidirectionalIterator, class T, class Distance>
+inline void __inplace_merge_aux(BidirectionalIterator first,
+                                BidirectionalIterator middle,
+                                BidirectionalIterator last, T*, Distance*) {
+  Distance len1 = 0;
+  distance(first, middle, len1);
+  Distance len2 = 0;
+  distance(middle, last, len2);
+
+  temporary_buffer<BidirectionalIterator, T> buf(first, last);
+  if (buf.begin() == 0)
+    __merge_without_buffer(first, middle, last, len1, len2);
+  else
+    __merge_adaptive(first, middle, last, len1, len2,
+                     buf.begin(), Distance(buf.size()));
+}
+
+template <class BidirectionalIterator, class T, class Distance, class Compare>
+inline void __inplace_merge_aux(BidirectionalIterator first,
+                                BidirectionalIterator middle,
+                                BidirectionalIterator last, T*, Distance*,
+                                Compare comp) {
+  Distance len1 = 0;
+  distance(first, middle, len1);
+  Distance len2 = 0;
+  distance(middle, last, len2);
+
+  temporary_buffer<BidirectionalIterator, T> buf(first, last);
+  if (buf.begin() == 0)
+    __merge_without_buffer(first, middle, last, len1, len2, comp);
+  else
+    __merge_adaptive(first, middle, last, len1, len2,
+                     buf.begin(), Distance(buf.size()),
+                     comp);
+}
+
+template <class BidirectionalIterator>
+inline void inplace_merge(BidirectionalIterator first,
+                          BidirectionalIterator middle,
+                          BidirectionalIterator last) {
+  if (first == middle || middle == last) return;
+  __inplace_merge_aux(first, middle, last, value_type(first),
+                      distance_type(first));
+}
+
+template <class BidirectionalIterator, class Compare>
+inline void inplace_merge(BidirectionalIterator first,
+                          BidirectionalIterator middle,
+                          BidirectionalIterator last, Compare comp) {
+  if (first == middle || middle == last) return;
+  __inplace_merge_aux(first, middle, last, value_type(first),
+                      distance_type(first), comp);
+}
+
+template <class InputIterator1, class InputIterator2>
+bool includes(InputIterator1 first1, InputIterator1 last1,
+              InputIterator2 first2, InputIterator2 last2) {
+  while (first1 != last1 && first2 != last2)
+    if (*first2 < *first1)
+      return false;
+    else if(*first1 < *first2) 
+      ++first1;
+    else
+      ++first1, ++first2;
+
+  return first2 == last2;
+}
+
+template <class InputIterator1, class InputIterator2, class Compare>
+bool includes(InputIterator1 first1, InputIterator1 last1,
+              InputIterator2 first2, InputIterator2 last2, Compare comp) {
+  while (first1 != last1 && first2 != last2)
+    if (comp(*first2, *first1))
+      return false;
+    else if(comp(*first1, *first2)) 
+      ++first1;
+    else
+      ++first1, ++first2;
+
+  return first2 == last2;
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator>
+OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
+                         InputIterator2 first2, InputIterator2 last2,
+                         OutputIterator result) {
+  while (first1 != last1 && first2 != last2) {
+    if (*first1 < *first2) {
+      *result = *first1;
+      ++first1;
+    }
+    else if (*first2 < *first1) {
+      *result = *first2;
+      ++first2;
+    }
+    else {
+      *result = *first1;
+      ++first1;
+      ++first2;
+    }
+    ++result;
+  }
+  return copy(first2, last2, copy(first1, last1, result));
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator,
+          class Compare>
+OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
+                         InputIterator2 first2, InputIterator2 last2,
+                         OutputIterator result, Compare comp) {
+  while (first1 != last1 && first2 != last2) {
+    if (comp(*first1, *first2)) {
+      *result = *first1;
+      ++first1;
+    }
+    else if (comp(*first2, *first1)) {
+      *result = *first2;
+      ++first2;
+    }
+    else {
+      *result = *first1;
+      ++first1;
+      ++first2;
+    }
+    ++result;
+  }
+  return copy(first2, last2, copy(first1, last1, result));
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator>
+OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
+                                InputIterator2 first2, InputIterator2 last2,
+                                OutputIterator result) {
+  while (first1 != last1 && first2 != last2) 
+    if (*first1 < *first2) 
+      ++first1;
+    else if (*first2 < *first1) 
+      ++first2;
+    else {
+      *result = *first1;
+      ++first1;
+      ++first2;
+      ++result;
+    }
+  return result;
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator,
+          class Compare>
+OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
+                                InputIterator2 first2, InputIterator2 last2,
+                                OutputIterator result, Compare comp) {
+  while (first1 != last1 && first2 != last2)
+    if (comp(*first1, *first2))
+      ++first1;
+    else if (comp(*first2, *first1))
+      ++first2;
+    else {
+      *result = *first1;
+      ++first1;
+      ++first2;
+      ++result;
+    }
+  return result;
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator>
+OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
+                              InputIterator2 first2, InputIterator2 last2,
+                              OutputIterator result) {
+  while (first1 != last1 && first2 != last2)
+    if (*first1 < *first2) {
+      *result = *first1;
+      ++first1;
+      ++result;
+    }
+    else if (*first2 < *first1)
+      ++first2;
+    else {
+      ++first1;
+      ++first2;
+    }
+  return copy(first1, last1, result);
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator, 
+          class Compare>
+OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1,
+                              InputIterator2 first2, InputIterator2 last2, 
+                              OutputIterator result, Compare comp) {
+  while (first1 != last1 && first2 != last2)
+    if (comp(*first1, *first2)) {
+      *result = *first1;
+      ++first1;
+      ++result;
+    }
+    else if (comp(*first2, *first1))
+      ++first2;
+    else {
+      ++first1;
+      ++first2;
+    }
+  return copy(first1, last1, result);
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator>
+OutputIterator set_symmetric_difference(InputIterator1 first1,
+                                        InputIterator1 last1,
+                                        InputIterator2 first2,
+                                        InputIterator2 last2,
+                                        OutputIterator result) {
+  while (first1 != last1 && first2 != last2)
+    if (*first1 < *first2) {
+      *result = *first1;
+      ++first1;
+      ++result;
+    }
+    else if (*first2 < *first1) {
+      *result = *first2;
+      ++first2;
+      ++result;
+    }
+    else {
+      ++first1;
+      ++first2;
+    }
+  return copy(first2, last2, copy(first1, last1, result));
+}
+
+template <class InputIterator1, class InputIterator2, class OutputIterator,
+          class Compare>
+OutputIterator set_symmetric_difference(InputIterator1 first1,
+                                        InputIterator1 last1,
+                                        InputIterator2 first2,
+                                        InputIterator2 last2,
+                                        OutputIterator result, Compare comp) {
+  while (first1 != last1 && first2 != last2)
+    if (comp(*first1, *first2)) {
+      *result = *first1;
+      ++first1;
+      ++result;
+    }
+    else if (comp(*first2, *first1)) {
+      *result = *first2;
+      ++first2;
+      ++result;
+    }
+    else {
+      ++first1;
+      ++first2;
+    }
+  return copy(first2, last2, copy(first1, last1, result));
+}
+
+template <class ForwardIterator>
+ForwardIterator max_element(ForwardIterator first, ForwardIterator last) {
+  if (first == last) return first;
+  ForwardIterator result = first;
+  while (++first != last) 
+    if (*result < *first) result = first;
+  return result;
+}
+
+template <class ForwardIterator, class Compare>
+ForwardIterator max_element(ForwardIterator first, ForwardIterator last,
+                            Compare comp) {
+  if (first == last) return first;
+  ForwardIterator result = first;
+  while (++first != last) 
+    if (comp(*result, *first)) result = first;
+  return result;
+}
+
+template <class ForwardIterator>
+ForwardIterator min_element(ForwardIterator first, ForwardIterator last) {
+  if (first == last) return first;
+  ForwardIterator result = first;
+  while (++first != last) 
+    if (*first < *result) result = first;
+  return result;
+}
+
+template <class ForwardIterator, class Compare>
+ForwardIterator min_element(ForwardIterator first, ForwardIterator last,
+                            Compare comp) {
+  if (first == last) return first;
+  ForwardIterator result = first;
+  while (++first != last) 
+    if (comp(*first, *result)) result = first;
+  return result;
+}
+
+template <class BidirectionalIterator>
+bool next_permutation(BidirectionalIterator first,
+                      BidirectionalIterator last) {
+  if (first == last) return false;
+  BidirectionalIterator i = first;
+  ++i;
+  if (i == last) return false;
+  i = last;
+  --i;
+
+  for(;;) {
+    BidirectionalIterator ii = i;
+    --i;
+    if (*i < *ii) {
+      BidirectionalIterator j = last;
+      while (!(*i < *--j));
+      iter_swap(i, j);
+      reverse(ii, last);
+      return true;
+    }
+    if (i == first) {
+      reverse(first, last);
+      return false;
+    }
+  }
+}
+
+template <class BidirectionalIterator, class Compare>
+bool next_permutation(BidirectionalIterator first, BidirectionalIterator last,
+                      Compare comp) {
+  if (first == last) return false;
+  BidirectionalIterator i = first;
+  ++i;
+  if (i == last) return false;
+  i = last;
+  --i;
+
+  for(;;) {
+    BidirectionalIterator ii = i;
+    --i;
+    if (comp(*i, *ii)) {
+      BidirectionalIterator j = last;
+      while (!comp(*i, *--j));
+      iter_swap(i, j);
+      reverse(ii, last);
+      return true;
+    }
+    if (i == first) {
+      reverse(first, last);
+      return false;
+    }
+  }
+}
+
+template <class BidirectionalIterator>
+bool prev_permutation(BidirectionalIterator first,
+                      BidirectionalIterator last) {
+  if (first == last) return false;
+  BidirectionalIterator i = first;
+  ++i;
+  if (i == last) return false;
+  i = last;
+  --i;
+
+  for(;;) {
+    BidirectionalIterator ii = i;
+    --i;
+    if (*ii < *i) {
+      BidirectionalIterator j = last;
+      while (!(*--j < *i));
+      iter_swap(i, j);
+      reverse(ii, last);
+      return true;
+    }
+    if (i == first) {
+      reverse(first, last);
+      return false;
+    }
+  }
+}
+
+template <class BidirectionalIterator, class Compare>
+bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last,
+                      Compare comp) {
+  if (first == last) return false;
+  BidirectionalIterator i = first;
+  ++i;
+  if (i == last) return false;
+  i = last;
+  --i;
+
+  for(;;) {
+    BidirectionalIterator ii = i;
+    --i;
+    if (comp(*ii, *i)) {
+      BidirectionalIterator j = last;
+      while (!comp(*--j, *i));
+      iter_swap(i, j);
+      reverse(ii, last);
+      return true;
+    }
+    if (i == first) {
+      reverse(first, last);
+      return false;
+    }
+  }
+}
+
+template <class InputIterator, class ForwardIterator>
+InputIterator find_first_of(InputIterator first1, InputIterator last1,
+                            ForwardIterator first2, ForwardIterator last2)
+{
+  for ( ; first1 != last1; ++first1) 
+    for (ForwardIterator iter = first2; iter != last2; ++iter)
+      if (*first1 == *iter)
+        return first1;
+  return last1;
+}
+
+template <class InputIterator, class ForwardIterator, class BinaryPredicate>
+InputIterator find_first_of(InputIterator first1, InputIterator last1,
+                            ForwardIterator first2, ForwardIterator last2,
+                            BinaryPredicate comp)
+{
+  for ( ; first1 != last1; ++first1) 
+    for (ForwardIterator iter = first2; iter != last2; ++iter)
+      if (comp(*first1, *iter))
+        return first1;
+  return last1;
+}
+
+
+// Search [first2, last2) as a subsequence in [first1, last1).
+
+// find_end for forward iterators. 
+template <class ForwardIterator1, class ForwardIterator2>
+ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1,
+                            ForwardIterator2 first2, ForwardIterator2 last2,
+                            forward_iterator_tag, forward_iterator_tag)
+{
+  if (first2 == last2)
+    return last1;
+  else {
+    ForwardIterator1 result = last1;
+    while (1) {
+      ForwardIterator1 new_result = search(first1, last1, first2, last2);
+      if (new_result == last1)
+        return result;
+      else {
+        result = new_result;
+        first1 = new_result;
+        ++first1;
+      }
+    }
+  }
+}
+
+template <class ForwardIterator1, class ForwardIterator2,
+          class BinaryPredicate>
+ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1,
+                            ForwardIterator2 first2, ForwardIterator2 last2,
+                            forward_iterator_tag, forward_iterator_tag,
+                            BinaryPredicate comp)
+{
+  if (first2 == last2)
+    return last1;
+  else {
+    ForwardIterator1 result = last1;
+    while (1) {
+      ForwardIterator1 new_result = search(first1, last1, first2, last2, comp);
+      if (new_result == last1)
+        return result;
+      else {
+        result = new_result;
+        first1 = new_result;
+        ++first1;
+      }
+    }
+  }
+}
+
+// find_end for bidirectional iterators.  Requires partial specialization.
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+template <class BidirectionalIterator1, class BidirectionalIterator2>
+BidirectionalIterator1
+__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
+           BidirectionalIterator2 first2, BidirectionalIterator2 last2,
+           bidirectional_iterator_tag, bidirectional_iterator_tag)
+{
+  typedef reverse_iterator<BidirectionalIterator1> reviter1;
+  typedef reverse_iterator<BidirectionalIterator2> reviter2;
+
+  reviter1 rlast1(first1);
+  reviter2 rlast2(first2);
+  reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2);
+
+  if (rresult == rlast1)
+    return last1;
+  else {
+    BidirectionalIterator1 result = rresult.base();
+    advance(result, -distance(first2, last2));
+    return result;
+  }
+}
+
+template <class BidirectionalIterator1, class BidirectionalIterator2,
+          class BinaryPredicate>
+BidirectionalIterator1
+__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1,
+           BidirectionalIterator2 first2, BidirectionalIterator2 last2,
+           bidirectional_iterator_tag, bidirectional_iterator_tag, 
+           BinaryPredicate comp)
+{
+  typedef reverse_iterator<BidirectionalIterator1> reviter1;
+  typedef reverse_iterator<BidirectionalIterator2> reviter2;
+
+  reviter1 rlast1(first1);
+  reviter2 rlast2(first2);
+  reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2,
+                            comp);
+
+  if (rresult == rlast1)
+    return last1;
+  else {
+    BidirectionalIterator1 result = rresult.base();
+    advance(result, -distance(first2, last2));
+    return result;
+  }
+}
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+// Dispatching functions.
+
+template <class ForwardIterator1, class ForwardIterator2>
+inline ForwardIterator1 
+find_end(ForwardIterator1 first1, ForwardIterator1 last1, 
+         ForwardIterator2 first2, ForwardIterator2 last2)
+{
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+  typedef typename iterator_traits<ForwardIterator1>::iterator_category
+          category1;
+  typedef typename iterator_traits<ForwardIterator2>::iterator_category
+          category2;
+  return __find_end(first1, last1, first2, last2, category1(), category2());
+#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+  return __find_end(first1, last1, first2, last2,
+                    forward_iterator_tag(), forward_iterator_tag());
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+}
+
+template <class ForwardIterator1, class ForwardIterator2, 
+          class BinaryPredicate>
+inline ForwardIterator1 
+find_end(ForwardIterator1 first1, ForwardIterator1 last1, 
+         ForwardIterator2 first2, ForwardIterator2 last2,
+         BinaryPredicate comp)
+{
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+  typedef typename iterator_traits<ForwardIterator1>::iterator_category
+          category1;
+  typedef typename iterator_traits<ForwardIterator2>::iterator_category
+          category2;
+  return __find_end(first1, last1, first2, last2, category1(), category2(),
+                    comp);
+#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+  return __find_end(first1, last1, first2, last2,
+                    forward_iterator_tag(), forward_iterator_tag(),
+                    comp);
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+}
+
+template <class RandomAccessIterator, class Distance>
+bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,
+               Distance*)
+{
+  const Distance n = last - first;
+
+  Distance parent = 0;
+  for (Distance child = 1; child < n; ++child) {
+    if (first[parent] < first[child]) 
+      return false;
+    if (child & 1 == 0)
+      ++parent;
+  }
+  return true;
+}
+
+template <class RandomAccessIterator>
+inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last)
+{
+  return __is_heap(first, last, distance_type(first));
+}
+
+
+template <class RandomAccessIterator, class Distance, class StrictWeakOrdering>
+bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,
+               StrictWeakOrdering comp,
+               Distance*)
+{
+  const Distance n = last - first;
+
+  Distance parent = 0;
+  for (Distance child = 1; child < n; ++child) {
+    if (comp(first[parent], first[child]))
+      return false;
+    if (child & 1 == 0)
+      ++parent;
+  }
+  return true;
+}
+
+template <class RandomAccessIterator, class StrictWeakOrdering>
+inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last,
+                    StrictWeakOrdering comp)
+{
+  return __is_heap(first, last, comp, distance_type(first));
+}
+
+
+template <class ForwardIterator>
+bool is_sorted(ForwardIterator first, ForwardIterator last)
+{
+  if (first == last)
+    return true;
+
+  ForwardIterator next = first;
+  for (++next; next != last; first = next, ++next) {
+    if (*next < *first)
+      return false;
+  }
+
+  return true;
+}
+
+template <class ForwardIterator, class StrictWeakOrdering>
+bool is_sorted(ForwardIterator first, ForwardIterator last,
+               StrictWeakOrdering comp)
+{
+  if (first == last)
+    return true;
+
+  ForwardIterator next = first;
+  for (++next; next != last; first = next, ++next) {
+    if (comp(*next, *first))
+      return false;
+  }
+
+  return true;
+}
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1209
+#endif
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_ALGO_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_algobase.h b/libstdc++/stl/stl_algobase.h
new file mode 100644 (file)
index 0000000..668baad
--- /dev/null
@@ -0,0 +1,439 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+
+#ifndef __SGI_STL_INTERNAL_ALGOBASE_H
+#define __SGI_STL_INTERNAL_ALGOBASE_H
+
+#ifndef __STL_CONFIG_H
+#include <stl_config.h>
+#endif
+#ifndef __SGI_STL_INTERNAL_RELOPS
+#include <stl_relops.h>
+#endif
+#ifndef __SGI_STL_INTERNAL_PAIR_H
+#include <stl_pair.h>
+#endif
+#ifndef __TYPE_TRAITS_H_
+#include <type_traits.h>
+#endif
+
+#include <string.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <new.h>
+#include <iostream.h>
+
+#ifndef __SGI_STL_INTERNAL_ITERATOR_H
+#include <stl_iterator.h>
+#endif
+
+__STL_BEGIN_NAMESPACE
+
+template <class ForwardIterator1, class ForwardIterator2, class T>
+inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, T*) {
+  T tmp = *a;
+  *a = *b;
+  *b = tmp;
+}
+
+template <class ForwardIterator1, class ForwardIterator2>
+inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) {
+  __iter_swap(a, b, value_type(a));
+}
+
+template <class T>
+inline void swap(T& a, T& b) {
+  T tmp = a;
+  a = b;
+  b = tmp;
+}
+
+#ifndef __BORLANDC__
+
+template <class T>
+inline const T& min(const T& a, const T& b) {
+  return b < a ? b : a;
+}
+
+template <class T>
+inline const T& max(const T& a, const T& b) {
+  return  a < b ? b : a;
+}
+
+#endif /* __BORLANDC__ */
+
+template <class T, class Compare>
+inline const T& min(const T& a, const T& b, Compare comp) {
+  return comp(b, a) ? b : a;
+}
+
+template <class T, class Compare>
+inline const T& max(const T& a, const T& b, Compare comp) {
+  return comp(a, b) ? b : a;
+}
+
+template <class InputIterator, class OutputIterator>
+inline OutputIterator __copy(InputIterator first, InputIterator last,
+                             OutputIterator result, input_iterator_tag)
+{
+  for ( ; first != last; ++result, ++first)
+    *result = *first;
+  return result;
+}
+
+template <class RandomAccessIterator, class OutputIterator, class Distance>
+inline OutputIterator
+__copy_d(RandomAccessIterator first, RandomAccessIterator last,
+         OutputIterator result, Distance*)
+{
+  for (Distance n = last - first; n > 0; --n, ++result, ++first) 
+    *result = *first;
+  return result;
+}
+
+template <class RandomAccessIterator, class OutputIterator>
+inline OutputIterator 
+__copy(RandomAccessIterator first, RandomAccessIterator last,
+       OutputIterator result, random_access_iterator_tag)
+{
+  return __copy_d(first, last, result, distance_type(first));
+}
+
+template <class InputIterator, class OutputIterator>
+struct __copy_dispatch
+{
+  OutputIterator operator()(InputIterator first, InputIterator last,
+                            OutputIterator result) {
+    return __copy(first, last, result, iterator_category(first));
+  }
+};
+
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 
+
+template <class T>
+inline T* __copy_t(const T* first, const T* last, T* result, __true_type) {
+  memmove(result, first, sizeof(T) * (last - first));
+  return result + (last - first);
+}
+
+template <class T>
+inline T* __copy_t(const T* first, const T* last, T* result, __false_type) {
+  return __copy_d(first, last, result, (ptrdiff_t*) 0);
+}
+
+template <class T>
+struct __copy_dispatch<T*, T*>
+{
+  T* operator()(T* first, T* last, T* result) {
+    typedef typename __type_traits<T>::has_trivial_assignment_operator t; 
+    return __copy_t(first, last, result, t());
+  }
+};
+
+template <class T>
+struct __copy_dispatch<const T*, T*>
+{
+  T* operator()(const T* first, const T* last, T* result) {
+    typedef typename __type_traits<T>::has_trivial_assignment_operator t; 
+    return __copy_t(first, last, result, t());
+  }
+};
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+template <class InputIterator, class OutputIterator>
+inline OutputIterator copy(InputIterator first, InputIterator last,
+                           OutputIterator result)
+{
+  return __copy_dispatch<InputIterator,OutputIterator>()(first, last, result);
+}
+
+inline char* copy(const char* first, const char* last, char* result) {
+  memmove(result, first, last - first);
+  return result + (last - first);
+}
+
+inline wchar_t* copy(const wchar_t* first, const wchar_t* last,
+                     wchar_t* result) {
+  memmove(result, first, sizeof(wchar_t) * (last - first));
+  return result + (last - first);
+}
+
+template <class BidirectionalIterator1, class BidirectionalIterator2>
+inline BidirectionalIterator2 __copy_backward(BidirectionalIterator1 first, 
+                                              BidirectionalIterator1 last, 
+                                              BidirectionalIterator2 result) {
+  while (first != last) *--result = *--last;
+  return result;
+}
+
+
+template <class BidirectionalIterator1, class BidirectionalIterator2>
+struct __copy_backward_dispatch
+{
+  BidirectionalIterator2 operator()(BidirectionalIterator1 first, 
+                                    BidirectionalIterator1 last, 
+                                    BidirectionalIterator2 result) {
+    return __copy_backward(first, last, result);
+  }
+};
+
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION 
+
+template <class T>
+inline T* __copy_backward_t(const T* first, const T* last, T* result,
+                            __true_type) {
+  const ptrdiff_t N = last - first;
+  memmove(result - N, first, sizeof(T) * N);
+  return result - N;
+}
+
+template <class T>
+inline T* __copy_backward_t(const T* first, const T* last, T* result,
+                            __false_type) {
+  return __copy_backward(first, last, result);
+}
+
+template <class T>
+struct __copy_backward_dispatch<T*, T*>
+{
+  T* operator()(T* first, T* last, T* result) {
+    typedef typename __type_traits<T>::has_trivial_assignment_operator t; 
+    return __copy_backward_t(first, last, result, t());
+  }
+};
+
+template <class T>
+struct __copy_backward_dispatch<const T*, T*>
+{
+  T* operator()(const T* first, const T* last, T* result) {
+    typedef typename __type_traits<T>::has_trivial_assignment_operator t; 
+    return __copy_backward_t(first, last, result, t());
+  }
+};
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+template <class BidirectionalIterator1, class BidirectionalIterator2>
+inline BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, 
+                                            BidirectionalIterator1 last, 
+                                            BidirectionalIterator2 result) {
+  return __copy_backward_dispatch<BidirectionalIterator1, 
+                                  BidirectionalIterator2>()(first, last, 
+                                                            result);
+}
+
+template <class InputIterator, class Size, class OutputIterator>
+pair<InputIterator, OutputIterator> __copy_n(InputIterator first, Size count,
+                                             OutputIterator result,
+                                             input_iterator_tag) {
+  for ( ; count > 0; --count, ++first, ++result)
+    *result = *first;
+  return pair<InputIterator, OutputIterator>(first, result);
+}
+
+template <class RandomAccessIterator, class Size, class OutputIterator>
+inline pair<RandomAccessIterator, OutputIterator>
+__copy_n(RandomAccessIterator first, Size count,
+         OutputIterator result,
+         random_access_iterator_tag) {
+  RandomAccessIterator last = first + count;
+  return pair<RandomAccessIterator, OutputIterator>(last,
+                                                    copy(first, last, result));
+}
+
+template <class InputIterator, class Size, class OutputIterator>
+inline pair<InputIterator, OutputIterator>
+copy_n(InputIterator first, Size count,
+       OutputIterator result) {
+  return __copy_n(first, count, result, iterator_category(first));
+}
+
+template <class ForwardIterator, class T>
+void fill(ForwardIterator first, ForwardIterator last, const T& value) {
+  for ( ; first != last; ++first)
+    *first = value;
+}
+
+template <class OutputIterator, class Size, class T>
+OutputIterator fill_n(OutputIterator first, Size n, const T& value) {
+  for ( ; n > 0; --n, ++first)
+    *first = value;
+  return first;
+}
+
+template <class InputIterator1, class InputIterator2>
+pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1,
+                                             InputIterator1 last1,
+                                             InputIterator2 first2) {
+  while (first1 != last1 && *first1 == *first2) {
+    ++first1;
+    ++first2;
+  }
+  return pair<InputIterator1, InputIterator2>(first1, first2);
+}
+
+template <class InputIterator1, class InputIterator2, class BinaryPredicate>
+pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1,
+                                             InputIterator1 last1,
+                                             InputIterator2 first2,
+                                             BinaryPredicate binary_pred) {
+  while (first1 != last1 && binary_pred(*first1, *first2)) {
+    ++first1;
+    ++first2;
+  }
+  return pair<InputIterator1, InputIterator2>(first1, first2);
+}
+
+template <class InputIterator1, class InputIterator2>
+inline bool equal(InputIterator1 first1, InputIterator1 last1,
+                 InputIterator2 first2) {
+  for ( ; first1 != last1; ++first1, ++first2)
+    if (*first1 != *first2)
+      return false;
+  return true;
+}
+
+template <class InputIterator1, class InputIterator2, class BinaryPredicate>
+inline bool equal(InputIterator1 first1, InputIterator1 last1,
+                 InputIterator2 first2, BinaryPredicate binary_pred) {
+  for ( ; first1 != last1; ++first1, ++first2)
+    if (!binary_pred(*first1, *first2))
+      return false;
+  return true;
+}
+
+template <class InputIterator1, class InputIterator2>
+bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
+                            InputIterator2 first2, InputIterator2 last2) {
+  for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) {
+    if (*first1 < *first2)
+      return true;
+    if (*first2 < *first1)
+      return false;
+  }
+  return first1 == last1 && first2 != last2;
+}
+
+template <class InputIterator1, class InputIterator2, class Compare>
+bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
+                            InputIterator2 first2, InputIterator2 last2,
+                            Compare comp) {
+  for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) {
+    if (comp(*first1, *first2))
+      return true;
+    if (comp(*first2, *first1))
+      return false;
+  }
+  return first1 == last1 && first2 != last2;
+}
+
+inline bool 
+lexicographical_compare(const unsigned char* first1,
+                        const unsigned char* last1,
+                        const unsigned char* first2,
+                        const unsigned char* last2)
+{
+  const size_t len1 = last1 - first1;
+  const size_t len2 = last2 - first2;
+  const int result = memcmp(first1, first2, min(len1, len2));
+  return result != 0 ? result < 0 : len1 < len2;
+}
+
+inline bool lexicographical_compare(const char* first1, const char* last1,
+                                    const char* first2, const char* last2)
+{
+#if CHAR_MAX == SCHAR_MAX
+  return lexicographical_compare((const signed char*) first1,
+                                 (const signed char*) last1,
+                                 (const signed char*) first2,
+                                 (const signed char*) last2);
+#else
+  return lexicographical_compare((const unsigned char*) first1,
+                                 (const unsigned char*) last1,
+                                 (const unsigned char*) first2,
+                                 (const unsigned char*) last2);
+#endif
+}
+
+template <class InputIterator1, class InputIterator2>
+int lexicographical_compare_3way(InputIterator1 first1, InputIterator1 last1,
+                                 InputIterator2 first2, InputIterator2 last2)
+{
+  while (first1 != last1 && first2 != last2) {
+    if (*first1 < *first2) return -1;
+    if (*first2 < *first1) return 1;
+    ++first1; ++first2;
+  }
+  if (first2 == last2) {
+    return !(first1 == last1);
+  } else {
+    return -1;
+  }
+}
+
+inline int
+lexicographical_compare_3way(const unsigned char* first1,
+                             const unsigned char* last1,
+                             const unsigned char* first2,
+                             const unsigned char* last2)
+{
+  const ptrdiff_t len1 = last1 - first1;
+  const ptrdiff_t len2 = last2 - first2;
+  const int result = memcmp(first1, first2, min(len1, len2));
+  return result != 0 ? result : (len1 == len2 ? 0 : (len1 < len2 ? -1 : 1));
+}
+
+inline int lexicographical_compare_3way(const char* first1, const char* last1,
+                                        const char* first2, const char* last2)
+{
+#if CHAR_MAX == SCHAR_MAX
+  return lexicographical_compare_3way(
+                               (const signed char*) first1,
+                                (const signed char*) last1,
+                                (const signed char*) first2,
+                                (const signed char*) last2);
+#else
+  return lexicographical_compare_3way((const unsigned char*) first1,
+                                      (const unsigned char*) last1,
+                                      (const unsigned char*) first2,
+                                      (const unsigned char*) last2);
+#endif
+}
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_ALGOBASE_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_alloc.h b/libstdc++/stl/stl_alloc.h
new file mode 100644 (file)
index 0000000..a6d4143
--- /dev/null
@@ -0,0 +1,698 @@
+/*
+ * Copyright (c) 1996-1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_ALLOC_H
+#define __SGI_STL_INTERNAL_ALLOC_H
+
+#ifdef __SUNPRO_CC
+#  define __PRIVATE public
+   // Extra access restrictions prevent us from really making some things
+   // private.
+#else
+#  define __PRIVATE private
+#endif
+
+#ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG
+#  define __USE_MALLOC
+#endif
+
+
+// This implements some standard node allocators.  These are
+// NOT the same as the allocators in the C++ draft standard or in
+// in the original STL.  They do not encapsulate different pointer
+// types; indeed we assume that there is only one pointer type.
+// The allocation primitives are intended to allocate individual objects,
+// not larger arenas as with the original STL allocators.
+
+#if 0
+#   include <new>
+#   define __THROW_BAD_ALLOC throw bad_alloc
+#elif !defined(__THROW_BAD_ALLOC)
+#   include <iostream.h>
+#   define __THROW_BAD_ALLOC cerr << "out of memory" << endl; exit(1)
+#endif
+
+#ifndef __ALLOC
+#   define __ALLOC alloc
+#endif
+#ifdef __STL_WIN32THREADS
+#   include <windows.h>
+#endif
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#ifndef __RESTRICT
+#  define __RESTRICT
+#endif
+
+#if !defined(_PTHREADS) && !defined(_NOTHREADS) \
+ && !defined(__STL_SGI_THREADS) && !defined(__STL_WIN32THREADS)
+#   define _NOTHREADS
+#endif
+
+# ifdef _PTHREADS
+    // POSIX Threads
+    // This is dubious, since this is likely to be a high contention
+    // lock.   Performance may not be adequate.
+#   include <pthread.h>
+#   define __NODE_ALLOCATOR_LOCK \
+        if (threads) pthread_mutex_lock(&__node_allocator_lock)
+#   define __NODE_ALLOCATOR_UNLOCK \
+        if (threads) pthread_mutex_unlock(&__node_allocator_lock)
+#   define __NODE_ALLOCATOR_THREADS true
+#   define __VOLATILE volatile  // Needed at -O3 on SGI
+# endif
+# ifdef __STL_WIN32THREADS
+    // The lock needs to be initialized by constructing an allocator
+    // objects of the right type.  We do that here explicitly for alloc.
+#   define __NODE_ALLOCATOR_LOCK \
+        EnterCriticalSection(&__node_allocator_lock)
+#   define __NODE_ALLOCATOR_UNLOCK \
+        LeaveCriticalSection(&__node_allocator_lock)
+#   define __NODE_ALLOCATOR_THREADS true
+#   define __VOLATILE volatile  // may not be needed
+# endif /* WIN32THREADS */
+# ifdef __STL_SGI_THREADS
+    // This should work without threads, with sproc threads, or with
+    // pthreads.  It is suboptimal in all cases.
+    // It is unlikely to even compile on nonSGI machines.
+
+    extern "C" {
+      extern int __us_rsthread_malloc;
+    }
+       // The above is copied from malloc.h.  Including <malloc.h>
+       // would be cleaner but fails with certain levels of standard
+       // conformance.
+#   define __NODE_ALLOCATOR_LOCK if (threads && __us_rsthread_malloc) \
+                { __lock(&__node_allocator_lock); }
+#   define __NODE_ALLOCATOR_UNLOCK if (threads && __us_rsthread_malloc) \
+                { __unlock(&__node_allocator_lock); }
+#   define __NODE_ALLOCATOR_THREADS true
+#   define __VOLATILE volatile  // Needed at -O3 on SGI
+# endif
+# ifdef _NOTHREADS
+//  Thread-unsafe
+#   define __NODE_ALLOCATOR_LOCK
+#   define __NODE_ALLOCATOR_UNLOCK
+#   define __NODE_ALLOCATOR_THREADS false
+#   define __VOLATILE
+# endif
+
+__STL_BEGIN_NAMESPACE
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1174
+#endif
+
+// Malloc-based allocator.  Typically slower than default alloc below.
+// Typically thread-safe and more storage efficient.
+#ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG
+# ifdef __DECLARE_GLOBALS_HERE
+    void (* __malloc_alloc_oom_handler)() = 0;
+    // g++ 2.7.2 does not handle static template data members.
+# else
+    extern void (* __malloc_alloc_oom_handler)();
+# endif
+#endif
+
+template <int inst>
+class __malloc_alloc_template {
+
+private:
+
+static void *oom_malloc(size_t);
+
+static void *oom_realloc(void *, size_t);
+
+#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG
+    static void (* __malloc_alloc_oom_handler)();
+#endif
+
+public:
+
+static void * allocate(size_t n)
+{
+    void *result = malloc(n);
+    if (0 == result) result = oom_malloc(n);
+    return result;
+}
+
+static void deallocate(void *p, size_t /* n */)
+{
+    free(p);
+}
+
+static void * reallocate(void *p, size_t /* old_sz */, size_t new_sz)
+{
+    void * result = realloc(p, new_sz);
+    if (0 == result) result = oom_realloc(p, new_sz);
+    return result;
+}
+
+static void (* set_malloc_handler(void (*f)()))()
+{
+    void (* old)() = __malloc_alloc_oom_handler;
+    __malloc_alloc_oom_handler = f;
+    return(old);
+}
+
+};
+
+// malloc_alloc out-of-memory handling
+
+#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG
+template <int inst>
+void (* __malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = 0;
+#endif
+
+template <int inst>
+void * __malloc_alloc_template<inst>::oom_malloc(size_t n)
+{
+    void (* my_malloc_handler)();
+    void *result;
+
+    for (;;) {
+        my_malloc_handler = __malloc_alloc_oom_handler;
+        if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; }
+        (*my_malloc_handler)();
+        result = malloc(n);
+        if (result) return(result);
+    }
+}
+
+template <int inst>
+void * __malloc_alloc_template<inst>::oom_realloc(void *p, size_t n)
+{
+    void (* my_malloc_handler)();
+    void *result;
+
+    for (;;) {
+        my_malloc_handler = __malloc_alloc_oom_handler;
+        if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; }
+        (*my_malloc_handler)();
+        result = realloc(p, n);
+        if (result) return(result);
+    }
+}
+
+typedef __malloc_alloc_template<0> malloc_alloc;
+
+template<class T, class Alloc>
+class simple_alloc {
+
+public:
+    static T *allocate(size_t n)
+                { return 0 == n? 0 : (T*) Alloc::allocate(n * sizeof (T)); }
+    static T *allocate(void)
+                { return (T*) Alloc::allocate(sizeof (T)); }
+    static void deallocate(T *p, size_t n)
+                { if (0 != n) Alloc::deallocate(p, n * sizeof (T)); }
+    static void deallocate(T *p)
+                { Alloc::deallocate(p, sizeof (T)); }
+};
+
+// Allocator adaptor to check size arguments for debugging.
+// Reports errors using assert.  Checking can be disabled with
+// NDEBUG, but it's far better to just use the underlying allocator
+// instead when no checking is desired.
+// There is some evidence that this can confuse Purify.
+template <class Alloc>
+class debug_alloc {
+
+private:
+
+enum {extra = 8};       // Size of space used to store size.  Note
+                        // that this must be large enough to preserve
+                        // alignment.
+
+public:
+
+static void * allocate(size_t n)
+{
+    char *result = (char *)Alloc::allocate(n + extra);
+    *(size_t *)result = n;
+    return result + extra;
+}
+
+static void deallocate(void *p, size_t n)
+{
+    char * real_p = (char *)p - extra;
+    assert(*(size_t *)real_p == n);
+    Alloc::deallocate(real_p, n + extra);
+}
+
+static void * reallocate(void *p, size_t old_sz, size_t new_sz)
+{
+    char * real_p = (char *)p - extra;
+    assert(*(size_t *)real_p == old_sz);
+    char * result = (char *)
+                  Alloc::reallocate(real_p, old_sz + extra, new_sz + extra);
+    *(size_t *)result = new_sz;
+    return result + extra;
+}
+
+
+};
+
+
+# ifdef __USE_MALLOC
+
+typedef malloc_alloc alloc;
+typedef malloc_alloc single_client_alloc;
+
+# else
+
+
+// Default node allocator.
+// With a reasonable compiler, this should be roughly as fast as the
+// original STL class-specific allocators, but with less fragmentation.
+// Default_alloc_template parameters are experimental and MAY
+// DISAPPEAR in the future.  Clients should just use alloc for now.
+//
+// Important implementation properties:
+// 1. If the client request an object of size > __MAX_BYTES, the resulting
+//    object will be obtained directly from malloc.
+// 2. In all other cases, we allocate an object of size exactly
+//    ROUND_UP(requested_size).  Thus the client has enough size
+//    information that we can return the object to the proper free list
+//    without permanently losing part of the object.
+//
+
+// The first template parameter specifies whether more than one thread
+// may use this allocator.  It is safe to allocate an object from
+// one instance of a default_alloc and deallocate it with another
+// one.  This effectively transfers its ownership to the second one.
+// This may have undesirable effects on reference locality.
+// The second parameter is unreferenced and serves only to allow the
+// creation of multiple default_alloc instances.
+// Node that containers built on different allocator instances have
+// different types, limiting the utility of this approach.
+#ifdef __SUNPRO_CC
+// breaks if we make these template class members:
+  enum {__ALIGN = 8};
+  enum {__MAX_BYTES = 128};
+  enum {__NFREELISTS = __MAX_BYTES/__ALIGN};
+#endif
+
+template <bool threads, int inst>
+class __default_alloc_template {
+
+private:
+  // Really we should use static const int x = N
+  // instead of enum { x = N }, but few compilers accept the former.
+# ifndef __SUNPRO_CC
+    enum {__ALIGN = 8};
+    enum {__MAX_BYTES = 128};
+    enum {__NFREELISTS = __MAX_BYTES/__ALIGN};
+# endif
+  static size_t ROUND_UP(size_t bytes) {
+        return (((bytes) + __ALIGN-1) & ~(__ALIGN - 1));
+  }
+__PRIVATE:
+  union obj {
+        union obj * free_list_link;
+        char client_data[1];    /* The client sees this.        */
+  };
+private:
+# ifdef __SUNPRO_CC
+    static obj * __VOLATILE free_list[]; 
+        // Specifying a size results in duplicate def for 4.1
+# else
+    static obj * __VOLATILE free_list[__NFREELISTS]; 
+# endif
+  static  size_t FREELIST_INDEX(size_t bytes) {
+        return (((bytes) + __ALIGN-1)/__ALIGN - 1);
+  }
+
+  // Returns an object of size n, and optionally adds to size n free list.
+  static void *refill(size_t n);
+  // Allocates a chunk for nobjs of size size.  nobjs may be reduced
+  // if it is inconvenient to allocate the requested number.
+  static char *chunk_alloc(size_t size, int &nobjs);
+
+  // Chunk allocation state.
+  static char *start_free;
+  static char *end_free;
+  static size_t heap_size;
+
+# ifdef __STL_SGI_THREADS
+    static volatile unsigned long __node_allocator_lock;
+    static void __lock(volatile unsigned long *); 
+    static inline void __unlock(volatile unsigned long *);
+# endif
+
+# ifdef _PTHREADS
+    static pthread_mutex_t __node_allocator_lock;
+# endif
+
+# ifdef __STL_WIN32THREADS
+    static CRITICAL_SECTION __node_allocator_lock;
+    static bool __node_allocator_lock_initialized;
+
+  public:
+    __default_alloc_template() {
+       // This assumes the first constructor is called before threads
+       // are started.
+        if (!__node_allocator_lock_initialized) {
+            InitializeCriticalSection(&__node_allocator_lock);
+            __node_allocator_lock_initialized = true;
+        }
+    }
+  private:
+# endif
+
+    class lock {
+        public:
+            lock() { __NODE_ALLOCATOR_LOCK; }
+            ~lock() { __NODE_ALLOCATOR_UNLOCK; }
+    };
+    friend class lock;
+
+public:
+
+  /* n must be > 0      */
+  static void * allocate(size_t n)
+  {
+    obj * __VOLATILE * my_free_list;
+    obj * __RESTRICT result;
+
+    if (n > (size_t) __MAX_BYTES) {
+        return(malloc_alloc::allocate(n));
+    }
+    my_free_list = free_list + FREELIST_INDEX(n);
+    // Acquire the lock here with a constructor call.
+    // This ensures that it is released in exit or during stack
+    // unwinding.
+#       ifndef _NOTHREADS
+        /*REFERENCED*/
+        lock lock_instance;
+#       endif
+    result = *my_free_list;
+    if (result == 0) {
+        void *r = refill(ROUND_UP(n));
+        return r;
+    }
+    *my_free_list = result -> free_list_link;
+    return (result);
+  };
+
+  /* p may not be 0 */
+  static void deallocate(void *p, size_t n)
+  {
+    obj *q = (obj *)p;
+    obj * __VOLATILE * my_free_list;
+
+    if (n > (size_t) __MAX_BYTES) {
+        malloc_alloc::deallocate(p, n);
+        return;
+    }
+    my_free_list = free_list + FREELIST_INDEX(n);
+    // acquire lock
+#       ifndef _NOTHREADS
+        /*REFERENCED*/
+        lock lock_instance;
+#       endif /* _NOTHREADS */
+    q -> free_list_link = *my_free_list;
+    *my_free_list = q;
+    // lock is released here
+  }
+
+  static void * reallocate(void *p, size_t old_sz, size_t new_sz);
+
+} ;
+
+typedef __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0> alloc;
+typedef __default_alloc_template<false, 0> single_client_alloc;
+
+
+
+/* We allocate memory in large chunks in order to avoid fragmenting     */
+/* the malloc heap too much.                                            */
+/* We assume that size is properly aligned.                             */
+/* We hold the allocation lock.                                         */
+template <bool threads, int inst>
+char*
+__default_alloc_template<threads, inst>::chunk_alloc(size_t size, int& nobjs)
+{
+    char * result;
+    size_t total_bytes = size * nobjs;
+    size_t bytes_left = end_free - start_free;
+
+    if (bytes_left >= total_bytes) {
+        result = start_free;
+        start_free += total_bytes;
+        return(result);
+    } else if (bytes_left >= size) {
+        nobjs = bytes_left/size;
+        total_bytes = size * nobjs;
+        result = start_free;
+        start_free += total_bytes;
+        return(result);
+    } else {
+        size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);
+        // Try to make use of the left-over piece.
+        if (bytes_left > 0) {
+            obj * __VOLATILE * my_free_list =
+                        free_list + FREELIST_INDEX(bytes_left);
+
+            ((obj *)start_free) -> free_list_link = *my_free_list;
+            *my_free_list = (obj *)start_free;
+        }
+        start_free = (char *)malloc(bytes_to_get);
+        if (0 == start_free) {
+            int i;
+            obj * __VOLATILE * my_free_list, *p;
+            // Try to make do with what we have.  That can't
+            // hurt.  We do not try smaller requests, since that tends
+            // to result in disaster on multi-process machines.
+            for (i = size; i <= __MAX_BYTES; i += __ALIGN) {
+                my_free_list = free_list + FREELIST_INDEX(i);
+                p = *my_free_list;
+                if (0 != p) {
+                    *my_free_list = p -> free_list_link;
+                    start_free = (char *)p;
+                    end_free = start_free + i;
+                    return(chunk_alloc(size, nobjs));
+                    // Any leftover piece will eventually make it to the
+                    // right free list.
+                }
+            }
+           end_free = 0;       // In case of exception.
+            start_free = (char *)malloc_alloc::allocate(bytes_to_get);
+            // This should either throw an
+            // exception or remedy the situation.  Thus we assume it
+            // succeeded.
+        }
+        heap_size += bytes_to_get;
+        end_free = start_free + bytes_to_get;
+        return(chunk_alloc(size, nobjs));
+    }
+}
+
+
+/* Returns an object of size n, and optionally adds to size n free list.*/
+/* We assume that n is properly aligned.                                */
+/* We hold the allocation lock.                                         */
+template <bool threads, int inst>
+void* __default_alloc_template<threads, inst>::refill(size_t n)
+{
+    int nobjs = 20;
+    char * chunk = chunk_alloc(n, nobjs);
+    obj * __VOLATILE * my_free_list;
+    obj * result;
+    obj * current_obj, * next_obj;
+    int i;
+
+    if (1 == nobjs) return(chunk);
+    my_free_list = free_list + FREELIST_INDEX(n);
+
+    /* Build free list in chunk */
+      result = (obj *)chunk;
+      *my_free_list = next_obj = (obj *)(chunk + n);
+      for (i = 1; ; i++) {
+        current_obj = next_obj;
+        next_obj = (obj *)((char *)next_obj + n);
+        if (nobjs - 1 == i) {
+            current_obj -> free_list_link = 0;
+            break;
+        } else {
+            current_obj -> free_list_link = next_obj;
+        }
+      }
+    return(result);
+}
+
+template <bool threads, int inst>
+void*
+__default_alloc_template<threads, inst>::reallocate(void *p,
+                                                    size_t old_sz,
+                                                    size_t new_sz)
+{
+    void * result;
+    size_t copy_sz;
+
+    if (old_sz > (size_t) __MAX_BYTES && new_sz > (size_t) __MAX_BYTES) {
+        return(realloc(p, new_sz));
+    }
+    if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return(p);
+    result = allocate(new_sz);
+    copy_sz = new_sz > old_sz? old_sz : new_sz;
+    memcpy(result, p, copy_sz);
+    deallocate(p, old_sz);
+    return(result);
+}
+
+#ifdef _PTHREADS
+    template <bool threads, int inst>
+    pthread_mutex_t
+    __default_alloc_template<threads, inst>::__node_allocator_lock
+        = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+#ifdef __STL_WIN32THREADS
+    template <bool threads, int inst> CRITICAL_SECTION
+    __default_alloc_template<threads, inst>::__node_allocator_lock;
+
+    template <bool threads, int inst> bool
+    __default_alloc_template<threads, inst>::__node_allocator_lock_initialized
+       = false;
+#endif
+
+#ifdef __STL_SGI_THREADS
+__STL_END_NAMESPACE
+#include <mutex.h>
+#include <time.h>
+__STL_BEGIN_NAMESPACE
+// Somewhat generic lock implementations.  We need only test-and-set
+// and some way to sleep.  These should work with both SGI pthreads
+// and sproc threads.  They may be useful on other systems.
+template <bool threads, int inst>
+volatile unsigned long
+__default_alloc_template<threads, inst>::__node_allocator_lock = 0;
+
+#if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) || defined(__GNUC__)
+#   define __test_and_set(l,v) test_and_set(l,v)
+#endif
+
+template <bool threads, int inst>
+void 
+__default_alloc_template<threads, inst>::__lock(volatile unsigned long *lock)
+{
+    const unsigned low_spin_max = 30;  // spin cycles if we suspect uniprocessor
+    const unsigned high_spin_max = 1000; // spin cycles for multiprocessor
+    static unsigned spin_max = low_spin_max;
+    unsigned my_spin_max;
+    static unsigned last_spins = 0;
+    unsigned my_last_spins;
+    static struct timespec ts = {0, 1000};
+    unsigned junk;
+#   define __ALLOC_PAUSE junk *= junk; junk *= junk; junk *= junk; junk *= junk
+    int i;
+
+    if (!__test_and_set((unsigned long *)lock, 1)) {
+        return;
+    }
+    my_spin_max = spin_max;
+    my_last_spins = last_spins;
+    for (i = 0; i < my_spin_max; i++) {
+        if (i < my_last_spins/2 || *lock) {
+            __ALLOC_PAUSE;
+            continue;
+        }
+        if (!__test_and_set((unsigned long *)lock, 1)) {
+            // got it!
+            // Spinning worked.  Thus we're probably not being scheduled
+            // against the other process with which we were contending.
+            // Thus it makes sense to spin longer the next time.
+            last_spins = i;
+            spin_max = high_spin_max;
+            return;
+        }
+    }
+    // We are probably being scheduled against the other process.  Sleep.
+    spin_max = low_spin_max;
+    for (;;) {
+        if (!__test_and_set((unsigned long *)lock, 1)) {
+            return;
+        }
+        nanosleep(&ts, 0);
+    }
+}
+
+template <bool threads, int inst>
+inline void
+__default_alloc_template<threads, inst>::__unlock(volatile unsigned long *lock)
+{
+#   if defined(__GNUC__) && __mips >= 3
+        asm("sync");
+        *lock = 0;
+#   elif __mips >= 3 && (defined (_ABIN32) || defined(_ABI64))
+        __lock_release(lock);
+#   else 
+        *lock = 0;
+        // This is not sufficient on many multiprocessors, since
+        // writes to protected variables and the lock may be reordered.
+#   endif
+}
+#endif
+
+template <bool threads, int inst>
+char *__default_alloc_template<threads, inst>::start_free = 0;
+
+template <bool threads, int inst>
+char *__default_alloc_template<threads, inst>::end_free = 0;
+
+template <bool threads, int inst>
+size_t __default_alloc_template<threads, inst>::heap_size = 0;
+
+template <bool threads, int inst>
+__default_alloc_template<threads, inst>::obj * __VOLATILE
+__default_alloc_template<threads, inst> ::free_list[
+# ifdef __SUNPRO_CC
+    __NFREELISTS
+# else
+    __default_alloc_template<threads, inst>::__NFREELISTS
+# endif
+] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
+// The 16 zeros are necessary to make version 4.1 of the SunPro
+// compiler happy.  Otherwise it appears to allocate too little
+// space for the array.
+
+# ifdef __STL_WIN32THREADS
+  // Create one to get critical section initialized.
+  // We do this onece per file, but only the first constructor
+  // does anything.
+  static alloc __node_allocator_dummy_instance;
+# endif
+
+#endif /* ! __USE_MALLOC */
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1174
+#endif
+
+__STL_END_NAMESPACE
+
+#undef __PRIVATE
+
+#endif /* __SGI_STL_INTERNAL_ALLOC_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_bvector.h b/libstdc++/stl/stl_bvector.h
new file mode 100644 (file)
index 0000000..db02251
--- /dev/null
@@ -0,0 +1,614 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_BVECTOR_H
+#define __SGI_STL_INTERNAL_BVECTOR_H
+
+__STL_BEGIN_NAMESPACE 
+
+static const int __WORD_BIT = int(CHAR_BIT*sizeof(unsigned int));
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1174
+#endif
+
+struct __bit_reference {
+  unsigned int* p;
+  unsigned int mask;
+  __bit_reference(unsigned int* x, unsigned int y) : p(x), mask(y) {}
+
+public:
+  __bit_reference() : p(0), mask(0) {}
+  operator bool() const { return !(!(*p & mask)); }
+  __bit_reference& operator=(bool x) {
+    if (x)      
+      *p |= mask;
+    else 
+      *p &= ~mask;
+    return *this;
+  }
+  __bit_reference& operator=(const __bit_reference& x) { return *this = bool(x); }
+  bool operator==(const __bit_reference& x) const {
+    return bool(*this) == bool(x);
+  }
+  bool operator<(const __bit_reference& x) const {
+    return bool(*this) < bool(x);
+  }
+  void flip() { *p ^= mask; }
+};
+
+inline void swap(__bit_reference x, __bit_reference y) {
+  bool tmp = x;
+  x = y;
+  y = tmp;
+}
+
+struct __bit_iterator : public random_access_iterator<bool, ptrdiff_t> {
+  typedef __bit_reference  reference;
+  typedef __bit_reference* pointer;
+  typedef __bit_iterator iterator;
+
+  unsigned int* p;
+  unsigned int offset;
+  void bump_up() {
+    if (offset++ == __WORD_BIT - 1) {
+      offset = 0;
+      ++p;
+    }
+  }
+  void bump_down() {
+    if (offset-- == 0) {
+      offset = __WORD_BIT - 1;
+      --p;
+    }
+  }
+
+  __bit_iterator() : p(0), offset(0) {}
+  __bit_iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {}
+  reference operator*() const { return reference(p, 1U << offset); }
+  iterator& operator++() {
+    bump_up();
+    return *this;
+  }
+  iterator operator++(int) {
+    iterator tmp = *this;
+    bump_up();
+    return tmp;
+  }
+  iterator& operator--() {
+    bump_down();
+    return *this;
+  }
+  iterator operator--(int) {
+    iterator tmp = *this;
+    bump_down();
+    return tmp;
+  }
+  iterator& operator+=(difference_type i) {
+    difference_type n = i + offset;
+    p += n / __WORD_BIT;
+    n = n % __WORD_BIT;
+    if (n < 0) {
+      offset = (unsigned int) n + __WORD_BIT;
+      --p;
+    } else
+      offset = (unsigned int) n;
+    return *this;
+  }
+  iterator& operator-=(difference_type i) {
+    *this += -i;
+    return *this;
+  }
+  iterator operator+(difference_type i) const {
+    iterator tmp = *this;
+    return tmp += i;
+  }
+  iterator operator-(difference_type i) const {
+    iterator tmp = *this;
+    return tmp -= i;
+  }
+  difference_type operator-(iterator x) const {
+    return __WORD_BIT * (p - x.p) + offset - x.offset;
+  }
+  reference operator[](difference_type i) { return *(*this + i); }
+  bool operator==(const iterator& x) const {
+    return p == x.p && offset == x.offset;
+  }
+  bool operator!=(const iterator& x) const {
+    return p != x.p || offset != x.offset;
+  }
+  bool operator<(iterator x) const {
+    return p < x.p || (p == x.p && offset < x.offset);
+  }
+};
+
+struct __bit_const_iterator
+  : public random_access_iterator<bool, ptrdiff_t>
+{
+  typedef bool                 reference;
+  typedef bool                 const_reference;
+  typedef const bool*          pointer;
+  typedef __bit_const_iterator const_iterator;
+
+  unsigned int* p;
+  unsigned int offset;
+  void bump_up() {
+    if (offset++ == __WORD_BIT - 1) {
+      offset = 0;
+      ++p;
+    }
+  }
+  void bump_down() {
+    if (offset-- == 0) {
+      offset = __WORD_BIT - 1;
+      --p;
+    }
+  }
+
+  __bit_const_iterator() : p(0), offset(0) {}
+  __bit_const_iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {}
+  __bit_const_iterator(const __bit_iterator& x) : p(x.p), offset(x.offset) {}
+  const_reference operator*() const {
+    return __bit_reference(p, 1U << offset);
+  }
+  const_iterator& operator++() {
+    bump_up();
+    return *this;
+  }
+  const_iterator operator++(int) {
+    const_iterator tmp = *this;
+    bump_up();
+    return tmp;
+  }
+  const_iterator& operator--() {
+    bump_down();
+    return *this;
+  }
+  const_iterator operator--(int) {
+    const_iterator tmp = *this;
+    bump_down();
+    return tmp;
+  }
+  const_iterator& operator+=(difference_type i) {
+    difference_type n = i + offset;
+    p += n / __WORD_BIT;
+    n = n % __WORD_BIT;
+    if (n < 0) {
+      offset = (unsigned int) n + __WORD_BIT;
+      --p;
+    } else
+      offset = (unsigned int) n;
+    return *this;
+  }
+  const_iterator& operator-=(difference_type i) {
+    *this += -i;
+    return *this;
+  }
+  const_iterator operator+(difference_type i) const {
+    const_iterator tmp = *this;
+    return tmp += i;
+  }
+  const_iterator operator-(difference_type i) const {
+    const_iterator tmp = *this;
+    return tmp -= i;
+  }
+  difference_type operator-(const_iterator x) const {
+    return __WORD_BIT * (p - x.p) + offset - x.offset;
+  }
+  const_reference operator[](difference_type i) { 
+    return *(*this + i); 
+  }
+  bool operator==(const const_iterator& x) const {
+    return p == x.p && offset == x.offset;
+  }
+  bool operator!=(const const_iterator& x) const {
+    return p != x.p || offset != x.offset;
+  }
+  bool operator<(const_iterator x) const {
+    return p < x.p || (p == x.p && offset < x.offset);
+  }
+};
+
+// The next few lines are confusing.  What we're doing is declaring a
+//  partial specialization of vector<T, Alloc> if we have the necessary
+//  compiler support.  Otherwise, we define a class bit_vector which uses
+//  the default allocator.  In either case, we typedef "data_allocator" 
+//  appropriately.
+
+#if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && !defined(__STL_NEED_BOOL)
+#define __SGI_STL_VECBOOL_TEMPLATE
+#define __BVECTOR vector
+#else
+#undef __SGI_STL_VECBOOL_TEMPLATE
+#define __BVECTOR bit_vector
+#endif
+
+#      ifdef __SGI_STL_VECBOOL_TEMPLATE
+       __STL_END_NAMESPACE
+#      include <stl_vector.h>
+       __STL_BEGIN_NAMESPACE
+template<class Alloc> class vector<bool, Alloc>
+#      else /* __SGI_STL_VECBOOL_TEMPLATE */
+class bit_vector
+#      endif /* __SGI_STL_VECBOOL_TEMPLATE */
+{
+#      ifdef __SGI_STL_VECBOOL_TEMPLATE
+  typedef simple_alloc<unsigned int, Alloc> data_allocator;
+#      else /* __SGI_STL_VECBOOL_TEMPLATE */
+  typedef simple_alloc<unsigned int, alloc> data_allocator;  
+#      endif /* __SGI_STL_VECBOOL_TEMPLATE */
+public:
+  typedef bool value_type;
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type; 
+  typedef __bit_reference reference;
+  typedef bool const_reference;
+  typedef __bit_reference* pointer;
+  typedef const bool* const_pointer;
+
+  typedef __bit_iterator                iterator;
+  typedef __bit_const_iterator          const_iterator;
+
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+  typedef reverse_iterator<const_iterator> const_reverse_iterator;
+  typedef reverse_iterator<iterator> reverse_iterator;
+#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+  typedef reverse_iterator<const_iterator, value_type, const_reference, 
+                           difference_type> const_reverse_iterator;
+  typedef reverse_iterator<iterator, value_type, reference, difference_type>
+          reverse_iterator;
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+protected:
+  iterator start;
+  iterator finish;
+  unsigned int* end_of_storage;
+  unsigned int* bit_alloc(size_type n) {
+    return data_allocator::allocate((n + __WORD_BIT - 1)/__WORD_BIT);
+  }
+  void deallocate() {
+    if (start.p)
+      data_allocator::deallocate(start.p, end_of_storage - start.p);
+  }
+  void initialize(size_type n) {
+    unsigned int* q = bit_alloc(n);
+    end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT;
+    start = iterator(q, 0);
+    finish = start + difference_type(n);
+  }
+  void insert_aux(iterator position, bool x) {
+    if (finish.p != end_of_storage) {
+      copy_backward(position, finish, finish + 1);
+      *position = x;
+      ++finish;
+    }
+    else {
+      size_type len = size() ? 2 * size() : __WORD_BIT;
+      unsigned int* q = bit_alloc(len);
+      iterator i = copy(begin(), position, iterator(q, 0));
+      *i++ = x;
+      finish = copy(position, end(), i);
+      deallocate();
+      end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
+      start = iterator(q, 0);
+    }
+  }
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  void initialize_range(InputIterator first, InputIterator last,
+                        input_iterator_tag) {
+    start = iterator();
+    finish = iterator();
+    end_of_storage = 0;
+    for ( ; first != last; ++first) 
+      push_back(*first);
+  }
+
+  template <class ForwardIterator>
+  void initialize_range(ForwardIterator first, ForwardIterator last,
+                        forward_iterator_tag) {
+    size_type n = 0;
+    distance(first, last, n);
+    initialize(n);
+    copy(first, last, start);
+  }
+
+  template <class InputIterator>
+  void insert_range(iterator pos,
+                    InputIterator first, InputIterator last,
+                    input_iterator_tag) {
+    for ( ; first != last; ++first) {
+      pos = insert(pos, *first);
+      ++pos;
+    }
+  }
+
+  template <class ForwardIterator>
+  void insert_range(iterator position,
+                    ForwardIterator first, ForwardIterator last,
+                    forward_iterator_tag) {
+    if (first != last) {
+      size_type n = 0;
+      distance(first, last, n);
+      if (capacity() - size() >= n) {
+        copy_backward(position, end(), finish + difference_type(n));
+        copy(first, last, position);
+        finish += difference_type(n);
+      }
+      else {
+        size_type len = size() + max(size(), n);
+        unsigned int* q = bit_alloc(len);
+        iterator i = copy(begin(), position, iterator(q, 0));
+        i = copy(first, last, i);
+        finish = copy(position, end(), i);
+        deallocate();
+        end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
+        start = iterator(q, 0);
+      }
+    }
+  }      
+
+#endif /* __STL_MEMBER_TEMPLATES */
+
+public:
+  iterator begin() { return start; }
+  const_iterator begin() const { return start; }
+  iterator end() { return finish; }
+  const_iterator end() const { return finish; }
+
+  reverse_iterator rbegin() { return reverse_iterator(end()); }
+  const_reverse_iterator rbegin() const { 
+    return const_reverse_iterator(end()); 
+  }
+  reverse_iterator rend() { return reverse_iterator(begin()); }
+  const_reverse_iterator rend() const { 
+    return const_reverse_iterator(begin()); 
+  }
+
+  size_type size() const { return size_type(end() - begin()); }
+  size_type max_size() const { return size_type(-1); }
+  size_type capacity() const {
+    return size_type(const_iterator(end_of_storage, 0) - begin());
+  }
+  bool empty() const { return begin() == end(); }
+  reference operator[](size_type n) {
+    return *(begin() + difference_type(n));
+  }
+  const_reference operator[](size_type n) const {
+    return *(begin() + difference_type(n));
+  }
+  __BVECTOR() : start(iterator()), finish(iterator()), end_of_storage(0) {}
+  __BVECTOR(size_type n, bool value) {
+    initialize(n);
+    fill(start.p, end_of_storage, value ? ~0 : 0);
+  }
+  __BVECTOR(int n, bool value) {
+    initialize(n);
+    fill(start.p, end_of_storage, value ? ~0 : 0);
+  }
+  __BVECTOR(long n, bool value) {
+    initialize(n);
+    fill(start.p, end_of_storage, value ? ~0 : 0);
+  }
+  explicit __BVECTOR(size_type n) {
+    initialize(n);
+    fill(start.p, end_of_storage, 0);
+  }
+  __BVECTOR(const __BVECTOR& x) {
+    initialize(x.size());
+    copy(x.begin(), x.end(), start);
+  }
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  __BVECTOR(InputIterator first, InputIterator last) {
+    initialize_range(first, last, iterator_category(first));
+  }
+#else /* __STL_MEMBER_TEMPLATES */
+  __BVECTOR(const_iterator first, const_iterator last) {
+    size_type n = 0;
+    distance(first, last, n);
+    initialize(n);
+    copy(first, last, start);
+  }
+  __BVECTOR(const bool* first, const bool* last) {
+    size_type n = 0;
+    distance(first, last, n);
+    initialize(n);
+    copy(first, last, start);
+  }
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  ~__BVECTOR() { deallocate(); }
+  __BVECTOR& operator=(const __BVECTOR& x) {
+    if (&x == this) return *this;
+    if (x.size() > capacity()) {
+      deallocate();
+      initialize(x.size());
+    }
+    copy(x.begin(), x.end(), begin());
+    finish = begin() + difference_type(x.size());
+    return *this;
+  }
+  void reserve(size_type n) {
+    if (capacity() < n) {
+      unsigned int* q = bit_alloc(n);
+      finish = copy(begin(), end(), iterator(q, 0));
+      deallocate();
+      start = iterator(q, 0);
+      end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT;
+    }
+  }
+  reference front() { return *begin(); }
+  const_reference front() const { return *begin(); }
+  reference back() { return *(end() - 1); }
+  const_reference back() const { return *(end() - 1); }
+  void push_back(bool x) {
+    if (finish.p != end_of_storage)
+      *finish++ = x;
+    else
+      insert_aux(end(), x);
+  }
+  void swap(__BVECTOR& x) {
+    __STD::swap(start, x.start);
+    __STD::swap(finish, x.finish);
+    __STD::swap(end_of_storage, x.end_of_storage);
+  }
+  iterator insert(iterator position, bool x = bool()) {
+    difference_type n = position - begin();
+    if (finish.p != end_of_storage && position == end())
+      *finish++ = x;
+    else
+      insert_aux(position, x);
+    return begin() + n;
+  }
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator> void insert(iterator position,
+                                             InputIterator first,
+                                             InputIterator last) {
+    insert_range(position, first, last, iterator_category(first));
+  }
+#else /* __STL_MEMBER_TEMPLATES */
+  void insert(iterator position, const_iterator first, 
+              const_iterator last) {
+    if (first == last) return;
+    size_type n = 0;
+    distance(first, last, n);
+    if (capacity() - size() >= n) {
+      copy_backward(position, end(), finish + n);
+      copy(first, last, position);
+      finish += n;
+    }
+    else {
+      size_type len = size() + max(size(), n);
+      unsigned int* q = bit_alloc(len);
+      iterator i = copy(begin(), position, iterator(q, 0));
+      i = copy(first, last, i);
+      finish = copy(position, end(), i);
+      deallocate();
+      end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
+      start = iterator(q, 0);
+    }
+  }
+
+  void insert(iterator position, const bool* first, const bool* last) {
+    if (first == last) return;
+    size_type n = 0;
+    distance(first, last, n);
+    if (capacity() - size() >= n) {
+      copy_backward(position, end(), finish + n);
+      copy(first, last, position);
+      finish += n;
+    }
+    else {
+      size_type len = size() + max(size(), n);
+      unsigned int* q = bit_alloc(len);
+      iterator i = copy(begin(), position, iterator(q, 0));
+      i = copy(first, last, i);
+      finish = copy(position, end(), i);
+      deallocate();
+      end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
+      start = iterator(q, 0);
+    }
+  }
+#endif /* __STL_MEMBER_TEMPLATES */
+  
+  void insert(iterator position, size_type n, bool x) {
+    if (n == 0) return;
+    if (capacity() - size() >= n) {
+      copy_backward(position, end(), finish + difference_type(n));
+      fill(position, position + difference_type(n), x);
+      finish += difference_type(n);
+    }
+    else {
+      size_type len = size() + max(size(), n);
+      unsigned int* q = bit_alloc(len);
+      iterator i = copy(begin(), position, iterator(q, 0));
+      fill_n(i, n, x);
+      finish = copy(position, end(), i + difference_type(n));
+      deallocate();
+      end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
+      start = iterator(q, 0);
+    }
+  }
+
+  void insert(iterator pos, int n, bool x)  { insert(pos, (size_type)n, x); }
+  void insert(iterator pos, long n, bool x) { insert(pos, (size_type)n, x); }
+
+  void pop_back() { --finish; }
+  void erase(iterator position) {
+    if (position + 1 != end())
+      copy(position + 1, end(), position);
+    --finish;
+  }
+  void erase(iterator first, iterator last) {
+    finish = copy(last, end(), first);
+  }
+  void resize(size_type new_size, bool x = bool()) {
+    if (new_size < size()) 
+      erase(begin() + difference_type(new_size), end());
+    else
+      insert(end(), new_size - size(), x);
+  }
+  void clear() { erase(begin(), end()); }
+};
+
+#ifdef __SGI_STL_VECBOOL_TEMPLATE
+
+typedef vector<bool, alloc> bit_vector;
+
+#else /* __SGI_STL_VECBOOL_TEMPLATE */
+
+inline bool operator==(const bit_vector& x, const bit_vector& y) {
+  return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+inline bool operator<(const bit_vector& x, const bit_vector& y) {
+  return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+#endif /* __SGI_STL_VECBOOL_TEMPLATE */
+
+#undef __SGI_STL_VECBOOL_TEMPLATE
+#undef __BVECTOR
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1174
+#endif
+
+__STL_END_NAMESPACE 
+
+#endif /* __SGI_STL_INTERNAL_BVECTOR_H */
+
+// Local Variables:
+// mode:C++
+// End:
index 31e96cf..c654666 100644 (file)
 # define __STL_CONFIG_H
 
 // What this file does.
-//  (1) Defines bool, true, and false if the compiler doesn't do so already.
-//  (2) Defines __STL_NO_DRAND48 if the compiler's standard library does
-//      not support the drand48() function.
-//  (3) Defines __STL_STATIC_TEMPLATE_MEMBER_BUG if the compiler can't 
-//      handle static members of template classes.
-//  (4) Defines 'typename' as a null macro if the compiler does not support
-//      the typename keyword.
-//  (5) Defines __STL_CLASS_PARTIAL_SPECIALIZATION if the compiler 
-//      supports partial specialization of template classes.
-//  (6) Defines __STL_MEMBER_TEMPLATES if the compiler supports
-//      template members of classes.
-//  (7) Defines 'explicit' as a null macro if the compiler does not support
-//      the explicit keyword.    
-//  (8) Defines __STL_LIMITED_DEFAULT_TEMPLATES if the compiler is
-//      unable to handle default template parameters that depend on
-//      previous template parameters.
-//  (9) Defines __STL_NON_TYPE_TMPL_PARAM_BUG if the compiler has 
-//      trouble performing function template argument deduction for
-//      non-type template parameters.
-//  (10) Defines __SGI_STL_NO_ARROW_OPERATOR if the compiler is unable
+//  (1)  Defines bool, true, and false if the compiler doesn't do so already.
+//  (2)  Defines __STL_NO_DRAND48 if the compiler's standard library does
+//       not support the drand48() function.
+//  (3)  Defines __STL_STATIC_TEMPLATE_MEMBER_BUG if the compiler can't 
+//       handle static members of template classes.
+//  (4)  Defines 'typename' as a null macro if the compiler does not support
+//       the typename keyword.
+//  (5)  Defines __STL_CLASS_PARTIAL_SPECIALIZATION if the compiler 
+//       supports partial specialization of class templates.
+//  (6)  Defines __STL_FUNCTION_TMPL_PARTIAL_ORDER if the compiler supports
+//       partial ordering of function templates (a.k.a partial specialization
+//       of function templates.
+//  (7)  Defines __STL_EXPLICIT_FUNCTION_TMPL_ARGS if the compiler
+//       supports calling a function template by providing its template
+//       arguments explicitly.
+//  (8)  Defines __STL_MEMBER_TEMPLATES if the compiler supports
+//       template members of classes.
+//  (9)  Defines 'explicit' as a null macro if the compiler does not support
+//       the explicit keyword.    
+//  (10) Defines __STL_LIMITED_DEFAULT_TEMPLATES if the compiler is
+//       unable to handle default template parameters that depend on
+//       previous template parameters.
+//  (11) Defines __STL_NON_TYPE_TMPL_PARAM_BUG if the compiler has 
+//       trouble performing function template argument deduction for
+//       non-type template parameters.
+//  (12) Defines __SGI_STL_NO_ARROW_OPERATOR if the compiler is unable
 //       to support the -> operator for iterators.
-//  (11) Defines __STL_USE_EXCEPTIONS if the compiler (in the current
+//  (13) Defines __STL_USE_EXCEPTIONS if the compiler (in the current
 //       compilation mode) supports exceptions.
-//  (12) Defines __STL_SGI_THREADS if this is being compiled on an SGI
+//  (14) Define __STL_USE_NAMESPACES if we're putting the STL into a 
+//       namespace.  
+//  (15) Defines __STL_SGI_THREADS if this is being compiled on an SGI
 //       compiler, and if the user hasn't selected pthreads or no threads
 //       instead.
-//  (13) Defines __STL_WIN32THREADS if this is being compiled on a 
+//  (16) Defines __STL_WIN32THREADS if this is being compiled on a 
 //       WIN32 compiler in multithreaded mode.
-//  (14) Defines __stl_assert either as a test or as a null macro,
+//  (17) Define namespace-related macros (__STD, __STL_BEGIN_NAMESPACE, etc.)
+//       apropriately.
+//  (18) Define exception-related macros (__STL_TRY, __STL_UNWIND, etc.)
+//       appropriately.
+//  (19) Defines __stl_assert either as a test or as a null macro,
 //       depending on whether or not __STL_ASSERTIONS is defined.
 
 # if defined(__sgi) && !defined(__GNUC__)
@@ -78,6 +90,9 @@
 #   ifdef __EXCEPTIONS
 #     define __STL_USE_EXCEPTIONS
 #   endif
+#   if (_COMPILER_VERSION >= 721) && defined(_NAMESPACES)
+#     define __STL_USE_NAMESPACES
+#   endif 
 #   if !defined(_NOTHREADS) && !defined(_PTHREADS)
 #     define __STL_SGI_THREADS
 #   endif
 #     define __STL_NEED_EXPLICIT
 #   else
 #     define __STL_CLASS_PARTIAL_SPECIALIZATION
+#     define __STL_FUNCTION_TMPL_PARTIAL_ORDER
+#     define __STL_EXPLICIT_FUNCTION_TMPL_ARGS
 #     define __STL_MEMBER_TEMPLATES
 #   endif
 #   ifdef __EXCEPTIONS
 #   define __STL_MEMBER_TEMPLATES
 #   define __STL_CLASS_PARTIAL_SPECIALIZATION
 #   define __STL_USE_EXCEPTIONS
+#   define __STL_USE_NAMESPACES
 # endif
 
 # if defined(_MSC_VER)
     typedef int bool;
 #   define true 1
 #   define false 0
-#   undef __STL_NEED_BOOL
 # endif
 
 # ifdef __STL_NEED_TYPENAME
 #   define typename
-#   undef __STL_NEED_TYPENAME
 # endif
 
 # ifdef __STL_NEED_EXPLICIT
 #   define explicit
-#   undef __STL_NEED_EXPLICIT
+# endif
+
+# ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS
+#   define __STL_NULL_TMPL_ARGS <>
+# else
+#   define __STL_NULL_TMPL_ARGS
+# endif
+
+# ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+#   define __STL_TEMPLATE_NULL template<>
+# else
+#   define __STL_TEMPLATE_NULL
+# endif
+
+// __STL_NO_NAMESPACES is a hook so that users can disable namespaces
+// without having to edit library headers.
+# if defined(__STL_USE_NAMESPACES) && !defined(__STL_NO_NAMESPACES)
+#   define __STD std
+#   define __STL_BEGIN_NAMESPACE namespace std {
+#   define __STL_END_NAMESPACE }
+#   define  __STL_USE_NAMESPACE_FOR_RELOPS
+#   define __STL_BEGIN_RELOPS_NAMESPACE namespace std {
+#   define __STL_END_RELOPS_NAMESPACE }
+#   define __STD_RELOPS std
+# else
+#   define __STD 
+#   define __STL_BEGIN_NAMESPACE 
+#   define __STL_END_NAMESPACE 
+#   undef  __STL_USE_NAMESPACE_FOR_RELOPS
+#   define __STL_BEGIN_RELOPS_NAMESPACE 
+#   define __STL_END_RELOPS_NAMESPACE 
+#   define __STD_RELOPS 
+# endif
+
+# ifdef __STL_USE_EXCEPTIONS
+#   define __STL_TRY try
+#   define __STL_CATCH_ALL catch(...)
+#   define __STL_RETHROW throw
+#   define __STL_NOTHROW throw()
+#   define __STL_UNWIND(action) catch(...) { action; throw; }
+# else
+#   define __STL_TRY 
+#   define __STL_CATCH_ALL if (false)
+#   define __STL_RETHROW 
+#   define __STL_NOTHROW 
+#   define __STL_UNWIND(action) 
 # endif
 
 #ifdef __STL_ASSERTIONS
 #endif
 
 #endif /* __STL_CONFIG_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_construct.h b/libstdc++/stl/stl_construct.h
new file mode 100644 (file)
index 0000000..4687635
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H
+#define __SGI_STL_INTERNAL_CONSTRUCT_H
+
+#include <new.h>
+
+__STL_BEGIN_NAMESPACE
+
+template <class T>
+inline void destroy(T* pointer) {
+    pointer->~T();
+}
+
+template <class T1, class T2>
+inline void construct(T1* p, const T2& value) {
+  new (p) T1(value);
+}
+
+template <class ForwardIterator>
+inline void
+__destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) {
+  for ( ; first < last; ++first)
+    destroy(&*first);
+}
+
+template <class ForwardIterator> 
+inline void __destroy_aux(ForwardIterator, ForwardIterator, __true_type) {}
+
+template <class ForwardIterator, class T>
+inline void __destroy(ForwardIterator first, ForwardIterator last, T*) {
+  typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor;
+  __destroy_aux(first, last, trivial_destructor());
+}
+
+template <class ForwardIterator>
+inline void destroy(ForwardIterator first, ForwardIterator last) {
+  __destroy(first, last, value_type(first));
+}
+
+inline void destroy(char*, char*) {}
+inline void destroy(wchar_t*, wchar_t*) {}
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_CONSTRUCT_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_deque.h b/libstdc++/stl/stl_deque.h
new file mode 100644 (file)
index 0000000..79d4008
--- /dev/null
@@ -0,0 +1,1335 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_DEQUE_H
+#define __SGI_STL_INTERNAL_DEQUE_H
+
+/* Class invariants:
+ *  For any nonsingular iterator i:
+ *    i.node is the address of an element in the map array.  The
+ *      contents of i.node is a pointer to the beginning of a node.
+ *    i.first == *(i.node) 
+ *    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, and that a deque
+ *    with N elements, where N is the buffer size, must have two nodes.
+ *  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].
+ */
+
+
+/*
+ * In previous versions of deque, node_size was fixed by the 
+ * implementation.  In this version, however, users can select
+ * the node size.  Deque has three template parameters; the third,
+ * a number of type size_t, is the number of elements per node.
+ * If the third template parameter is 0 (which is the default), 
+ * then deque will use a default node size.
+ *
+ * The only reason for using an alternate node size is if your application
+ * requires a different performance tradeoff than the default.  If,
+ * for example, your program contains many deques each of which contains
+ * only a few elements, then you might want to save memory (possibly
+ * by sacrificing some speed) by using smaller nodes.
+ *
+ * Unfortunately, some compilers have trouble with non-type template 
+ * parameters; stl_config.h defines __STL_NON_TYPE_TMPL_PARAM_BUG if
+ * that is the case.  If your compiler is one of them, then you will
+ * not be able to use alternate node sizes; you will have to use the
+ * default value.
+ */
+
+__STL_BEGIN_NAMESPACE 
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1174
+#endif
+
+// Note: this function is simply a kludge to work around several compilers'
+//  bugs in handling constant expressions.
+inline size_t __deque_buf_size(size_t n, size_t sz)
+{
+  return n != 0 ? n : (sz < 512 ? size_t(512 / sz) : size_t(1));
+}
+
+#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
+template <class T, class Ref, class Ptr, size_t BufSiz>
+struct __deque_iterator {
+  typedef __deque_iterator<T, T&, T*, BufSiz>             iterator;
+  typedef __deque_iterator<T, const T&, const T*, BufSiz> const_iterator;
+  static size_t buffer_size() {return __deque_buf_size(BufSiz, sizeof(T)); }
+#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */
+template <class T, class Ref, class Ptr>
+struct __deque_iterator {
+  typedef __deque_iterator<T, T&, T*>             iterator;
+  typedef __deque_iterator<T, const T&, const T*> const_iterator;
+  static size_t buffer_size() {return __deque_buf_size(0, sizeof(T)); }
+#endif
+
+  typedef random_access_iterator_tag iterator_category;
+  typedef T value_type;
+  typedef Ptr pointer;
+  typedef Ref reference;
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+  typedef T** map_pointer;
+
+  typedef __deque_iterator self;
+
+  T* cur;
+  T* first;
+  T* last;
+  map_pointer node;
+
+  __deque_iterator(T* x, map_pointer y) 
+    : cur(x), first(*y), last(*y + buffer_size()), node(y) {}
+  __deque_iterator() : cur(0), first(0), last(0), node(0) {}
+  __deque_iterator(const iterator& x)
+    : cur(x.cur), first(x.first), last(x.last), node(x.node) {}
+
+  reference operator*() const { return *cur; }
+#ifndef __SGI_STL_NO_ARROW_OPERATOR
+  pointer operator->() const { return &(operator*()); }
+#endif /* __SGI_STL_NO_ARROW_OPERATOR */
+
+  difference_type operator-(const self& x) const {
+    return difference_type(buffer_size()) * (node - x.node - 1) +
+      (cur - first) + (x.last - x.cur);
+  }
+
+  self& operator++() {
+    ++cur;
+    if (cur == last) {
+      set_node(node + 1);
+      cur = first;
+    }
+    return *this; 
+  }
+  self operator++(int)  {
+    self tmp = *this;
+    ++*this;
+    return tmp;
+  }
+
+  self& operator--() {
+    if (cur == first) {
+      set_node(node - 1);
+      cur = last;
+    }
+    --cur;
+    return *this;
+  }
+  self operator--(int) {
+    self tmp = *this;
+    --*this;
+    return tmp;
+  }
+
+  self& operator+=(difference_type n) {
+    difference_type offset = n + (cur - first);
+    if (offset >= 0 && offset < difference_type(buffer_size()))
+      cur += n;
+    else {
+      difference_type node_offset =
+        offset > 0 ? offset / difference_type(buffer_size())
+                   : -difference_type((-offset - 1) / buffer_size()) - 1;
+      set_node(node + node_offset);
+      cur = first + (offset - node_offset * difference_type(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); }
+
+  bool operator==(const self& x) const { return cur == x.cur; }
+  bool operator!=(const self& x) const { return !(*this == x); }
+  bool operator<(const self& x) const {
+    return (node == x.node) ? (cur < x.cur) : (node < x.node);
+  }
+
+  void set_node(map_pointer new_node) {
+    node = new_node;
+    first = *new_node;
+    last = first + difference_type(buffer_size());
+  }
+};
+
+#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
+
+template <class T, class Ref, class Ptr, size_t BufSiz>
+inline random_access_iterator_tag
+iterator_category(const __deque_iterator<T, Ref, Ptr, BufSiz>&) {
+  return random_access_iterator_tag();
+}
+
+template <class T, class Ref, class Ptr, size_t BufSiz>
+inline T* value_type(const __deque_iterator<T, Ref, Ptr, BufSiz>&) {
+  return 0;
+}
+
+template <class T, class Ref, class Ptr, size_t BufSiz>
+inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr, BufSiz>&) {
+  return 0;
+}
+
+#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */
+
+template <class T, class Ref, class Ptr>
+inline random_access_iterator_tag
+iterator_category(const __deque_iterator<T, Ref, Ptr>&) {
+  return random_access_iterator_tag();
+}
+
+template <class T, class Ref, class Ptr>
+inline T* value_type(const __deque_iterator<T, Ref, Ptr>&) { return 0; }
+
+template <class T, class Ref, class Ptr>
+inline ptrdiff_t* distance_type(const __deque_iterator<T, Ref, Ptr>&) {
+  return 0;
+}
+
+#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+// See __deque_buf_size().  The only reason that the default value is 0
+//  is as a workaround for bugs in the way that some compilers handle
+//  constant expressions.
+template <class T, class Alloc = alloc, size_t BufSiz = 0> 
+class deque {
+public:                         // Basic types
+  typedef T value_type;
+  typedef value_type* pointer;
+  typedef const value_type* const_pointer;
+  typedef value_type& reference;
+  typedef const value_type& const_reference;
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+
+public:                         // Iterators
+#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
+  typedef __deque_iterator<T, T&, T*, BufSiz>              iterator;
+  typedef __deque_iterator<T, const T&, const T&, BufSiz>  const_iterator;
+#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */
+  typedef __deque_iterator<T, T&, T*>                      iterator;
+  typedef __deque_iterator<T, const T&, const T*>          const_iterator;
+#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
+
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+  typedef reverse_iterator<const_iterator> const_reverse_iterator;
+  typedef reverse_iterator<iterator> reverse_iterator;
+#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+  typedef reverse_iterator<const_iterator, value_type, const_reference, 
+                           difference_type>  
+          const_reverse_iterator;
+  typedef reverse_iterator<iterator, value_type, reference, difference_type>
+          reverse_iterator; 
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+protected:                      // Internal typedefs
+  typedef pointer* map_pointer;
+  typedef simple_alloc<value_type, Alloc> data_allocator;
+  typedef simple_alloc<pointer, Alloc> map_allocator;
+
+  static size_type buffer_size() {
+    return __deque_buf_size(BufSiz, sizeof(value_type));
+  }
+  static size_type initial_map_size() { return 8; }
+
+protected:                      // Data members
+  iterator start;
+  iterator finish;
+
+  map_pointer map;
+  size_type map_size;
+
+public:                         // Basic accessors
+  iterator begin() { return start; }
+  iterator end() { return finish; }
+  const_iterator begin() const { return start; }
+  const_iterator end() const { return finish; }
+
+  reverse_iterator rbegin() { return reverse_iterator(finish); }
+  reverse_iterator rend() { return reverse_iterator(start); }
+  const_reverse_iterator rbegin() const {
+    return const_reverse_iterator(finish);
+  }
+  const_reverse_iterator rend() const {
+    return const_reverse_iterator(start);
+  }
+
+  reference operator[](size_type n) { return start[difference_type(n)]; }
+  const_reference operator[](size_type n) const {
+    return start[difference_type(n)];
+  }
+
+  reference front() { return *start; }
+  reference back() {
+    iterator tmp = finish;
+    --tmp;
+    return *tmp;
+  }
+  const_reference front() const { return *start; }
+  const_reference back() const {
+    const_iterator tmp = finish;
+    --tmp;
+    return *tmp;
+  }
+
+  size_type size() const { return finish - start;; }
+  size_type max_size() const { return size_type(-1); }
+  bool empty() const { return finish == start; }
+
+public:                         // Constructor, destructor.
+  deque()
+    : start(), finish(), map(0), map_size(0)
+  {
+    create_map_and_nodes(0);
+  }
+
+  deque(const deque& x)
+    : start(), finish(), map(0), map_size(0)
+  {
+    create_map_and_nodes(x.size());
+    __STL_TRY {
+      uninitialized_copy(x.begin(), x.end(), start);
+    }
+    __STL_UNWIND(destroy_map_and_nodes());
+  }
+
+  deque(size_type n, const value_type& value)
+    : start(), finish(), map(0), map_size(0)
+  {
+    fill_initialize(n, value);
+  }
+
+  deque(int n, const value_type& value)
+    : start(), finish(), map(0), map_size(0)
+  {
+    fill_initialize(n, value);
+  }
+  deque(long n, const value_type& value)
+    : start(), finish(), map(0), map_size(0)
+  {
+    fill_initialize(n, value);
+  }
+
+  explicit deque(size_type n)
+    : start(), finish(), map(0), map_size(0)
+  {
+    fill_initialize(n, value_type());
+  }
+
+#ifdef __STL_MEMBER_TEMPLATES
+
+  template <class InputIterator>
+  deque(InputIterator first, InputIterator last)
+    : start(), finish(), map(0), map_size(0)
+  {
+    range_initialize(first, last, iterator_category(first));
+  }
+
+#else /* __STL_MEMBER_TEMPLATES */
+
+  deque(const value_type* first, const value_type* last)
+    : start(), finish(), map(0), map_size(0)
+  {
+    create_map_and_nodes(last - first);
+    __STL_TRY {
+      uninitialized_copy(first, last, start);
+    }
+    __STL_UNWIND(destroy_map_and_nodes());
+  }
+
+  deque(const_iterator first, const_iterator last)
+    : start(), finish(), map(0), map_size(0)
+  {
+    create_map_and_nodes(last - first);
+    __STL_TRY {
+      uninitialized_copy(first, last, start);
+    }
+    __STL_UNWIND(destroy_map_and_nodes());
+  }
+
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  ~deque() {
+    destroy(start, finish);
+    destroy_map_and_nodes();
+  }
+
+  deque& operator= (const deque& x) {
+    const size_type len = size();
+    if (&x != this) {
+      if (len >= x.size())
+        erase(copy(x.begin(), x.end(), start), finish);
+      else {
+        const_iterator mid = x.begin() + difference_type(len);
+        copy(x.begin(), mid, start);
+        insert(finish, mid, x.end());
+      }
+    }
+    return *this;
+  }        
+
+  void swap(deque& x) {
+    __STD::swap(start, x.start);
+    __STD::swap(finish, x.finish);
+    __STD::swap(map, x.map);
+    __STD::swap(map_size, x.map_size);
+  }
+
+public:                         // push_* and pop_*
+  
+  void push_back(const value_type& t) {
+    if (finish.cur != finish.last - 1) {
+      construct(finish.cur, t);
+      ++finish.cur;
+    }
+    else
+      push_back_aux(t);
+  }
+
+  void push_front(const value_type& t) {
+    if (start.cur != start.first) {
+      construct(start.cur - 1, t);
+      --start.cur;
+    }
+    else
+      push_front_aux(t);
+  }
+
+  void pop_back() {
+    if (finish.cur != finish.first) {
+      --finish.cur;
+      destroy(finish.cur);
+    }
+    else
+      pop_back_aux();
+  }
+
+  void pop_front() {
+    if (start.cur != start.last - 1) {
+      destroy(start.cur);
+      ++start.cur;
+    }
+    else 
+      pop_front_aux();
+  }
+
+public:                         // Insert
+
+  iterator insert(iterator position, const value_type& x) {
+    if (position.cur == start.cur) {
+      push_front(x);
+      return start;
+    }
+    else if (position.cur == finish.cur) {
+      push_back(x);
+      iterator tmp = finish;
+      --tmp;
+      return tmp;
+    }
+    else {
+      return insert_aux(position, x);
+    }
+  }
+
+  iterator insert(iterator position) { return insert(position, value_type()); }
+
+  void insert(iterator pos, size_type n, const value_type& x); 
+
+  void insert(iterator pos, int n, const value_type& x) {
+    insert(pos, (size_type) n, x);
+  }
+  void insert(iterator pos, long n, const value_type& x) {
+    insert(pos, (size_type) n, x);
+  }
+
+#ifdef __STL_MEMBER_TEMPLATES  
+
+  template <class InputIterator>
+  void insert(iterator pos, InputIterator first, InputIterator last) {
+    insert(pos, first, last, iterator_category(first));
+  }
+
+#else /* __STL_MEMBER_TEMPLATES */
+
+  void insert(iterator pos, const value_type* first, const value_type* last);
+  void insert(iterator pos, const_iterator first, const_iterator last);
+
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  void resize(size_type new_size, const value_type& x) {
+    const size_type len = size();
+    if (new_size < len) 
+      erase(start + new_size, finish);
+    else
+      insert(finish, new_size - len, x);
+  }
+
+  void resize(size_type new_size) { resize(new_size, value_type()); }
+
+public:                         // Erase
+  iterator erase(iterator pos) {
+    iterator next = pos;
+    ++next;
+    difference_type index = pos - start;
+    if (index < size() >> 1) {
+      copy_backward(start, pos, next);
+      pop_front();
+    }
+    else {
+      copy(next, finish, pos);
+      pop_back();
+    }
+    return start + index;
+  }
+
+  iterator erase(iterator first, iterator last);
+  void clear(); 
+
+protected:                        // Internal construction/destruction
+
+  void create_map_and_nodes(size_type num_elements);
+  void destroy_map_and_nodes();
+  void fill_initialize(size_type n, const value_type& value);
+
+#ifdef __STL_MEMBER_TEMPLATES  
+
+  template <class InputIterator>
+  void range_initialize(InputIterator first, InputIterator last,
+                        input_iterator_tag);
+
+  template <class ForwardIterator>
+  void range_initialize(ForwardIterator first, ForwardIterator last,
+                        forward_iterator_tag);
+
+#endif /* __STL_MEMBER_TEMPLATES */
+
+protected:                        // Internal push_* and pop_*
+
+  void push_back_aux(const value_type& t);
+  void push_front_aux(const value_type& t);
+  void pop_back_aux();
+  void pop_front_aux();
+
+protected:                        // Internal insert functions
+
+#ifdef __STL_MEMBER_TEMPLATES  
+
+  template <class InputIterator>
+  void insert(iterator pos, InputIterator first, InputIterator last,
+              input_iterator_tag);
+
+  template <class ForwardIterator>
+  void insert(iterator pos, ForwardIterator first, ForwardIterator last,
+              forward_iterator_tag);
+
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  iterator insert_aux(iterator pos, const value_type& x);
+  void insert_aux(iterator pos, size_type n, const value_type& x);
+
+#ifdef __STL_MEMBER_TEMPLATES  
+
+  template <class ForwardIterator>
+  void insert_aux(iterator pos, ForwardIterator first, ForwardIterator last,
+                  size_type n);
+
+#else /* __STL_MEMBER_TEMPLATES */
+  
+  void insert_aux(iterator pos,
+                  const value_type* first, const value_type* last,
+                  size_type n);
+
+  void insert_aux(iterator pos, const_iterator first, const_iterator last,
+                  size_type n);
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  iterator reserve_elements_at_front(size_type n) {
+    size_type vacancies = start.cur - start.first;
+    if (n > vacancies) 
+      new_elements_at_front(n - vacancies);
+    return start - difference_type(n);
+  }
+
+  iterator reserve_elements_at_back(size_type n) {
+    size_type vacancies = (finish.last - finish.cur) - 1;
+    if (n > vacancies)
+      new_elements_at_back(n - vacancies);
+    return finish + difference_type(n);
+  }
+
+  void new_elements_at_front(size_type new_elements);
+  void new_elements_at_back(size_type new_elements);
+
+  void destroy_nodes_at_front(iterator before_start);
+  void destroy_nodes_at_back(iterator after_finish);
+
+protected:                      // Allocation of map and nodes
+
+  // Makes sure the map has space for new nodes.  Does not actually
+  //  add the nodes.  Can invalidate map pointers.  (And consequently, 
+  //  deque iterators.)
+
+  void reserve_map_at_back (size_type nodes_to_add = 1) {
+    if (nodes_to_add + 1 > map_size - (finish.node - map))
+      reallocate_map(nodes_to_add, false);
+  }
+
+  void reserve_map_at_front (size_type nodes_to_add = 1) {
+    if (nodes_to_add > start.node - map)
+      reallocate_map(nodes_to_add, true);
+  }
+
+  void reallocate_map(size_type nodes_to_add, bool add_at_front);
+
+  pointer allocate_node() { return data_allocator::allocate(buffer_size()); }
+  void deallocate_node(pointer n) {
+    data_allocator::deallocate(n, buffer_size());
+  }
+
+#ifdef __STL_NON_TYPE_TMPL_PARAM_BUG
+public:
+  bool operator==(const deque<T, Alloc, 0>& x) const {
+    return size() == x.size() && equal(begin(), end(), x.begin());
+  }
+  bool operator!=(const deque<T, Alloc, 0>& x) const {
+    return size() != x.size() || !equal(begin(), end(), x.begin());
+  }
+  bool operator<(const deque<T, Alloc, 0>& x) const {
+    return lexicographical_compare(begin(), end(), x.begin(), x.end());
+  }
+#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
+};
+
+// Non-inline member functions
+
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::insert(iterator pos,
+                                      size_type n, const value_type& x) {
+  if (pos.cur == start.cur) {
+    iterator new_start = reserve_elements_at_front(n);
+    uninitialized_fill(new_start, start, x);
+    start = new_start;
+  }
+  else if (pos.cur == finish.cur) {
+    iterator new_finish = reserve_elements_at_back(n);
+    uninitialized_fill(finish, new_finish, x);
+    finish = new_finish;
+  }
+  else 
+    insert_aux(pos, n, x);
+}
+
+#ifndef __STL_MEMBER_TEMPLATES  
+
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::insert(iterator pos,
+                                      const value_type* first,
+                                      const value_type* last) {
+  size_type n = last - first;
+  if (pos.cur == start.cur) {
+    iterator new_start = reserve_elements_at_front(n);
+    __STL_TRY {
+      uninitialized_copy(first, last, new_start);
+      start = new_start;
+    }
+    __STL_UNWIND(destroy_nodes_at_front(new_start));
+  }
+  else if (pos.cur == finish.cur) {
+    iterator new_finish = reserve_elements_at_back(n);
+    __STL_TRY {
+      uninitialized_copy(first, last, finish);
+      finish = new_finish;
+    }
+    __STL_UNWIND(destroy_nodes_at_back(new_finish));
+  }
+  else
+    insert_aux(pos, first, last, n);
+}
+
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::insert(iterator pos,
+                                      const_iterator first,
+                                      const_iterator last)
+{
+  size_type n = last - first;
+  if (pos.cur == start.cur) {
+    iterator new_start = reserve_elements_at_front(n);
+    __STL_TRY {
+      uninitialized_copy(first, last, new_start);
+      start = new_start;
+    }
+    __STL_UNWIND(destroy_nodes_at_front(new_start));
+  }
+  else if (pos.cur == finish.cur) {
+    iterator new_finish = reserve_elements_at_back(n);
+    __STL_TRY {
+      uninitialized_copy(first, last, finish);
+      finish = new_finish;
+    }
+    __STL_UNWIND(destroy_nodes_at_back(new_finish));
+  }
+  else
+    insert_aux(pos, first, last, n);
+}
+
+#endif /* __STL_MEMBER_TEMPLATES */
+
+template <class T, class Alloc, size_t BufSize>
+deque<T, Alloc, BufSize>::iterator 
+deque<T, Alloc, BufSize>::erase(iterator first, iterator last) {
+  if (first == start && last == finish) {
+    clear();
+    return finish;
+  }
+  else {
+    difference_type n = last - first;
+    difference_type elems_before = first - start;
+    if (elems_before < (size() - n) / 2) {
+      copy_backward(start, first, last);
+      iterator new_start = start + n;
+      destroy(start, new_start);
+      for (map_pointer cur = start.node; cur < new_start.node; ++cur)
+        data_allocator::deallocate(*cur, buffer_size());
+      start = new_start;
+    }
+    else {
+      copy(last, finish, first);
+      iterator new_finish = finish - n;
+      destroy(new_finish, finish);
+      for (map_pointer cur = new_finish.node + 1; cur <= finish.node; ++cur)
+        data_allocator::deallocate(*cur, buffer_size());
+      finish = new_finish;
+    }
+    return start + elems_before;
+  }
+}
+
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::clear() {
+  for (map_pointer node = start.node + 1; node < finish.node; ++node) {
+    destroy(*node, *node + buffer_size());
+    data_allocator::deallocate(*node, buffer_size());
+  }
+
+  if (start.node != finish.node) {
+    destroy(start.cur, start.last);
+    destroy(finish.first, finish.cur);
+    data_allocator::deallocate(finish.first, buffer_size());
+  }
+  else
+    destroy(start.cur, finish.cur);
+
+  finish = start;
+}
+
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::create_map_and_nodes(size_type num_elements) {
+  size_type num_nodes = num_elements / buffer_size() + 1;
+
+  map_size = max(initial_map_size(), num_nodes + 2);
+  map = map_allocator::allocate(map_size);
+
+  map_pointer nstart = map + (map_size - num_nodes) / 2;
+  map_pointer nfinish = nstart + num_nodes - 1;
+    
+  map_pointer cur;
+  __STL_TRY {
+    for (cur = nstart; cur <= nfinish; ++cur)
+      *cur = allocate_node();
+  }
+#     ifdef  __STL_USE_EXCEPTIONS 
+  catch(...) {
+    for (map_pointer n = nstart; n < cur; ++n)
+      deallocate_node(*n);
+    map_allocator::deallocate(map, map_size);
+    throw;
+  }
+#     endif /* __STL_USE_EXCEPTIONS */
+
+  start.set_node(nstart);
+  finish.set_node(nfinish);
+  start.cur = start.first;
+  finish.cur = finish.first + num_elements % buffer_size();
+}
+
+// This is only used as a cleanup function in catch clauses.
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::destroy_map_and_nodes() {
+  for (map_pointer cur = start.node; cur <= finish.node; ++cur)
+    deallocate_node(*cur);
+  map_allocator::deallocate(map, map_size);
+}
+  
+
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::fill_initialize(size_type n,
+                                               const value_type& value) {
+  create_map_and_nodes(n);
+  map_pointer cur;
+  __STL_TRY {
+    for (cur = start.node; cur < finish.node; ++cur)
+      uninitialized_fill(*cur, *cur + buffer_size(), value);
+    uninitialized_fill(finish.first, finish.cur, value);
+  }
+#       ifdef __STL_USE_EXCEPTIONS
+  catch(...) {
+    for (map_pointer n = start.node; n < cur; ++n)
+      destroy(*n, *n + buffer_size());
+    destroy_map_and_nodes();
+    throw;
+  }
+#       endif /* __STL_USE_EXCEPTIONS */
+}
+
+#ifdef __STL_MEMBER_TEMPLATES  
+
+template <class T, class Alloc, size_t BufSize>
+template <class InputIterator>
+void deque<T, Alloc, BufSize>::range_initialize(InputIterator first,
+                                                InputIterator last,
+                                                input_iterator_tag) {
+  create_map_and_nodes(0);
+  for ( ; first != last; ++first)
+    push_back(*first);
+}
+
+template <class T, class Alloc, size_t BufSize>
+template <class ForwardIterator>
+void deque<T, Alloc, BufSize>::range_initialize(ForwardIterator first,
+                                                ForwardIterator last,
+                                                forward_iterator_tag) {
+  size_type n = 0;
+  distance(first, last, n);
+  create_map_and_nodes(n);
+  __STL_TRY {
+    uninitialized_copy(first, last, start);
+  }
+  __STL_UNWIND(destroy_map_and_nodes());
+}
+
+#endif /* __STL_MEMBER_TEMPLATES */
+
+// Called only if finish.cur == finish.last - 1.
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::push_back_aux(const value_type& t) {
+  value_type t_copy = t;
+  reserve_map_at_back();
+  *(finish.node + 1) = allocate_node();
+  __STL_TRY {
+    construct(finish.cur, t_copy);
+    finish.set_node(finish.node + 1);
+    finish.cur = finish.first;
+  }
+  __STL_UNWIND(deallocate_node(*(finish.node + 1)));
+}
+
+// Called only if start.cur == start.first.
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::push_front_aux(const value_type& t) {
+  value_type t_copy = t;
+  reserve_map_at_front();
+  *(start.node - 1) = allocate_node();
+  __STL_TRY {
+    start.set_node(start.node - 1);
+    start.cur = start.last - 1;
+    construct(start.cur, t_copy);
+  }
+#     ifdef __STL_USE_EXCEPTIONS
+  catch(...) {
+    start.set_node(start.node + 1);
+    start.cur = start.first;
+    deallocate_node(*(start.node - 1));
+    throw;
+  }
+#     endif /* __STL_USE_EXCEPTIONS */
+} 
+
+// Called only if finish.cur == finish.first.
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>:: pop_back_aux() {
+  deallocate_node(finish.first);
+  finish.set_node(finish.node - 1);
+  finish.cur = finish.last - 1;
+  destroy(finish.cur);
+}
+
+// Called only if start.cur == start.last - 1.  Note that if the deque
+//  has at least one element (a necessary precondition for this member
+//  function), and if start.cur == start.last, then the deque must have
+//  at least two nodes.
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::pop_front_aux() {
+  destroy(start.cur);
+  deallocate_node(start.first);
+  start.set_node(start.node + 1);
+  start.cur = start.first;
+}      
+
+#ifdef __STL_MEMBER_TEMPLATES  
+
+template <class T, class Alloc, size_t BufSize>
+template <class InputIterator>
+void deque<T, Alloc, BufSize>::insert(iterator pos,
+                                      InputIterator first, InputIterator last,
+                                      input_iterator_tag) {
+  copy(first, last, inserter(*this, pos));
+}
+
+template <class T, class Alloc, size_t BufSize>
+template <class ForwardIterator>
+void deque<T, Alloc, BufSize>::insert(iterator pos,
+                                      ForwardIterator first,
+                                      ForwardIterator last,
+                                      forward_iterator_tag) {
+  size_type n = 0;
+  distance(first, last, n);
+  if (pos.cur == start.cur) {
+    iterator new_start = reserve_elements_at_front(n);
+    __STL_TRY {
+      uninitialized_copy(first, last, new_start);
+      start = new_start;
+    }
+    __STL_UNWIND(destroy_nodes_at_front(new_start));
+  }
+  else if (pos.cur == finish.cur) {
+    iterator new_finish = reserve_elements_at_back(n);
+    __STL_TRY {
+      uninitialized_copy(first, last, finish);
+      finish = new_finish;
+    }
+    __STL_UNWIND(destroy_nodes_at_back(new_finish));
+  }
+  else
+    insert_aux(pos, first, last, n);
+}
+
+#endif /* __STL_MEMBER_TEMPLATES */
+
+template <class T, class Alloc, size_t BufSize>
+typename deque<T, Alloc, BufSize>::iterator
+deque<T, Alloc, BufSize>::insert_aux(iterator pos, const value_type& x) {
+  difference_type index = pos - start;
+  value_type x_copy = x;
+  if (index < size() / 2) {
+    push_front(front());
+    iterator front1 = start;
+    ++front1;
+    iterator front2 = front1;
+    ++front2;
+    pos = start + index;
+    iterator pos1 = pos;
+    ++pos1;
+    copy(front2, pos1, front1);
+  }
+  else {
+    push_back(back());
+    iterator back1 = finish;
+    --back1;
+    iterator back2 = back1;
+    --back2;
+    pos = start + index;
+    copy_backward(pos, back2, back1);
+  }
+  *pos = x_copy;
+  return pos;
+}
+
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
+                                          size_type n, const value_type& x) {
+  const difference_type elems_before = pos - start;
+  size_type length = size();
+  value_type x_copy = x;
+  if (elems_before < length / 2) {
+    iterator new_start = reserve_elements_at_front(n);
+    iterator old_start = start;
+    pos = start + elems_before;
+    __STL_TRY {
+      if (elems_before >= difference_type(n)) {
+        iterator start_n = start + difference_type(n);
+        uninitialized_copy(start, start_n, new_start);
+        start = new_start;
+        copy(start_n, pos, old_start);
+        fill(pos - difference_type(n), pos, x_copy);
+      }
+      else {
+        __uninitialized_copy_fill(start, pos, new_start, start, x_copy);
+        start = new_start;
+        fill(old_start, pos, x_copy);
+      }
+    }
+    __STL_UNWIND(destroy_nodes_at_front(new_start));
+  }
+  else {
+    iterator new_finish = reserve_elements_at_back(n);
+    iterator old_finish = finish;
+    const difference_type elems_after = difference_type(length) - elems_before;
+    pos = finish - elems_after;
+    __STL_TRY {
+      if (elems_after > difference_type(n)) {
+        iterator finish_n = finish - difference_type(n);
+        uninitialized_copy(finish_n, finish, finish);
+        finish = new_finish;
+        copy_backward(pos, finish_n, old_finish);
+        fill(pos, pos + difference_type(n), x_copy);
+      }
+      else {
+        __uninitialized_fill_copy(finish, pos + difference_type(n),
+                                  x_copy,
+                                  pos, finish);
+        finish = new_finish;
+        fill(pos, old_finish, x_copy);
+      }
+    }
+    __STL_UNWIND(destroy_nodes_at_back(new_finish));
+  }
+}
+
+#ifdef __STL_MEMBER_TEMPLATES  
+
+template <class T, class Alloc, size_t BufSize>
+template <class ForwardIterator>
+void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
+                                          ForwardIterator first,
+                                          ForwardIterator last,
+                                          size_type n)
+{
+  const difference_type elems_before = pos - start;
+  size_type length = size();
+  if (elems_before < length / 2) {
+    iterator new_start = reserve_elements_at_front(n);
+    iterator old_start = start;
+    pos = start + elems_before;
+    __STL_TRY {
+      if (elems_before >= difference_type(n)) {
+        iterator start_n = start + difference_type(n); 
+        uninitialized_copy(start, start_n, new_start);
+        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) - elems_before);
+        __uninitialized_copy_copy(start, pos, first, mid, new_start);
+        start = new_start;
+        copy(mid, last, old_start);
+      }
+    }
+    __STL_UNWIND(destroy_nodes_at_front(new_start));
+  }
+  else {
+    iterator new_finish = reserve_elements_at_back(n);
+    iterator old_finish = finish;
+    const difference_type elems_after = difference_type(length) - elems_before;
+    pos = finish - elems_after;
+    __STL_TRY {
+      if (elems_after > difference_type(n)) {
+        iterator finish_n = finish - difference_type(n);
+        uninitialized_copy(finish_n, finish, finish);
+        finish = new_finish;
+        copy_backward(pos, finish_n, old_finish);
+        copy(first, last, pos);
+      }
+      else {
+        ForwardIterator mid = first;
+        advance(mid, elems_after);
+        __uninitialized_copy_copy(mid, last, pos, finish, finish);
+        finish = new_finish;
+        copy(first, mid, pos);
+      }
+    }
+    __STL_UNWIND(destroy_nodes_at_back(new_finish));
+  }
+}
+
+#else /* __STL_MEMBER_TEMPLATES */
+
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
+                                          const value_type* first,
+                                          const value_type* last,
+                                          size_type n)
+{
+  const difference_type elems_before = pos - start;
+  size_type length = size();
+  if (elems_before < length / 2) {
+    iterator new_start = reserve_elements_at_front(n);
+    iterator old_start = start;
+    pos = start + elems_before;
+    __STL_TRY {
+      if (elems_before >= difference_type(n)) {
+        iterator start_n = start + difference_type(n);
+        uninitialized_copy(start, start_n, new_start);
+        start = new_start;
+        copy(start_n, pos, old_start);
+        copy(first, last, pos - difference_type(n));
+      }
+      else {
+        const value_type* mid = first + (difference_type(n) - elems_before);
+        __uninitialized_copy_copy(start, pos, first, mid, new_start);
+        start = new_start;
+        copy(mid, last, old_start);
+      }
+    }
+    __STL_UNWIND(destroy_nodes_at_front(new_start));
+  }
+  else {
+    iterator new_finish = reserve_elements_at_back(n);
+    iterator old_finish = finish;
+    const difference_type elems_after = difference_type(length) - elems_before;
+    pos = finish - elems_after;
+    __STL_TRY {
+      if (elems_after > difference_type(n)) {
+        iterator finish_n = finish - difference_type(n);
+        uninitialized_copy(finish_n, finish, finish);
+        finish = new_finish;
+        copy_backward(pos, finish_n, old_finish);
+        copy(first, last, pos);
+      }
+      else {
+        const value_type* mid = first + elems_after;
+        __uninitialized_copy_copy(mid, last, pos, finish, finish);
+        finish = new_finish;
+        copy(first, mid, pos);
+      }
+    }
+    __STL_UNWIND(destroy_nodes_at_back(new_finish));
+  }
+}
+
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::insert_aux(iterator pos,
+                                          const_iterator first,
+                                          const_iterator last,
+                                          size_type n)
+{
+  const difference_type elems_before = pos - start;
+  size_type length = size();
+  if (elems_before < length / 2) {
+    iterator new_start = reserve_elements_at_front(n);
+    iterator old_start = start;
+    pos = start + elems_before;
+    __STL_TRY {
+      if (elems_before >= n) {
+        iterator start_n = start + n;
+        uninitialized_copy(start, start_n, new_start);
+        start = new_start;
+        copy(start_n, pos, old_start);
+        copy(first, last, pos - difference_type(n));
+      }
+      else {
+        const_iterator mid = first + (n - elems_before);
+        __uninitialized_copy_copy(start, pos, first, mid, new_start);
+        start = new_start;
+        copy(mid, last, old_start);
+      }
+    }
+    __STL_UNWIND(destroy_nodes_at_front(new_start));
+  }
+  else {
+    iterator new_finish = reserve_elements_at_back(n);
+    iterator old_finish = finish;
+    const difference_type elems_after = length - elems_before;
+    pos = finish - elems_after;
+    __STL_TRY {
+      if (elems_after > n) {
+        iterator finish_n = finish - difference_type(n);
+        uninitialized_copy(finish_n, finish, finish);
+        finish = new_finish;
+        copy_backward(pos, finish_n, old_finish);
+        copy(first, last, pos);
+      }
+      else {
+        const_iterator mid = first + elems_after;
+        __uninitialized_copy_copy(mid, last, pos, finish, finish);
+        finish = new_finish;
+        copy(first, mid, pos);
+      }
+    }
+    __STL_UNWIND(destroy_nodes_at_back(new_finish));
+  }
+}
+
+#endif /* __STL_MEMBER_TEMPLATES */
+
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::new_elements_at_front(size_type new_elements) {
+  size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size();
+  reserve_map_at_front(new_nodes);
+  size_type i;
+  __STL_TRY {
+    for (i = 1; i <= new_nodes; ++i)
+      *(start.node - i) = allocate_node();
+  }
+#       ifdef __STL_USE_EXCEPTIONS
+  catch(...) {
+    for (size_type j = 1; j < i; ++j)
+      deallocate_node(*(start.node - j));      
+    throw;
+  }
+#       endif /* __STL_USE_EXCEPTIONS */
+}
+
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::new_elements_at_back(size_type new_elements) {
+  size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size();
+  reserve_map_at_back(new_nodes);
+  size_type i;
+  __STL_TRY {
+    for (i = 1; i <= new_nodes; ++i)
+      *(finish.node + i) = allocate_node();
+  }
+#       ifdef __STL_USE_EXCEPTIONS
+  catch(...) {
+    for (size_type j = 1; j < i; ++j)
+      deallocate_node(*(finish.node + j));      
+    throw;
+  }
+#       endif /* __STL_USE_EXCEPTIONS */
+}
+
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::destroy_nodes_at_front(iterator before_start) {
+  for (map_pointer n = before_start.node; n < start.node; ++n)
+    deallocate_node(*n);
+}
+
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::destroy_nodes_at_back(iterator after_finish) {
+  for (map_pointer n = after_finish.node; n > finish.node; --n)
+    deallocate_node(*n);
+}
+
+template <class T, class Alloc, size_t BufSize>
+void deque<T, Alloc, BufSize>::reallocate_map(size_type nodes_to_add,
+                                              bool add_at_front) {
+  size_type old_num_nodes = finish.node - start.node + 1;
+  size_type new_num_nodes = old_num_nodes + nodes_to_add;
+
+  map_pointer new_nstart;
+  if (map_size > 2 * new_num_nodes) {
+    new_nstart = map + (map_size - new_num_nodes) / 2 
+                     + (add_at_front ? nodes_to_add : 0);
+    if (new_nstart < start.node)
+      copy(start.node, finish.node + 1, new_nstart);
+    else
+      copy_backward(start.node, finish.node + 1, new_nstart + old_num_nodes);
+  }
+  else {
+    size_type new_map_size = map_size + max(map_size, nodes_to_add) + 2;
+
+    map_pointer new_map = map_allocator::allocate(new_map_size);
+    new_nstart = new_map + (new_map_size - new_num_nodes) / 2
+                         + (add_at_front ? nodes_to_add : 0);
+    copy(start.node, finish.node + 1, new_nstart);
+    map_allocator::deallocate(map, map_size);
+
+    map = new_map;
+    map_size = new_map_size;
+  }
+
+  start.set_node(new_nstart);
+  finish.set_node(new_nstart + old_num_nodes - 1);
+}
+
+
+// Nonmember functions.
+
+#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
+
+template <class T, class Alloc, size_t BufSiz>
+bool operator==(const deque<T, Alloc, BufSiz>& x,
+                const deque<T, Alloc, BufSiz>& y) {
+  return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+template <class T, class Alloc, size_t BufSiz>
+bool operator<(const deque<T, Alloc, BufSiz>& x,
+               const deque<T, Alloc, BufSiz>& y) {
+  return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
+
+#if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) && \
+    !defined(__STL_NON_TYPE_TMPL_PARAM_BUG)
+
+template <class T, class Alloc, size_t BufSiz>
+inline void swap(deque<T, Alloc, BufSiz>& x, deque<T, Alloc, BufSiz>& y) {
+  x.swap(y);
+}
+
+#endif
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1174
+#endif
+          
+__STL_END_NAMESPACE 
+  
+#endif /* __SGI_STL_INTERNAL_DEQUE_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_function.h b/libstdc++/stl/stl_function.h
new file mode 100644 (file)
index 0000000..c0d785d
--- /dev/null
@@ -0,0 +1,628 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_FUNCTION_H
+#define __SGI_STL_INTERNAL_FUNCTION_H
+
+__STL_BEGIN_NAMESPACE
+
+template <class Arg, class Result>
+struct unary_function {
+    typedef Arg argument_type;
+    typedef Result result_type;
+};
+
+template <class Arg1, class Arg2, class Result>
+struct binary_function {
+    typedef Arg1 first_argument_type;
+    typedef Arg2 second_argument_type;
+    typedef Result result_type;
+};      
+
+template <class T>
+struct plus : public binary_function<T, T, T> {
+    T operator()(const T& x, const T& y) const { return x + y; }
+};
+
+template <class T>
+struct minus : public binary_function<T, T, T> {
+    T operator()(const T& x, const T& y) const { return x - y; }
+};
+
+template <class T>
+struct multiplies : public binary_function<T, T, T> {
+    T operator()(const T& x, const T& y) const { return x * y; }
+};
+
+template <class T>
+struct divides : public binary_function<T, T, T> {
+    T operator()(const T& x, const T& y) const { return x / y; }
+};
+
+template <class T> inline T identity_element(plus<T>) { return T(0); }
+
+template <class T> inline T identity_element(multiplies<T>) { return T(1); }
+
+template <class T>
+struct modulus : public binary_function<T, T, T> {
+    T operator()(const T& x, const T& y) const { return x % y; }
+};
+
+template <class T>
+struct negate : public unary_function<T, T> {
+    T operator()(const T& x) const { return -x; }
+};
+
+template <class T>
+struct equal_to : public binary_function<T, T, bool> {
+    bool operator()(const T& x, const T& y) const { return x == y; }
+};
+
+template <class T>
+struct not_equal_to : public binary_function<T, T, bool> {
+    bool operator()(const T& x, const T& y) const { return x != y; }
+};
+
+template <class T>
+struct greater : public binary_function<T, T, bool> {
+    bool operator()(const T& x, const T& y) const { return x > y; }
+};
+
+template <class T>
+struct less : public binary_function<T, T, bool> {
+    bool operator()(const T& x, const T& y) const { return x < y; }
+};
+
+template <class T>
+struct greater_equal : public binary_function<T, T, bool> {
+    bool operator()(const T& x, const T& y) const { return x >= y; }
+};
+
+template <class T>
+struct less_equal : public binary_function<T, T, bool> {
+    bool operator()(const T& x, const T& y) const { return x <= y; }
+};
+
+template <class T>
+struct logical_and : public binary_function<T, T, bool> {
+    bool operator()(const T& x, const T& y) const { return x && y; }
+};
+
+template <class T>
+struct logical_or : public binary_function<T, T, bool> {
+    bool operator()(const T& x, const T& y) const { return x || y; }
+};
+
+template <class T>
+struct logical_not : public unary_function<T, bool> {
+    bool operator()(const T& x) const { return !x; }
+};
+
+template <class Predicate>
+class unary_negate
+  : public unary_function<typename Predicate::argument_type, bool> {
+protected:
+  Predicate pred;
+public:
+  explicit unary_negate(const Predicate& x) : pred(x) {}
+  bool operator()(const typename Predicate::argument_type& x) const {
+    return !pred(x);
+  }
+};
+
+template <class Predicate>
+inline unary_negate<Predicate> not1(const Predicate& pred) {
+  return unary_negate<Predicate>(pred);
+}
+
+template <class Predicate> 
+class binary_negate 
+  : public binary_function<typename Predicate::first_argument_type,
+                           typename Predicate::second_argument_type,
+                           bool> {
+protected:
+  Predicate pred;
+public:
+  explicit binary_negate(const Predicate& x) : pred(x) {}
+  bool operator()(const typename Predicate::first_argument_type& x, 
+                  const typename Predicate::second_argument_type& y) const {
+    return !pred(x, y); 
+  }
+};
+
+template <class Predicate>
+inline binary_negate<Predicate> not2(const Predicate& pred) {
+  return binary_negate<Predicate>(pred);
+}
+
+template <class Operation> 
+class binder1st
+  : public unary_function<typename Operation::second_argument_type,
+                          typename Operation::result_type> {
+protected:
+  Operation op;
+  typename Operation::first_argument_type value;
+public:
+  binder1st(const Operation& x,
+            const typename Operation::first_argument_type& y)
+      : op(x), value(y) {}
+  typename Operation::result_type
+  operator()(const typename Operation::second_argument_type& x) const {
+    return op(value, x); 
+  }
+};
+
+template <class Operation, class T>
+inline binder1st<Operation> bind1st(const Operation& op, const T& x) {
+  typedef typename Operation::first_argument_type arg1_type;
+  return binder1st<Operation>(op, arg1_type(x));
+}
+
+template <class Operation> 
+class binder2nd
+  : public unary_function<typename Operation::first_argument_type,
+                          typename Operation::result_type> {
+protected:
+  Operation op;
+  typename Operation::second_argument_type value;
+public:
+  binder2nd(const Operation& x,
+            const typename Operation::second_argument_type& y) 
+      : op(x), value(y) {}
+  typename Operation::result_type
+  operator()(const typename Operation::first_argument_type& x) const {
+    return op(x, value); 
+  }
+};
+
+template <class Operation, class T>
+inline binder2nd<Operation> bind2nd(const Operation& op, const T& x) {
+  typedef typename Operation::second_argument_type arg2_type;
+  return binder2nd<Operation>(op, arg2_type(x));
+}
+
+template <class Operation1, class Operation2>
+class unary_compose : public unary_function<typename Operation2::argument_type,
+                                            typename Operation1::result_type> {
+protected:
+  Operation1 op1;
+  Operation2 op2;
+public:
+  unary_compose(const Operation1& x, const Operation2& y) : op1(x), op2(y) {}
+  typename Operation1::result_type
+  operator()(const typename Operation2::argument_type& x) const {
+    return op1(op2(x));
+  }
+};
+
+template <class Operation1, class Operation2>
+inline unary_compose<Operation1, Operation2> compose1(const Operation1& op1, 
+                                                      const Operation2& op2) {
+  return unary_compose<Operation1, Operation2>(op1, op2);
+}
+
+template <class Operation1, class Operation2, class Operation3>
+class binary_compose
+  : public unary_function<typename Operation2::argument_type,
+                          typename Operation1::result_type> {
+protected:
+  Operation1 op1;
+  Operation2 op2;
+  Operation3 op3;
+public:
+  binary_compose(const Operation1& x, const Operation2& y, 
+                 const Operation3& z) : op1(x), op2(y), op3(z) { }
+  typename Operation1::result_type
+  operator()(const typename Operation2::argument_type& x) const {
+    return op1(op2(x), op3(x));
+  }
+};
+
+template <class Operation1, class Operation2, class Operation3>
+inline binary_compose<Operation1, Operation2, Operation3> 
+compose2(const Operation1& op1, const Operation2& op2, const Operation3& op3) {
+  return binary_compose<Operation1, Operation2, Operation3>(op1, op2, op3);
+}
+
+template <class Arg, class Result>
+class pointer_to_unary_function : public unary_function<Arg, Result> {
+protected:
+  Result (*ptr)(Arg);
+public:
+  pointer_to_unary_function() {}
+  explicit pointer_to_unary_function(Result (*x)(Arg)) : ptr(x) {}
+  Result operator()(Arg x) const { return ptr(x); }
+};
+
+template <class Arg, class Result>
+inline pointer_to_unary_function<Arg, Result> ptr_fun(Result (*x)(Arg)) {
+  return pointer_to_unary_function<Arg, Result>(x);
+}
+
+template <class Arg1, class Arg2, class Result>
+class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result> {
+protected:
+    Result (*ptr)(Arg1, Arg2);
+public:
+    pointer_to_binary_function() {}
+    explicit pointer_to_binary_function(Result (*x)(Arg1, Arg2)) : ptr(x) {}
+    Result operator()(Arg1 x, Arg2 y) const { return ptr(x, y); }
+};
+
+template <class Arg1, class Arg2, class Result>
+inline pointer_to_binary_function<Arg1, Arg2, Result> 
+ptr_fun(Result (*x)(Arg1, Arg2)) {
+  return pointer_to_binary_function<Arg1, Arg2, Result>(x);
+}
+
+template <class T>
+struct identity : public unary_function<T, T> {
+  const T& operator()(const T& x) const { return x; }
+};
+
+template <class Pair>
+struct select1st : public unary_function<Pair, typename Pair::first_type> {
+  const typename Pair::first_type& operator()(const Pair& x) const
+  {
+    return x.first;
+  }
+};
+
+template <class Pair>
+struct select2nd : public unary_function<Pair, typename Pair::second_type> {
+  const typename Pair::second_type& operator()(const Pair& x) const
+  {
+    return x.second;
+  }
+};
+
+template <class Arg1, class Arg2>
+struct project1st : public binary_function<Arg1, Arg2, Arg1> {
+  Arg1 operator()(const Arg1& x, const Arg2&) const { return x; }
+};
+
+template <class Arg1, class Arg2>
+struct project2nd : public binary_function<Arg1, Arg2, Arg2> {
+  Arg2 operator()(const Arg1&, const Arg2& y) const { return y; }
+};
+
+template <class Result>
+struct constant_void_fun
+{
+  typedef Result result_type;
+  result_type val;
+  constant_void_fun(const result_type& v) : val(v) {}
+  const result_type& operator()() const { return val; }
+};  
+
+#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
+template <class Result, class Argument = Result>
+#else
+template <class Result, class Argument>
+#endif
+struct constant_unary_fun : public unary_function<Argument, Result> {
+  Result val;
+  constant_unary_fun(const Result& v) : val(v) {}
+  const Result& operator()(const Argument&) const { return val; }
+};
+
+#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
+template <class Result, class Arg1 = Result, class Arg2 = Arg1>
+#else
+template <class Result, class Arg1, class Arg2>
+#endif
+struct constant_binary_fun : public binary_function<Arg1, Arg2, Result> {
+  Result val;
+  constant_binary_fun(const Result& v) : val(v) {}
+  const Result& operator()(const Arg1&, const Arg2&) const {
+    return val;
+  }
+};
+
+template <class Result>
+inline constant_void_fun<Result> constant0(const Result& val)
+{
+  return constant_void_fun<Result>(val);
+}
+
+template <class Result>
+inline constant_unary_fun<Result,Result> constant1(const Result& val)
+{
+  return constant_unary_fun<Result,Result>(val);
+}
+
+template <class Result>
+inline constant_binary_fun<Result,Result,Result> constant2(const Result& val)
+{
+  return constant_binary_fun<Result,Result,Result>(val);
+}
+
+// Note: this code assumes that int is 32 bits.
+class subtractive_rng : public unary_function<unsigned int, unsigned int> {
+private:
+  unsigned int table[55];
+  size_t index1;
+  size_t index2;
+public:
+  unsigned int operator()(unsigned int limit) {
+    index1 = (index1 + 1) % 55;
+    index2 = (index2 + 1) % 55;
+    table[index1] = table[index1] - table[index2];
+    return table[index1] % limit;
+  }
+
+  void initialize(unsigned int seed)
+  {
+    unsigned int k = 1;
+    table[54] = seed;
+    size_t i;
+    for (i = 0; i < 54; i++) {
+        size_t ii = (21 * (i + 1) % 55) - 1;
+        table[ii] = k;
+        k = seed - k;
+        seed = table[ii];
+    }
+    for (int loop = 0; loop < 4; loop++) {
+        for (i = 0; i < 55; i++)
+            table[i] = table[i] - table[(1 + i + 30) % 55];
+    }
+    index1 = 0;
+    index2 = 31;
+  }
+
+  subtractive_rng(unsigned int seed) { initialize(seed); }
+  subtractive_rng() { initialize(161803398u); }
+};
+
+
+// Adaptor function objects: pointers to member functions.
+
+// There are a total of 16 = 2^4 function objects in this family.
+//  (1) Member functions taking no arguments vs member functions taking
+//       one argument.
+//  (2) Call through pointer vs call through reference.
+//  (3) Member function with void return type vs member function with
+//      non-void return type.
+//  (4) Const vs non-const member function.
+
+// Note that choice (4) is not present in the 8/97 draft C++ standard, 
+//  which only allows these adaptors to be used with non-const functions.
+//  This is likely to be recified before the standard becomes final.
+// Note also that choice (3) is nothing more than a workaround: according
+//  to the draft, compilers should handle void and non-void the same way.
+//  This feature is not yet widely implemented, though.  You can only use
+//  member functions returning void if your compiler supports partial
+//  specialization.
+
+// All of this complexity is in the function objects themselves.  You can
+//  ignore it by using the helper function mem_fun, mem_fun_ref,
+//  mem_fun1, and mem_fun1_ref, which create whichever type of adaptor
+//  is appropriate.
+
+
+template <class S, class T>
+class mem_fun_t : public unary_function<T*, S> {
+public:
+  explicit mem_fun_t(S (T::*pf)()) : f(pf) {}
+  S operator()(T* p) const { return (p->*f)(); }
+private:
+  S (T::*f)();
+};
+
+template <class S, class T>
+class const_mem_fun_t : public unary_function<const T*, S> {
+public:
+  explicit const_mem_fun_t(S (T::*pf)() const) : f(pf) {}
+  S operator()(const T* p) const { return (p->*f)(); }
+private:
+  S (T::*f)() const;
+};
+
+
+template <class S, class T>
+class mem_fun_ref_t : public unary_function<T, S> {
+public:
+  explicit mem_fun_ref_t(S (T::*pf)()) : f(pf) {}
+  S operator()(T& r) const { return (r.*f)(); }
+private:
+  S (T::*f)();
+};
+
+template <class S, class T>
+class const_mem_fun_ref_t : public unary_function<T, S> {
+public:
+  explicit const_mem_fun_ref_t(S (T::*pf)() const) : f(pf) {}
+  S operator()(const T& r) const { return (r.*f)(); }
+private:
+  S (T::*f)() const;
+};
+
+template <class S, class T, class A>
+class mem_fun1_t : public binary_function<T*, A, S> {
+public:
+  explicit mem_fun1_t(S (T::*pf)(A)) : f(pf) {}
+  S operator()(T* p, A x) const { return (p->*f)(x); }
+private:
+  S (T::*f)(A);
+};
+
+template <class S, class T, class A>
+class const_mem_fun1_t : public binary_function<const T*, A, S> {
+public:
+  explicit const_mem_fun1_t(S (T::*pf)(A) const) : f(pf) {}
+  S operator()(const T* p, A x) const { return (p->*f)(x); }
+private:
+  S (T::*f)(A) const;
+};
+
+template <class S, class T, class A>
+class mem_fun1_ref_t : public binary_function<T, A, S> {
+public:
+  explicit mem_fun1_ref_t(S (T::*pf)(A)) : f(pf) {}
+  S operator()(T& r, A x) const { return (r.*f)(x); }
+private:
+  S (T::*f)(A);
+};
+
+template <class S, class T, class A>
+class const_mem_fun1_ref_t : public binary_function<T, A, S> {
+public:
+  explicit const_mem_fun1_ref_t(S (T::*pf)(A) const) : f(pf) {}
+  S operator()(const T& r, A x) const { return (r.*f)(x); }
+private:
+  S (T::*f)(A) const;
+};
+
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+template <class T>
+class mem_fun_t<void, T> : public unary_function<T*, void> {
+public:
+  explicit mem_fun_t(void (T::*pf)()) : f(pf) {}
+  void operator()(T* p) const { (p->*f)(); }
+private:
+  void (T::*f)();
+};
+
+template <class T>
+class const_mem_fun_t<void, T> : public unary_function<const T*, void> {
+public:
+  explicit const_mem_fun_t(void (T::*pf)() const) : f(pf) {}
+  void operator()(const T* p) const { (p->*f)(); }
+private:
+  void (T::*f)() const;
+};
+
+template <class T>
+class mem_fun_ref_t<void, T> : public unary_function<T, void> {
+public:
+  explicit mem_fun_ref_t(void (T::*pf)()) : f(pf) {}
+  void operator()(T& r) const { (r.*f)(); }
+private:
+  void (T::*f)();
+};
+
+template <class T>
+class const_mem_fun_ref_t<void, T> : public unary_function<T, void> {
+public:
+  explicit const_mem_fun_ref_t(void (T::*pf)() const) : f(pf) {}
+  void operator()(const T& r) const { (r.*f)(); }
+private:
+  void (T::*f)() const;
+};
+
+template <class T, class A>
+class mem_fun1_t<void, T, A> : public binary_function<T*, A, void> {
+public:
+  explicit mem_fun1_t(void (T::*pf)(A)) : f(pf) {}
+  void operator()(T* p, A x) const { (p->*f)(x); }
+private:
+  void (T::*f)(A);
+};
+
+template <class T, class A>
+class const_mem_fun1_t<void, T, A> : public binary_function<const T*, A, void> {
+public:
+  explicit const_mem_fun1_t(void (T::*pf)(A) const) : f(pf) {}
+  void operator()(const T* p, A x) const { (p->*f)(x); }
+private:
+  void (T::*f)(A) const;
+};
+
+template <class T, class A>
+class mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> {
+public:
+  explicit mem_fun1_ref_t(void (T::*pf)(A)) : f(pf) {}
+  void operator()(T& r, A x) const { (r.*f)(x); }
+private:
+  void (T::*f)(A);
+};
+
+template <class T, class A>
+class const_mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> {
+public:
+  explicit const_mem_fun1_ref_t(void (T::*pf)(A) const) : f(pf) {}
+  void operator()(const T& r, A x) const { (r.*f)(x); }
+private:
+  void (T::*f)(A) const;
+};
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+// Mem_fun adaptor helper functions.  There are only four:
+//  mem_fun, mem_fun_ref, mem_fun1, mem_fun1_ref.
+
+template <class S, class T>
+inline mem_fun_t<S,T> mem_fun(S (T::*f)()) { 
+  return mem_fun_t<S,T>(f);
+}
+
+template <class S, class T>
+inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const) {
+  return const_mem_fun_t<S,T>(f);
+}
+
+template <class S, class T>
+inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)()) { 
+  return mem_fun_ref_t<S,T>(f);
+}
+
+template <class S, class T>
+inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const) {
+  return const_mem_fun_ref_t<S,T>(f);
+}
+
+template <class S, class T, class A>
+inline mem_fun1_t<S,T,A> mem_fun1(S (T::*f)(A)) { 
+  return mem_fun1_t<S,T,A>(f);
+}
+
+template <class S, class T, class A>
+inline const_mem_fun1_t<S,T,A> mem_fun1(S (T::*f)(A) const) {
+  return const_mem_fun1_t<S,T,A>(f);
+}
+
+template <class S, class T, class A>
+inline mem_fun1_ref_t<S,T,A> mem_fun1_ref(S (T::*f)(A)) { 
+  return mem_fun1_ref_t<S,T,A>(f);
+}
+
+template <class S, class T, class A>
+inline const_mem_fun1_ref_t<S,T,A> mem_fun1_ref(S (T::*f)(A) const) {
+  return const_mem_fun1_ref_t<S,T,A>(f);
+}
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_FUNCTION_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_hash_fun.h b/libstdc++/stl/stl_hash_fun.h
new file mode 100644 (file)
index 0000000..3afa9dc
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_HASH_FUN_H
+#define __SGI_STL_HASH_FUN_H
+
+#include <stddef.h>
+
+__STL_BEGIN_NAMESPACE
+
+template <class Key> struct hash { };
+
+inline size_t __stl_hash_string(const char* s)
+{
+  unsigned long h = 0; 
+  for ( ; *s; ++s)
+    h = 5*h + *s;
+  
+  return size_t(h);
+}
+
+__STL_TEMPLATE_NULL struct hash<char*>
+{
+  size_t operator()(const char* s) const { return __stl_hash_string(s); }
+};
+
+__STL_TEMPLATE_NULL struct hash<const char*>
+{
+  size_t operator()(const char* s) const { return __stl_hash_string(s); }
+};
+
+__STL_TEMPLATE_NULL struct hash<char> {
+  size_t operator()(char x) const { return x; }
+};
+__STL_TEMPLATE_NULL struct hash<unsigned char> {
+  size_t operator()(unsigned char x) const { return x; }
+};
+__STL_TEMPLATE_NULL struct hash<signed char> {
+  size_t operator()(unsigned char x) const { return x; }
+};
+__STL_TEMPLATE_NULL struct hash<short> {
+  size_t operator()(short x) const { return x; }
+};
+__STL_TEMPLATE_NULL struct hash<unsigned short> {
+  size_t operator()(unsigned short x) const { return x; }
+};
+__STL_TEMPLATE_NULL struct hash<int> {
+  size_t operator()(int x) const { return x; }
+};
+__STL_TEMPLATE_NULL struct hash<unsigned int> {
+  size_t operator()(unsigned int x) const { return x; }
+};
+__STL_TEMPLATE_NULL struct hash<long> {
+  size_t operator()(long x) const { return x; }
+};
+__STL_TEMPLATE_NULL struct hash<unsigned long> {
+  size_t operator()(unsigned long x) const { return x; }
+};
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_HASH_FUN_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_hash_map.h b/libstdc++/stl/stl_hash_map.h
new file mode 100644 (file)
index 0000000..9999e9a
--- /dev/null
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_HASH_MAP_H
+#define __SGI_STL_INTERNAL_HASH_MAP_H
+
+
+__STL_BEGIN_NAMESPACE
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1174
+#endif
+
+#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
+template <class Key, class T, class HashFcn = hash<Key>,
+          class EqualKey = equal_to<Key>,
+          class Alloc = alloc>
+#else
+template <class Key, class T, class HashFcn, class EqualKey, 
+          class Alloc = alloc>
+#endif
+class hash_map
+{
+private:
+  typedef hashtable<pair<const Key, T>, Key, HashFcn,
+                    select1st<pair<const Key, T> >, EqualKey, Alloc> ht;
+  ht rep;
+
+public:
+  typedef typename ht::key_type key_type;
+  typedef T data_type;
+  typedef T mapped_type;
+  typedef typename ht::value_type value_type;
+  typedef typename ht::hasher hasher;
+  typedef typename ht::key_equal key_equal;
+
+  typedef typename ht::size_type size_type;
+  typedef typename ht::difference_type difference_type;
+  typedef typename ht::pointer pointer;
+  typedef typename ht::const_pointer const_pointer;
+  typedef typename ht::reference reference;
+  typedef typename ht::const_reference const_reference;
+
+  typedef typename ht::iterator iterator;
+  typedef typename ht::const_iterator const_iterator;
+
+  hasher hash_funct() const { return rep.hash_funct(); }
+  key_equal key_eq() const { return rep.key_eq(); }
+
+public:
+  hash_map() : rep(100, hasher(), key_equal()) {}
+  explicit hash_map(size_type n) : rep(n, hasher(), key_equal()) {}
+  hash_map(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
+  hash_map(size_type n, const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) {}
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  hash_map(InputIterator f, InputIterator l)
+    : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
+  template <class InputIterator>
+  hash_map(InputIterator f, InputIterator l, size_type n)
+    : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
+  template <class InputIterator>
+  hash_map(InputIterator f, InputIterator l, size_type n,
+           const hasher& hf)
+    : rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
+  template <class InputIterator>
+  hash_map(InputIterator f, InputIterator l, size_type n,
+           const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) { rep.insert_unique(f, l); }
+
+#else
+  hash_map(const value_type* f, const value_type* l)
+    : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
+  hash_map(const value_type* f, const value_type* l, size_type n)
+    : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
+  hash_map(const value_type* f, const value_type* l, size_type n,
+           const hasher& hf)
+    : rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
+  hash_map(const value_type* f, const value_type* l, size_type n,
+           const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) { rep.insert_unique(f, l); }
+
+  hash_map(const_iterator f, const_iterator l)
+    : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
+  hash_map(const_iterator f, const_iterator l, size_type n)
+    : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
+  hash_map(const_iterator f, const_iterator l, size_type n,
+           const hasher& hf)
+    : rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
+  hash_map(const_iterator f, const_iterator l, size_type n,
+           const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) { rep.insert_unique(f, l); }
+#endif /*__STL_MEMBER_TEMPLATES */
+
+public:
+  size_type size() const { return rep.size(); }
+  size_type max_size() const { return rep.max_size(); }
+  bool empty() const { return rep.empty(); }
+  void swap(hash_map& hs) { rep.swap(hs.rep); }
+  friend bool
+  operator== __STL_NULL_TMPL_ARGS (const hash_map&, const hash_map&);
+
+  iterator begin() { return rep.begin(); }
+  iterator end() { return rep.end(); }
+  const_iterator begin() const { return rep.begin(); }
+  const_iterator end() const { return rep.end(); }
+
+public:
+  pair<iterator, bool> insert(const value_type& obj)
+    { return rep.insert_unique(obj); }
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); }
+#else
+  void insert(const value_type* f, const value_type* l) {
+    rep.insert_unique(f,l);
+  }
+  void insert(const_iterator f, const_iterator l) { rep.insert_unique(f, l); }
+#endif /*__STL_MEMBER_TEMPLATES */
+  pair<iterator, bool> insert_noresize(const value_type& obj)
+    { return rep.insert_unique_noresize(obj); }    
+
+  iterator find(const key_type& key) { return rep.find(key); }
+  const_iterator find(const key_type& key) const { return rep.find(key); }
+
+  T& operator[](const key_type& key) {
+    return rep.find_or_insert(value_type(key, T())).second;
+  }
+
+  size_type count(const key_type& key) const { return rep.count(key); }
+  
+  pair<iterator, iterator> equal_range(const key_type& key)
+    { return rep.equal_range(key); }
+  pair<const_iterator, const_iterator> equal_range(const key_type& key) const
+    { return rep.equal_range(key); }
+
+  size_type erase(const key_type& key) {return rep.erase(key); }
+  void erase(iterator it) { rep.erase(it); }
+  void erase(iterator f, iterator l) { rep.erase(f, l); }
+  void clear() { rep.clear(); }
+
+public:
+  void resize(size_type hint) { rep.resize(hint); }
+  size_type bucket_count() const { return rep.bucket_count(); }
+  size_type max_bucket_count() const { return rep.max_bucket_count(); }
+  size_type elems_in_bucket(size_type n) const
+    { return rep.elems_in_bucket(n); }
+};
+
+template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
+inline bool operator==(const hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1,
+                       const hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2)
+{
+  return hm1.rep == hm2.rep;
+}
+
+#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
+
+template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
+inline void swap(hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1,
+                 hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2)
+{
+  hm1.swap(hm2);
+}
+
+#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
+
+#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
+template <class Key, class T, class HashFcn = hash<Key>,
+          class EqualKey = equal_to<Key>,
+          class Alloc = alloc>
+#else
+template <class Key, class T, class HashFcn, class EqualKey,
+          class Alloc = alloc>
+#endif
+class hash_multimap
+{
+private:
+  typedef hashtable<pair<const Key, T>, Key, HashFcn,
+                    select1st<pair<const Key, T> >, EqualKey, Alloc> ht;
+  ht rep;
+
+public:
+  typedef typename ht::key_type key_type;
+  typedef T data_type;
+  typedef T mapped_type;
+  typedef typename ht::value_type value_type;
+  typedef typename ht::hasher hasher;
+  typedef typename ht::key_equal key_equal;
+
+  typedef typename ht::size_type size_type;
+  typedef typename ht::difference_type difference_type;
+  typedef typename ht::pointer pointer;
+  typedef typename ht::const_pointer const_pointer;
+  typedef typename ht::reference reference;
+  typedef typename ht::const_reference const_reference;
+
+  typedef typename ht::iterator iterator;
+  typedef typename ht::const_iterator const_iterator;
+
+  hasher hash_funct() const { return rep.hash_funct(); }
+  key_equal key_eq() const { return rep.key_eq(); }
+
+public:
+  hash_multimap() : rep(100, hasher(), key_equal()) {}
+  explicit hash_multimap(size_type n) : rep(n, hasher(), key_equal()) {}
+  hash_multimap(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
+  hash_multimap(size_type n, const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) {}
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  hash_multimap(InputIterator f, InputIterator l)
+    : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
+  template <class InputIterator>
+  hash_multimap(InputIterator f, InputIterator l, size_type n)
+    : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
+  template <class InputIterator>
+  hash_multimap(InputIterator f, InputIterator l, size_type n,
+                const hasher& hf)
+    : rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
+  template <class InputIterator>
+  hash_multimap(InputIterator f, InputIterator l, size_type n,
+                const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) { rep.insert_equal(f, l); }
+
+#else
+  hash_multimap(const value_type* f, const value_type* l)
+    : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
+  hash_multimap(const value_type* f, const value_type* l, size_type n)
+    : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
+  hash_multimap(const value_type* f, const value_type* l, size_type n,
+                const hasher& hf)
+    : rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
+  hash_multimap(const value_type* f, const value_type* l, size_type n,
+                const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) { rep.insert_equal(f, l); }
+
+  hash_multimap(const_iterator f, const_iterator l)
+    : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
+  hash_multimap(const_iterator f, const_iterator l, size_type n)
+    : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
+  hash_multimap(const_iterator f, const_iterator l, size_type n,
+                const hasher& hf)
+    : rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
+  hash_multimap(const_iterator f, const_iterator l, size_type n,
+                const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) { rep.insert_equal(f, l); }
+#endif /*__STL_MEMBER_TEMPLATES */
+
+public:
+  size_type size() const { return rep.size(); }
+  size_type max_size() const { return rep.max_size(); }
+  bool empty() const { return rep.empty(); }
+  void swap(hash_multimap& hs) { rep.swap(hs.rep); }
+  friend bool
+  operator== __STL_NULL_TMPL_ARGS (const hash_multimap&, const hash_multimap&);
+
+  iterator begin() { return rep.begin(); }
+  iterator end() { return rep.end(); }
+  const_iterator begin() const { return rep.begin(); }
+  const_iterator end() const { return rep.end(); }
+
+public:
+  iterator insert(const value_type& obj) { return rep.insert_equal(obj); }
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); }
+#else
+  void insert(const value_type* f, const value_type* l) {
+    rep.insert_equal(f,l);
+  }
+  void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); }
+#endif /*__STL_MEMBER_TEMPLATES */
+  iterator insert_noresize(const value_type& obj)
+    { return rep.insert_equal_noresize(obj); }    
+
+  iterator find(const key_type& key) { return rep.find(key); }
+  const_iterator find(const key_type& key) const { return rep.find(key); }
+
+  size_type count(const key_type& key) const { return rep.count(key); }
+  
+  pair<iterator, iterator> equal_range(const key_type& key)
+    { return rep.equal_range(key); }
+  pair<const_iterator, const_iterator> equal_range(const key_type& key) const
+    { return rep.equal_range(key); }
+
+  size_type erase(const key_type& key) {return rep.erase(key); }
+  void erase(iterator it) { rep.erase(it); }
+  void erase(iterator f, iterator l) { rep.erase(f, l); }
+  void clear() { rep.clear(); }
+
+public:
+  void resize(size_type hint) { rep.resize(hint); }
+  size_type bucket_count() const { return rep.bucket_count(); }
+  size_type max_bucket_count() const { return rep.max_bucket_count(); }
+  size_type elems_in_bucket(size_type n) const
+    { return rep.elems_in_bucket(n); }
+};
+
+template <class Key, class T, class HF, class EqKey, class Alloc>
+inline bool operator==(const hash_multimap<Key, T, HF, EqKey, Alloc>& hm1,
+                       const hash_multimap<Key, T, HF, EqKey, Alloc>& hm2)
+{
+  return hm1.rep == hm2.rep;
+}
+
+#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
+
+template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
+inline void swap(hash_multimap<Key, T, HashFcn, EqualKey, Alloc>& hm1,
+                 hash_multimap<Key, T, HashFcn, EqualKey, Alloc>& hm2)
+{
+  hm1.swap(hm2);
+}
+
+#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1174
+#endif
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_HASH_MAP_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_hash_set.h b/libstdc++/stl/stl_hash_set.h
new file mode 100644 (file)
index 0000000..80159da
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_HASH_SET_H
+#define __SGI_STL_INTERNAL_HASH_SET_H
+
+__STL_BEGIN_NAMESPACE
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1174
+#endif
+
+#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
+template <class Value, class HashFcn = hash<Value>,
+          class EqualKey = equal_to<Value>,
+          class Alloc = alloc>
+#else
+template <class Value, class HashFcn, class EqualKey, class Alloc = alloc>
+#endif
+class hash_set
+{
+private:
+  typedef hashtable<Value, Value, HashFcn, identity<Value>, 
+                    EqualKey, Alloc> ht;
+  ht rep;
+
+public:
+  typedef typename ht::key_type key_type;
+  typedef typename ht::value_type value_type;
+  typedef typename ht::hasher hasher;
+  typedef typename ht::key_equal key_equal;
+
+  typedef typename ht::size_type size_type;
+  typedef typename ht::difference_type difference_type;
+  typedef typename ht::const_pointer pointer;
+  typedef typename ht::const_pointer const_pointer;
+  typedef typename ht::const_reference reference;
+  typedef typename ht::const_reference const_reference;
+
+  typedef typename ht::const_iterator iterator;
+  typedef typename ht::const_iterator const_iterator;
+
+  hasher hash_funct() const { return rep.hash_funct(); }
+  key_equal key_eq() const { return rep.key_eq(); }
+
+public:
+  hash_set() : rep(100, hasher(), key_equal()) {}
+  explicit hash_set(size_type n) : rep(n, hasher(), key_equal()) {}
+  hash_set(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
+  hash_set(size_type n, const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) {}
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  hash_set(InputIterator f, InputIterator l)
+    : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
+  template <class InputIterator>
+  hash_set(InputIterator f, InputIterator l, size_type n)
+    : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
+  template <class InputIterator>
+  hash_set(InputIterator f, InputIterator l, size_type n,
+           const hasher& hf)
+    : rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
+  template <class InputIterator>
+  hash_set(InputIterator f, InputIterator l, size_type n,
+           const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) { rep.insert_unique(f, l); }
+#else
+
+  hash_set(const value_type* f, const value_type* l)
+    : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
+  hash_set(const value_type* f, const value_type* l, size_type n)
+    : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
+  hash_set(const value_type* f, const value_type* l, size_type n,
+           const hasher& hf)
+    : rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
+  hash_set(const value_type* f, const value_type* l, size_type n,
+           const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) { rep.insert_unique(f, l); }
+
+  hash_set(const_iterator f, const_iterator l)
+    : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
+  hash_set(const_iterator f, const_iterator l, size_type n)
+    : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
+  hash_set(const_iterator f, const_iterator l, size_type n,
+           const hasher& hf)
+    : rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
+  hash_set(const_iterator f, const_iterator l, size_type n,
+           const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) { rep.insert_unique(f, l); }
+#endif /*__STL_MEMBER_TEMPLATES */
+
+public:
+  size_type size() const { return rep.size(); }
+  size_type max_size() const { return rep.max_size(); }
+  bool empty() const { return rep.empty(); }
+  void swap(hash_set& hs) { rep.swap(hs.rep); }
+  friend bool operator== __STL_NULL_TMPL_ARGS (const hash_set&,
+                                               const hash_set&);
+
+  iterator begin() const { return rep.begin(); }
+  iterator end() const { return rep.end(); }
+
+public:
+  pair<iterator, bool> insert(const value_type& obj)
+    {
+      pair<typename ht::iterator, bool> p = rep.insert_unique(obj);
+      return pair<iterator, bool>(p.first, p.second);
+    }
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); }
+#else
+  void insert(const value_type* f, const value_type* l) {
+    rep.insert_unique(f,l);
+  }
+  void insert(const_iterator f, const_iterator l) {rep.insert_unique(f, l); }
+#endif /*__STL_MEMBER_TEMPLATES */
+  pair<iterator, bool> insert_noresize(const value_type& obj)
+  {
+    pair<typename ht::iterator, bool> p = rep.insert_unique_noresize(obj);
+    return pair<iterator, bool>(p.first, p.second);
+  }
+
+  iterator find(const key_type& key) const { return rep.find(key); }
+
+  size_type count(const key_type& key) const { return rep.count(key); }
+  
+  pair<iterator, iterator> equal_range(const key_type& key) const
+    { return rep.equal_range(key); }
+
+  size_type erase(const key_type& key) {return rep.erase(key); }
+  void erase(iterator it) { rep.erase(it); }
+  void erase(iterator f, iterator l) { rep.erase(f, l); }
+  void clear() { rep.clear(); }
+
+public:
+  void resize(size_type hint) { rep.resize(hint); }
+  size_type bucket_count() const { return rep.bucket_count(); }
+  size_type max_bucket_count() const { return rep.max_bucket_count(); }
+  size_type elems_in_bucket(size_type n) const
+    { return rep.elems_in_bucket(n); }
+};
+
+template <class Value, class HashFcn, class EqualKey, class Alloc>
+inline bool operator==(const hash_set<Value, HashFcn, EqualKey, Alloc>& hs1,
+                       const hash_set<Value, HashFcn, EqualKey, Alloc>& hs2)
+{
+  return hs1.rep == hs2.rep;
+}
+
+#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
+
+template <class Val, class HashFcn, class EqualKey, class Alloc>
+inline void swap(hash_set<Val, HashFcn, EqualKey, Alloc>& hs1,
+                 hash_set<Val, HashFcn, EqualKey, Alloc>& hs2) {
+  hs1.swap(hs2);
+}
+
+#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
+
+
+#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
+template <class Value, class HashFcn = hash<Value>,
+          class EqualKey = equal_to<Value>,
+          class Alloc = alloc>
+#else
+template <class Value, class HashFcn, class EqualKey, class Alloc = alloc>
+#endif
+class hash_multiset
+{
+private:
+  typedef hashtable<Value, Value, HashFcn, identity<Value>, 
+                    EqualKey, Alloc> ht;
+  ht rep;
+
+public:
+  typedef typename ht::key_type key_type;
+  typedef typename ht::value_type value_type;
+  typedef typename ht::hasher hasher;
+  typedef typename ht::key_equal key_equal;
+
+  typedef typename ht::size_type size_type;
+  typedef typename ht::difference_type difference_type;
+  typedef typename ht::const_pointer pointer;
+  typedef typename ht::const_pointer const_pointer;
+  typedef typename ht::const_reference reference;
+  typedef typename ht::const_reference const_reference;
+
+  typedef typename ht::const_iterator iterator;
+  typedef typename ht::const_iterator const_iterator;
+
+  hasher hash_funct() const { return rep.hash_funct(); }
+  key_equal key_eq() const { return rep.key_eq(); }
+
+public:
+  hash_multiset() : rep(100, hasher(), key_equal()) {}
+  explicit hash_multiset(size_type n) : rep(n, hasher(), key_equal()) {}
+  hash_multiset(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
+  hash_multiset(size_type n, const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) {}
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  hash_multiset(InputIterator f, InputIterator l)
+    : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
+  template <class InputIterator>
+  hash_multiset(InputIterator f, InputIterator l, size_type n)
+    : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
+  template <class InputIterator>
+  hash_multiset(InputIterator f, InputIterator l, size_type n,
+                const hasher& hf)
+    : rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
+  template <class InputIterator>
+  hash_multiset(InputIterator f, InputIterator l, size_type n,
+                const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) { rep.insert_equal(f, l); }
+#else
+
+  hash_multiset(const value_type* f, const value_type* l)
+    : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
+  hash_multiset(const value_type* f, const value_type* l, size_type n)
+    : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
+  hash_multiset(const value_type* f, const value_type* l, size_type n,
+                const hasher& hf)
+    : rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
+  hash_multiset(const value_type* f, const value_type* l, size_type n,
+                const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) { rep.insert_equal(f, l); }
+
+  hash_multiset(const_iterator f, const_iterator l)
+    : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
+  hash_multiset(const_iterator f, const_iterator l, size_type n)
+    : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
+  hash_multiset(const_iterator f, const_iterator l, size_type n,
+                const hasher& hf)
+    : rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
+  hash_multiset(const_iterator f, const_iterator l, size_type n,
+                const hasher& hf, const key_equal& eql)
+    : rep(n, hf, eql) { rep.insert_equal(f, l); }
+#endif /*__STL_MEMBER_TEMPLATES */
+
+public:
+  size_type size() const { return rep.size(); }
+  size_type max_size() const { return rep.max_size(); }
+  bool empty() const { return rep.empty(); }
+  void swap(hash_multiset& hs) { rep.swap(hs.rep); }
+  friend bool operator== __STL_NULL_TMPL_ARGS (const hash_multiset&,
+                                               const hash_multiset&);
+
+  iterator begin() const { return rep.begin(); }
+  iterator end() const { return rep.end(); }
+
+public:
+  iterator insert(const value_type& obj) { return rep.insert_equal(obj); }
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); }
+#else
+  void insert(const value_type* f, const value_type* l) {
+    rep.insert_equal(f,l);
+  }
+  void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); }
+#endif /*__STL_MEMBER_TEMPLATES */
+  iterator insert_noresize(const value_type& obj)
+    { return rep.insert_equal_noresize(obj); }    
+
+  iterator find(const key_type& key) const { return rep.find(key); }
+
+  size_type count(const key_type& key) const { return rep.count(key); }
+  
+  pair<iterator, iterator> equal_range(const key_type& key) const
+    { return rep.equal_range(key); }
+
+  size_type erase(const key_type& key) {return rep.erase(key); }
+  void erase(iterator it) { rep.erase(it); }
+  void erase(iterator f, iterator l) { rep.erase(f, l); }
+  void clear() { rep.clear(); }
+
+public:
+  void resize(size_type hint) { rep.resize(hint); }
+  size_type bucket_count() const { return rep.bucket_count(); }
+  size_type max_bucket_count() const { return rep.max_bucket_count(); }
+  size_type elems_in_bucket(size_type n) const
+    { return rep.elems_in_bucket(n); }
+};
+
+template <class Val, class HashFcn, class EqualKey, class Alloc>
+inline bool operator==(const hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs1,
+                       const hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs2)
+{
+  return hs1.rep == hs2.rep;
+}
+
+#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
+
+template <class Val, class HashFcn, class EqualKey, class Alloc>
+inline void swap(hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs1,
+                 hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs2)
+  hs1.swap(hs2);
+}
+
+#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1174
+#endif
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_HASH_SET_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_hashtable.h b/libstdc++/stl/stl_hashtable.h
new file mode 100644 (file)
index 0000000..2452f62
--- /dev/null
@@ -0,0 +1,948 @@
+/*
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_HASHTABLE_H
+#define __SGI_STL_INTERNAL_HASHTABLE_H
+
+// Hashtable class, used to implement the hashed associative containers
+// hash_set, hash_map, hash_multiset, and hash_multimap.
+
+#include <stl_algobase.h>
+#include <stl_alloc.h>
+#include <stl_construct.h>
+#include <stl_tempbuf.h>
+#include <stl_algo.h>
+#include <stl_uninitialized.h>
+#include <stl_function.h>
+#include <stl_vector.h>
+#include <stl_hash_fun.h>
+
+__STL_BEGIN_NAMESPACE
+
+template <class Value>
+struct __hashtable_node
+{
+  __hashtable_node* next;
+  Value val;
+};  
+
+template <class Value, class Key, class HashFcn,
+          class ExtractKey, class EqualKey, class Alloc = alloc>
+class hashtable;
+
+template <class Value, class Key, class HashFcn,
+          class ExtractKey, class EqualKey, class Alloc>
+struct __hashtable_iterator;
+
+template <class Value, class Key, class HashFcn,
+          class ExtractKey, class EqualKey, class Alloc>
+struct __hashtable_const_iterator;
+
+template <class Value, class Key, class HashFcn,
+          class ExtractKey, class EqualKey, class Alloc>
+struct __hashtable_iterator {
+  typedef hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>
+          hashtable;
+  typedef __hashtable_iterator<Value, Key, HashFcn, 
+                               ExtractKey, EqualKey, Alloc>
+          iterator;
+  typedef __hashtable_const_iterator<Value, Key, HashFcn, 
+                                     ExtractKey, EqualKey, Alloc>
+          const_iterator;
+  typedef __hashtable_node<Value> node;
+
+  typedef forward_iterator_tag iterator_category;
+  typedef Value value_type;
+  typedef ptrdiff_t difference_type;
+  typedef size_t size_type;
+  typedef Value& reference;
+  typedef Value* pointer;
+
+  node* cur;
+  hashtable* ht;
+
+  __hashtable_iterator(node* n, hashtable* tab) : cur(n), ht(tab) {}
+  __hashtable_iterator() {}
+  reference operator*() const { return cur->val; }
+#ifndef __SGI_STL_NO_ARROW_OPERATOR
+  pointer operator->() const { return &(operator*()); }
+#endif /* __SGI_STL_NO_ARROW_OPERATOR */
+  iterator& operator++();
+  iterator operator++(int);
+  bool operator==(const iterator& it) const { return cur == it.cur; }
+  bool operator!=(const iterator& it) const { return cur != it.cur; }
+};
+
+
+template <class Value, class Key, class HashFcn,
+          class ExtractKey, class EqualKey, class Alloc>
+struct __hashtable_const_iterator {
+  typedef hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>
+          hashtable;
+  typedef __hashtable_iterator<Value, Key, HashFcn, 
+                               ExtractKey, EqualKey, Alloc>
+          iterator;
+  typedef __hashtable_const_iterator<Value, Key, HashFcn, 
+                                     ExtractKey, EqualKey, Alloc>
+          const_iterator;
+  typedef __hashtable_node<Value> node;
+
+  typedef forward_iterator_tag iterator_category;
+  typedef Value value_type;
+  typedef ptrdiff_t difference_type;
+  typedef size_t size_type;
+  typedef const Value& reference;
+  typedef const Value* pointer;
+
+  const node* cur;
+  const hashtable* ht;
+
+  __hashtable_const_iterator(const node* n, const hashtable* tab)
+    : cur(n), ht(tab) {}
+  __hashtable_const_iterator() {}
+  __hashtable_const_iterator(const iterator& it) : cur(it.cur), ht(it.ht) {}
+  reference operator*() const { return cur->val; }
+#ifndef __SGI_STL_NO_ARROW_OPERATOR
+  pointer operator->() const { return &(operator*()); }
+#endif /* __SGI_STL_NO_ARROW_OPERATOR */
+  const_iterator& operator++();
+  const_iterator operator++(int);
+  bool operator==(const const_iterator& it) const { return cur == it.cur; }
+  bool operator!=(const const_iterator& it) const { return cur != it.cur; }
+};
+
+// Note: assumes long is at least 32 bits.
+static const int __stl_num_primes = 28;
+static const unsigned long __stl_prime_list[__stl_num_primes] =
+{
+  53,         97,         193,       389,       769,
+  1543,       3079,       6151,      12289,     24593,
+  49157,      98317,      196613,    393241,    786433,
+  1572869,    3145739,    6291469,   12582917,  25165843,
+  50331653,   100663319,  201326611, 402653189, 805306457, 
+  1610612741, 3221225473, 4294967291
+};
+
+inline unsigned long __stl_next_prime(unsigned long n)
+{
+  const unsigned long* first = __stl_prime_list;
+  const unsigned long* last = __stl_prime_list + __stl_num_primes;
+  const unsigned long* pos = lower_bound(first, last, n);
+  return pos == last ? *(last - 1) : *pos;
+}
+
+
+template <class Value, class Key, class HashFcn,
+          class ExtractKey, class EqualKey,
+          class Alloc>
+class hashtable {
+public:
+  typedef Key key_type;
+  typedef Value value_type;
+  typedef HashFcn hasher;
+  typedef EqualKey key_equal;
+
+  typedef size_t            size_type;
+  typedef ptrdiff_t         difference_type;
+  typedef value_type*       pointer;
+  typedef const value_type* const_pointer;
+  typedef value_type&       reference;
+  typedef const value_type& const_reference;
+
+  hasher hash_funct() const { return hash; }
+  key_equal key_eq() const { return equals; }
+
+private:
+  hasher hash;
+  key_equal equals;
+  ExtractKey get_key;
+
+  typedef __hashtable_node<Value> node;
+  typedef simple_alloc<node, Alloc> node_allocator;
+
+  vector<node*,Alloc> buckets;
+  size_type num_elements;
+
+public:
+  typedef __hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, 
+                               Alloc>
+  iterator;
+
+  typedef __hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey,
+                                     Alloc>
+  const_iterator;
+
+  friend struct
+  __hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>;
+  friend struct
+  __hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>;
+
+public:
+  hashtable(size_type n,
+            const HashFcn&    hf,
+            const EqualKey&   eql,
+            const ExtractKey& ext)
+    : hash(hf), equals(eql), get_key(ext), num_elements(0)
+  {
+    initialize_buckets(n);
+  }
+
+  hashtable(size_type n,
+            const HashFcn&    hf,
+            const EqualKey&   eql)
+    : hash(hf), equals(eql), get_key(ExtractKey()), num_elements(0)
+  {
+    initialize_buckets(n);
+  }
+
+  hashtable(const hashtable& ht)
+    : hash(ht.hash), equals(ht.equals), get_key(ht.get_key), num_elements(0)
+  {
+    copy_from(ht);
+  }
+
+  hashtable& operator= (const hashtable& ht)
+  {
+    if (&ht != this) {
+      clear();
+      hash = ht.hash;
+      equals = ht.equals;
+      get_key = ht.get_key;
+      copy_from(ht);
+    }
+    return *this;
+  }
+
+  ~hashtable() { clear(); }
+
+  size_type size() const { return num_elements; }
+  size_type max_size() const { return size_type(-1); }
+  bool empty() const { return size() == 0; }
+
+  void swap(hashtable& ht)
+  {
+    __STD::swap(hash, ht.hash);
+    __STD::swap(equals, ht.equals);
+    __STD::swap(get_key, ht.get_key);
+    buckets.swap(ht.buckets);
+    __STD::swap(num_elements, ht.num_elements);
+  }
+
+  iterator begin()
+  { 
+    for (size_type n = 0; n < buckets.size(); ++n)
+      if (buckets[n])
+        return iterator(buckets[n], this);
+    return end();
+  }
+
+  iterator end() { return iterator(0, this); }
+
+  const_iterator begin() const
+  {
+    for (size_type n = 0; n < buckets.size(); ++n)
+      if (buckets[n])
+        return const_iterator(buckets[n], this);
+    return end();
+  }
+
+  const_iterator end() const { return const_iterator(0, this); }
+
+  friend bool
+  operator== __STL_NULL_TMPL_ARGS (const hashtable&, const hashtable&);
+
+public:
+
+  size_type bucket_count() const { return buckets.size(); }
+
+  size_type max_bucket_count() const
+    { return __stl_prime_list[__stl_num_primes - 1]; } 
+
+  size_type elems_in_bucket(size_type bucket) const
+  {
+    size_type result = 0;
+    for (node* cur = buckets[bucket]; cur; cur = cur->next)
+      result += 1;
+    return result;
+  }
+
+  pair<iterator, bool> insert_unique(const value_type& obj)
+  {
+    resize(num_elements + 1);
+    return insert_unique_noresize(obj);
+  }
+
+  iterator insert_equal(const value_type& obj)
+  {
+    resize(num_elements + 1);
+    return insert_equal_noresize(obj);
+  }
+
+  pair<iterator, bool> insert_unique_noresize(const value_type& obj);
+  iterator insert_equal_noresize(const value_type& obj);
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  void insert_unique(InputIterator f, InputIterator l)
+  {
+    insert_unique(f, l, iterator_category(f));
+  }
+
+  template <class InputIterator>
+  void insert_equal(InputIterator f, InputIterator l)
+  {
+    insert_equal(f, l, iterator_category(f));
+  }
+
+  template <class InputIterator>
+  void insert_unique(InputIterator f, InputIterator l,
+                     input_iterator_tag)
+  {
+    for ( ; f != l; ++f)
+      insert_unique(*f);
+  }
+
+  template <class InputIterator>
+  void insert_equal(InputIterator f, InputIterator l,
+                    input_iterator_tag)
+  {
+    for ( ; f != l; ++f)
+      insert_equal(*f);
+  }
+
+  template <class ForwardIterator>
+  void insert_unique(ForwardIterator f, ForwardIterator l,
+                     forward_iterator_tag)
+  {
+    size_type n = 0;
+    distance(f, l, n);
+    resize(num_elements + n);
+    for ( ; n > 0; --n, ++f)
+      insert_unique_noresize(*f);
+  }
+
+  template <class ForwardIterator>
+  void insert_equal(ForwardIterator f, ForwardIterator l,
+                    forward_iterator_tag)
+  {
+    size_type n = 0;
+    distance(f, l, n);
+    resize(num_elements + n);
+    for ( ; n > 0; --n, ++f)
+      insert_equal_noresize(*f);
+  }
+
+#else /* __STL_MEMBER_TEMPLATES */
+  void insert_unique(const value_type* f, const value_type* l)
+  {
+    size_type n = l - f;
+    resize(num_elements + n);
+    for ( ; n > 0; --n, ++f)
+      insert_unique_noresize(*f);
+  }
+
+  void insert_equal(const value_type* f, const value_type* l)
+  {
+    size_type n = l - f;
+    resize(num_elements + n);
+    for ( ; n > 0; --n, ++f)
+      insert_equal_noresize(*f);
+  }
+
+  void insert_unique(const_iterator f, const_iterator l)
+  {
+    size_type n = 0;
+    distance(f, l, n);
+    resize(num_elements + n);
+    for ( ; n > 0; --n, ++f)
+      insert_unique_noresize(*f);
+  }
+
+  void insert_equal(const_iterator f, const_iterator l)
+  {
+    size_type n = 0;
+    distance(f, l, n);
+    resize(num_elements + n);
+    for ( ; n > 0; --n, ++f)
+      insert_equal_noresize(*f);
+  }
+#endif /*__STL_MEMBER_TEMPLATES */
+
+  reference find_or_insert(const value_type& obj);
+
+  iterator find(const key_type& key) 
+  {
+    size_type n = bkt_num_key(key);
+    node* first;
+    for ( first = buckets[n];
+          first && !equals(get_key(first->val), key);
+          first = first->next)
+      {}
+    return iterator(first, this);
+  } 
+
+  const_iterator find(const key_type& key) const
+  {
+    size_type n = bkt_num_key(key);
+    const node* first;
+    for ( first = buckets[n];
+          first && !equals(get_key(first->val), key);
+          first = first->next)
+      {}
+    return const_iterator(first, this);
+  } 
+
+  size_type count(const key_type& key) const
+  {
+    const size_type n = bkt_num_key(key);
+    size_type result = 0;
+
+    for (const node* cur = buckets[n]; cur; cur = cur->next)
+      if (equals(get_key(cur->val), key))
+        ++result;
+    return result;
+  }
+
+  pair<iterator, iterator> equal_range(const key_type& key);
+  pair<const_iterator, const_iterator> equal_range(const key_type& key) const;
+
+  size_type erase(const key_type& key);
+  void erase(const iterator& it);
+  void erase(iterator first, iterator last);
+
+  void erase(const const_iterator& it);
+  void erase(const_iterator first, const_iterator last);
+
+  void resize(size_type num_elements_hint);
+  void clear();
+
+private:
+  size_type next_size(size_type n) const { return __stl_next_prime(n); }
+
+  void initialize_buckets(size_type n)
+  {
+    const size_type n_buckets = next_size(n);
+    buckets.reserve(n_buckets);
+    buckets.insert(buckets.end(), n_buckets, (node*) 0);
+    num_elements = 0;
+  }
+
+  size_type bkt_num_key(const key_type& key) const
+  {
+    return bkt_num_key(key, buckets.size());
+  }
+
+  size_type bkt_num(const value_type& obj) const
+  {
+    return bkt_num_key(get_key(obj));
+  }
+
+  size_type bkt_num_key(const key_type& key, size_t n) const
+  {
+    return hash(key) % n;
+  }
+
+  size_type bkt_num(const value_type& obj, size_t n) const
+  {
+    return bkt_num_key(get_key(obj), n);
+  }
+
+  node* new_node(const value_type& obj)
+  {
+    node* n = node_allocator::allocate();
+    n->next = 0;
+    __STL_TRY {
+      construct(&n->val, obj);
+      return n;
+    }
+    __STL_UNWIND(node_allocator::deallocate(n));
+  }
+  
+  void delete_node(node* n)
+  {
+    destroy(&n->val);
+    node_allocator::deallocate(n);
+  }
+
+  void erase_bucket(const size_type n, node* first, node* last);
+  void erase_bucket(const size_type n, node* last);
+
+  void copy_from(const hashtable& ht);
+
+};
+
+template <class V, class K, class HF, class ExK, class EqK, class A>
+__hashtable_iterator<V, K, HF, ExK, EqK, A>&
+__hashtable_iterator<V, K, HF, ExK, EqK, A>::operator++()
+{
+  const node* old = cur;
+  cur = cur->next;
+  if (!cur) {
+    size_type bucket = ht->bkt_num(old->val);
+    while (!cur && ++bucket < ht->buckets.size())
+      cur = ht->buckets[bucket];
+  }
+  return *this;
+}
+
+template <class V, class K, class HF, class ExK, class EqK, class A>
+inline __hashtable_iterator<V, K, HF, ExK, EqK, A>
+__hashtable_iterator<V, K, HF, ExK, EqK, A>::operator++(int)
+{
+  iterator tmp = *this;
+  ++*this;
+  return tmp;
+}
+
+template <class V, class K, class HF, class ExK, class EqK, class A>
+__hashtable_const_iterator<V, K, HF, ExK, EqK, A>&
+__hashtable_const_iterator<V, K, HF, ExK, EqK, A>::operator++()
+{
+  const node* old = cur;
+  cur = cur->next;
+  if (!cur) {
+    size_type bucket = ht->bkt_num(old->val);
+    while (!cur && ++bucket < ht->buckets.size())
+      cur = ht->buckets[bucket];
+  }
+  return *this;
+}
+
+template <class V, class K, class HF, class ExK, class EqK, class A>
+inline __hashtable_const_iterator<V, K, HF, ExK, EqK, A>
+__hashtable_const_iterator<V, K, HF, ExK, EqK, A>::operator++(int)
+{
+  const_iterator tmp = *this;
+  ++*this;
+  return tmp;
+}
+
+#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+template <class V, class K, class HF, class ExK, class EqK, class All>
+inline forward_iterator_tag
+iterator_category(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&)
+{
+  return forward_iterator_tag();
+}
+
+template <class V, class K, class HF, class ExK, class EqK, class All>
+inline V* value_type(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&)
+{
+  return (V*) 0;
+}
+
+template <class V, class K, class HF, class ExK, class EqK, class All>
+inline hashtable<V, K, HF, ExK, EqK, All>::difference_type*
+distance_type(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&)
+{
+  return (hashtable<V, K, HF, ExK, EqK, All>::difference_type*) 0;
+}
+
+template <class V, class K, class HF, class ExK, class EqK, class All>
+inline forward_iterator_tag
+iterator_category(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&)
+{
+  return forward_iterator_tag();
+}
+
+template <class V, class K, class HF, class ExK, class EqK, class All>
+inline V* 
+value_type(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&)
+{
+  return (V*) 0;
+}
+
+template <class V, class K, class HF, class ExK, class EqK, class All>
+inline hashtable<V, K, HF, ExK, EqK, All>::difference_type*
+distance_type(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&)
+{
+  return (hashtable<V, K, HF, ExK, EqK, All>::difference_type*) 0;
+}
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+template <class V, class K, class HF, class Ex, class Eq, class A>
+bool operator==(const hashtable<V, K, HF, Ex, Eq, A>& ht1,
+                const hashtable<V, K, HF, Ex, Eq, A>& ht2)
+{
+  typedef typename hashtable<V, K, HF, Ex, Eq, A>::node node;
+  if (ht1.buckets.size() != ht2.buckets.size())
+    return false;
+  for (int n = 0; n < ht1.buckets.size(); ++n) {
+    node* cur1 = ht1.buckets[n];
+    node* cur2 = ht2.buckets[n];
+    for ( ; cur1 && cur2 && cur1->val == cur2->val;
+          cur1 = cur1->next, cur2 = cur2->next)
+      {}
+    if (cur1 || cur2)
+      return false;
+  }
+  return true;
+}  
+
+#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
+
+template <class Val, class Key, class HF, class Extract, class EqKey, class A>
+inline void swap(hashtable<Val, Key, HF, Extract, EqKey, A>& ht1,
+                 hashtable<Val, Key, HF, Extract, EqKay, A>& ht2) {
+  ht1.swap(ht2);
+}
+
+#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
+
+
+template <class V, class K, class HF, class Ex, class Eq, class A>
+pair<typename hashtable<V, K, HF, Ex, Eq, A>::iterator, bool> 
+hashtable<V, K, HF, Ex, Eq, A>::insert_unique_noresize(const value_type& obj)
+{
+  const size_type n = bkt_num(obj);
+  node* first = buckets[n];
+
+  for (node* cur = first; cur; cur = cur->next) 
+    if (equals(get_key(cur->val), get_key(obj)))
+      return pair<iterator, bool>(iterator(cur, this), false);
+
+  node* tmp = new_node(obj);
+  tmp->next = first;
+  buckets[n] = tmp;
+  ++num_elements;
+  return pair<iterator, bool>(iterator(tmp, this), true);
+}
+
+template <class V, class K, class HF, class Ex, class Eq, class A>
+typename hashtable<V, K, HF, Ex, Eq, A>::iterator 
+hashtable<V, K, HF, Ex, Eq, A>::insert_equal_noresize(const value_type& obj)
+{
+  const size_type n = bkt_num(obj);
+  node* first = buckets[n];
+
+  for (node* cur = first; cur; cur = cur->next) 
+    if (equals(get_key(cur->val), get_key(obj))) {
+      node* tmp = new_node(obj);
+      tmp->next = cur->next;
+      cur->next = tmp;
+      ++num_elements;
+      return iterator(tmp, this);
+    }
+
+  node* tmp = new_node(obj);
+  tmp->next = first;
+  buckets[n] = tmp;
+  ++num_elements;
+  return iterator(tmp, this);
+}
+
+template <class V, class K, class HF, class Ex, class Eq, class A>
+typename hashtable<V, K, HF, Ex, Eq, A>::reference 
+hashtable<V, K, HF, Ex, Eq, A>::find_or_insert(const value_type& obj)
+{
+  resize(num_elements + 1);
+
+  size_type n = bkt_num(obj);
+  node* first = buckets[n];
+
+  for (node* cur = first; cur; cur = cur->next)
+    if (equals(get_key(cur->val), get_key(obj)))
+      return cur->val;
+
+  node* tmp = new_node(obj);
+  tmp->next = first;
+  buckets[n] = tmp;
+  ++num_elements;
+  return tmp->val;
+}
+
+template <class V, class K, class HF, class Ex, class Eq, class A>
+pair<typename hashtable<V, K, HF, Ex, Eq, A>::iterator,
+     typename hashtable<V, K, HF, Ex, Eq, A>::iterator> 
+hashtable<V, K, HF, Ex, Eq, A>::equal_range(const key_type& key)
+{
+  typedef pair<iterator, iterator> pii;
+  const size_type n = bkt_num_key(key);
+
+  for (node* first = buckets[n]; first; first = first->next) {
+    if (equals(get_key(first->val), key)) {
+      for (node* cur = first->next; cur; cur = cur->next)
+        if (!equals(get_key(cur->val), key))
+          return pii(iterator(first, this), iterator(cur, this));
+      for (size_type m = n + 1; m < buckets.size(); ++m)
+        if (buckets[m])
+          return pii(iterator(first, this),
+                     iterator(buckets[m], this));
+      return pii(iterator(first, this), end());
+    }
+  }
+  return pii(end(), end());
+}
+
+template <class V, class K, class HF, class Ex, class Eq, class A>
+pair<typename hashtable<V, K, HF, Ex, Eq, A>::const_iterator, 
+     typename hashtable<V, K, HF, Ex, Eq, A>::const_iterator> 
+hashtable<V, K, HF, Ex, Eq, A>::equal_range(const key_type& key) const
+{
+  typedef pair<const_iterator, const_iterator> pii;
+  const size_type n = bkt_num_key(key);
+
+  for (const node* first = buckets[n] ; first; first = first->next) {
+    if (equals(get_key(first->val), key)) {
+      for (const node* cur = first->next; cur; cur = cur->next)
+        if (!equals(get_key(cur->val), key))
+          return pii(const_iterator(first, this),
+                     const_iterator(cur, this));
+      for (size_type m = n + 1; m < buckets.size(); ++m)
+        if (buckets[m])
+          return pii(const_iterator(first, this),
+                     const_iterator(buckets[m], this));
+      return pii(const_iterator(first, this), end());
+    }
+  }
+  return pii(end(), end());
+}
+
+template <class V, class K, class HF, class Ex, class Eq, class A>
+typename hashtable<V, K, HF, Ex, Eq, A>::size_type 
+hashtable<V, K, HF, Ex, Eq, A>::erase(const key_type& key)
+{
+  const size_type n = bkt_num_key(key);
+  node* first = buckets[n];
+  size_type erased = 0;
+
+  if (first) {
+    node* cur = first;
+    node* next = cur->next;
+    while (next) {
+      if (equals(get_key(next->val), key)) {
+        cur->next = next->next;
+        delete_node(next);
+        next = cur->next;
+        ++erased;
+        --num_elements;
+      }
+      else {
+        cur = next;
+        next = cur->next;
+      }
+    }
+    if (equals(get_key(first->val), key)) {
+      buckets[n] = first->next;
+      delete_node(first);
+      ++erased;
+      --num_elements;
+    }
+  }
+  return erased;
+}
+
+template <class V, class K, class HF, class Ex, class Eq, class A>
+void hashtable<V, K, HF, Ex, Eq, A>::erase(const iterator& it)
+{
+  if (node* const p = it.cur) {
+    const size_type n = bkt_num(p->val);
+    node* cur = buckets[n];
+
+    if (cur == p) {
+      buckets[n] = cur->next;
+      delete_node(cur);
+      --num_elements;
+    }
+    else {
+      node* next = cur->next;
+      while (next) {
+        if (next == p) {
+          cur->next = next->next;
+          delete_node(next);
+          --num_elements;
+          break;
+        }
+        else {
+          cur = next;
+          next = cur->next;
+        }
+      }
+    }
+  }
+}
+
+template <class V, class K, class HF, class Ex, class Eq, class A>
+void hashtable<V, K, HF, Ex, Eq, A>::erase(iterator first, iterator last)
+{
+  size_type f_bucket = first.cur ? bkt_num(first.cur->val) : buckets.size();
+  size_type l_bucket = last.cur ? bkt_num(last.cur->val) : buckets.size();
+
+  if (first.cur == last.cur)
+    return;
+  else if (f_bucket == l_bucket)
+    erase_bucket(f_bucket, first.cur, last.cur);
+  else {
+    erase_bucket(f_bucket, first.cur, 0);
+    for (size_type n = f_bucket + 1; n < l_bucket; ++n)
+      erase_bucket(n, 0);
+    if (l_bucket != buckets.size())
+      erase_bucket(l_bucket, last.cur);
+  }
+}
+
+template <class V, class K, class HF, class Ex, class Eq, class A>
+inline void
+hashtable<V, K, HF, Ex, Eq, A>::erase(const_iterator first,
+                                      const_iterator last)
+{
+  erase(iterator(const_cast<node*>(first.cur),
+                 const_cast<hashtable*>(first.ht)),
+        iterator(const_cast<node*>(last.cur),
+                 const_cast<hashtable*>(last.ht)));
+}
+
+template <class V, class K, class HF, class Ex, class Eq, class A>
+inline void
+hashtable<V, K, HF, Ex, Eq, A>::erase(const const_iterator& it)
+{
+  erase(iterator(const_cast<node*>(it.cur),
+                 const_cast<hashtable*>(it.ht)));
+}
+
+template <class V, class K, class HF, class Ex, class Eq, class A>
+void hashtable<V, K, HF, Ex, Eq, A>::resize(size_type num_elements_hint)
+{
+  const size_type old_n = buckets.size();
+  if (num_elements_hint > old_n) {
+    const size_type n = next_size(num_elements_hint);
+    if (n > old_n) {
+      vector<node*, A> tmp(n, (node*) 0);
+      __STL_TRY {
+        for (size_type bucket = 0; bucket < old_n; ++bucket) {
+          node* first = buckets[bucket];
+          while (first) {
+            size_type new_bucket = bkt_num(first->val, n);
+            buckets[bucket] = first->next;
+            first->next = tmp[new_bucket];
+            tmp[new_bucket] = first;
+            first = buckets[bucket];          
+          }
+        }
+        buckets.swap(tmp);
+      }
+#         ifdef __STL_USE_EXCEPTIONS
+      catch(...) {
+        for (size_type bucket = 0; bucket < tmp.size(); ++bucket) {
+          while (tmp[bucket]) {
+            node* next = tmp[bucket]->next;
+            delete_node(tmp[bucket]);
+            tmp[bucket] = next;
+          }
+        }
+        throw;
+      }
+#         endif /* __STL_USE_EXCEPTIONS */
+    }
+  }
+}
+
+template <class V, class K, class HF, class Ex, class Eq, class A>
+void hashtable<V, K, HF, Ex, Eq, A>::erase_bucket(const size_type n, 
+                                                  node* first, node* last)
+{
+  node* cur = buckets[n];
+  if (cur == first)
+    erase_bucket(n, last);
+  else {
+    node* next;
+    for (next = cur->next; next != first; cur = next, next = cur->next)
+      ;
+    while (next) {
+      cur->next = next->next;
+      delete_node(next);
+      next = cur->next;
+      --num_elements;
+    }
+  }
+}
+
+template <class V, class K, class HF, class Ex, class Eq, class A>
+void 
+hashtable<V, K, HF, Ex, Eq, A>::erase_bucket(const size_type n, node* last)
+{
+  node* cur = buckets[n];
+  while (cur != last) {
+    node* next = cur->next;
+    delete_node(cur);
+    cur = next;
+    buckets[n] = cur;
+    --num_elements;
+  }
+}
+
+template <class V, class K, class HF, class Ex, class Eq, class A>
+void hashtable<V, K, HF, Ex, Eq, A>::clear()
+{
+  for (size_type i = 0; i < buckets.size(); ++i) {
+    node* cur = buckets[i];
+    while (cur != 0) {
+      node* next = cur->next;
+      delete_node(cur);
+      cur = next;
+    }
+    buckets[i] = 0;
+  }
+  num_elements = 0;
+}
+
+    
+template <class V, class K, class HF, class Ex, class Eq, class A>
+void hashtable<V, K, HF, Ex, Eq, A>::copy_from(const hashtable& ht)
+{
+  buckets.clear();
+  buckets.reserve(ht.buckets.size());
+  buckets.insert(buckets.end(), ht.buckets.size(), (node*) 0);
+  __STL_TRY {
+    for (size_type i = 0; i < ht.buckets.size(); ++i) {
+      if (const node* cur = ht.buckets[i]) {
+        node* copy = new_node(cur->val);
+        buckets[i] = copy;
+
+        for (node* next = cur->next; next; cur = next, next = cur->next) {
+          copy->next = new_node(next->val);
+          copy = copy->next;
+        }
+      }
+    }
+    num_elements = ht.num_elements;
+  }
+  __STL_UNWIND(clear());
+}
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_HASHTABLE_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_heap.h b/libstdc++/stl/stl_heap.h
new file mode 100644 (file)
index 0000000..3fe24f8
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * Copyright (c) 1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_HEAP_H
+#define __SGI_STL_INTERNAL_HEAP_H
+
+__STL_BEGIN_NAMESPACE
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1209
+#endif
+
+template <class RandomAccessIterator, class Distance, class T>
+void __push_heap(RandomAccessIterator first, Distance holeIndex,
+                 Distance topIndex, T value) {
+  Distance parent = (holeIndex - 1) / 2;
+  while (holeIndex > topIndex && *(first + parent) < value) {
+    *(first + holeIndex) = *(first + parent);
+    holeIndex = parent;
+    parent = (holeIndex - 1) / 2;
+  }    
+  *(first + holeIndex) = value;
+}
+
+template <class RandomAccessIterator, class Distance, class T>
+inline void __push_heap_aux(RandomAccessIterator first,
+                            RandomAccessIterator last, Distance*, T*) {
+  __push_heap(first, Distance((last - first) - 1), Distance(0), 
+              T(*(last - 1)));
+}
+
+template <class RandomAccessIterator>
+inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) {
+  __push_heap_aux(first, last, distance_type(first), value_type(first));
+}
+
+template <class RandomAccessIterator, class Distance, class T, class Compare>
+void __push_heap(RandomAccessIterator first, Distance holeIndex,
+                 Distance topIndex, T value, Compare comp) {
+  Distance parent = (holeIndex - 1) / 2;
+  while (holeIndex > topIndex && comp(*(first + parent), value)) {
+    *(first + holeIndex) = *(first + parent);
+    holeIndex = parent;
+    parent = (holeIndex - 1) / 2;
+  }
+  *(first + holeIndex) = value;
+}
+
+template <class RandomAccessIterator, class Compare, class Distance, class T>
+inline void __push_heap_aux(RandomAccessIterator first,
+                            RandomAccessIterator last, Compare comp,
+                            Distance*, T*) {
+  __push_heap(first, Distance((last - first) - 1), Distance(0), 
+              T(*(last - 1)), comp);
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void push_heap(RandomAccessIterator first, RandomAccessIterator last,
+                      Compare comp) {
+  __push_heap_aux(first, last, comp, distance_type(first), value_type(first));
+}
+
+template <class RandomAccessIterator, class Distance, class T>
+void __adjust_heap(RandomAccessIterator first, Distance holeIndex,
+                   Distance len, T value) {
+  Distance topIndex = holeIndex;
+  Distance secondChild = 2 * holeIndex + 2;
+  while (secondChild < len) {
+    if (*(first + secondChild) < *(first + (secondChild - 1)))
+      secondChild--;
+    *(first + holeIndex) = *(first + secondChild);
+    holeIndex = secondChild;
+    secondChild = 2 * (secondChild + 1);
+  }
+  if (secondChild == len) {
+    *(first + holeIndex) = *(first + (secondChild - 1));
+    holeIndex = secondChild - 1;
+  }
+  __push_heap(first, holeIndex, topIndex, value);
+}
+
+template <class RandomAccessIterator, class T, class Distance>
+inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last,
+                       RandomAccessIterator result, T value, Distance*) {
+  *result = *first;
+  __adjust_heap(first, Distance(0), Distance(last - first), value);
+}
+
+template <class RandomAccessIterator, class T>
+inline void __pop_heap_aux(RandomAccessIterator first,
+                           RandomAccessIterator last, T*) {
+  __pop_heap(first, last - 1, last - 1, T(*(last - 1)), distance_type(first));
+}
+
+template <class RandomAccessIterator>
+inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last) {
+  __pop_heap_aux(first, last, value_type(first));
+}
+
+template <class RandomAccessIterator, class Distance, class T, class Compare>
+void __adjust_heap(RandomAccessIterator first, Distance holeIndex,
+                   Distance len, T value, Compare comp) {
+  Distance topIndex = holeIndex;
+  Distance secondChild = 2 * holeIndex + 2;
+  while (secondChild < len) {
+    if (comp(*(first + secondChild), *(first + (secondChild - 1))))
+      secondChild--;
+    *(first + holeIndex) = *(first + secondChild);
+    holeIndex = secondChild;
+    secondChild = 2 * (secondChild + 1);
+  }
+  if (secondChild == len) {
+    *(first + holeIndex) = *(first + (secondChild - 1));
+    holeIndex = secondChild - 1;
+  }
+  __push_heap(first, holeIndex, topIndex, value, comp);
+}
+
+template <class RandomAccessIterator, class T, class Compare, class Distance>
+inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last,
+                       RandomAccessIterator result, T value, Compare comp,
+                       Distance*) {
+  *result = *first;
+  __adjust_heap(first, Distance(0), Distance(last - first), value, comp);
+}
+
+template <class RandomAccessIterator, class T, class Compare>
+inline void __pop_heap_aux(RandomAccessIterator first,
+                           RandomAccessIterator last, T*, Compare comp) {
+  __pop_heap(first, last - 1, last - 1, T(*(last - 1)), comp,
+             distance_type(first));
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last,
+                     Compare comp) {
+    __pop_heap_aux(first, last, value_type(first), comp);
+}
+
+template <class RandomAccessIterator, class T, class Distance>
+void __make_heap(RandomAccessIterator first, RandomAccessIterator last, T*,
+                 Distance*) {
+  if (last - first < 2) return;
+  Distance len = last - first;
+  Distance parent = (len - 2)/2;
+    
+  while (true) {
+    __adjust_heap(first, parent, len, T(*(first + parent)));
+    if (parent == 0) return;
+    parent--;
+  }
+}
+
+template <class RandomAccessIterator>
+inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) {
+  __make_heap(first, last, value_type(first), distance_type(first));
+}
+
+template <class RandomAccessIterator, class Compare, class T, class Distance>
+void __make_heap(RandomAccessIterator first, RandomAccessIterator last,
+                 Compare comp, T*, Distance*) {
+  if (last - first < 2) return;
+  Distance len = last - first;
+  Distance parent = (len - 2)/2;
+    
+  while (true) {
+    __adjust_heap(first, parent, len, T(*(first + parent)), comp);
+    if (parent == 0) return;
+    parent--;
+  }
+}
+
+template <class RandomAccessIterator, class Compare>
+inline void make_heap(RandomAccessIterator first, RandomAccessIterator last,
+                      Compare comp) {
+  __make_heap(first, last, comp, value_type(first), distance_type(first));
+}
+
+template <class RandomAccessIterator>
+void sort_heap(RandomAccessIterator first, RandomAccessIterator last) {
+  while (last - first > 1) pop_heap(first, last--);
+}
+
+template <class RandomAccessIterator, class Compare>
+void sort_heap(RandomAccessIterator first, RandomAccessIterator last,
+               Compare comp) {
+  while (last - first > 1) pop_heap(first, last--, comp);
+}
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1209
+#endif
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_HEAP_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_iterator.h b/libstdc++/stl/stl_iterator.h
new file mode 100644 (file)
index 0000000..892db3e
--- /dev/null
@@ -0,0 +1,843 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_ITERATOR_H
+#define __SGI_STL_INTERNAL_ITERATOR_H
+
+__STL_BEGIN_NAMESPACE
+
+struct input_iterator_tag {};
+struct output_iterator_tag {};
+struct forward_iterator_tag : public input_iterator_tag {};
+struct bidirectional_iterator_tag : public forward_iterator_tag {};
+struct random_access_iterator_tag : public bidirectional_iterator_tag {};
+
+template <class T, class Distance> struct input_iterator {
+  typedef input_iterator_tag iterator_category;
+  typedef T                  value_type;
+  typedef Distance           difference_type;
+  typedef T*                 pointer;
+  typedef T&                 reference;
+};
+
+struct output_iterator {
+  typedef output_iterator_tag iterator_category;
+  typedef void                value_type;
+  typedef void                difference_type;
+  typedef void                pointer;
+  typedef void                reference;
+};
+
+template <class T, class Distance> struct forward_iterator {
+  typedef forward_iterator_tag iterator_category;
+  typedef T                    value_type;
+  typedef Distance             difference_type;
+  typedef T*                   pointer;
+  typedef T&                   reference;
+};
+
+
+template <class T, class Distance> struct bidirectional_iterator {
+  typedef bidirectional_iterator_tag iterator_category;
+  typedef T                          value_type;
+  typedef Distance                   difference_type;
+  typedef T*                         pointer;
+  typedef T&                         reference;
+};
+
+template <class T, class Distance> struct random_access_iterator {
+  typedef random_access_iterator_tag iterator_category;
+  typedef T                          value_type;
+  typedef Distance                   difference_type;
+  typedef T*                         pointer;
+  typedef T&                         reference;
+};
+
+#ifdef __STL_USE_NAMESPACES
+template <class Category, class T, class Distance = ptrdiff_t,
+          class Pointer = T*, class Reference = T&>
+struct iterator {
+  typedef Category  iterator_category;
+  typedef T         value_type;
+  typedef Distance  difference_type;
+  typedef Pointer   pointer;
+  typedef Reference reference;
+};
+#endif /* __STL_USE_NAMESPACES */
+
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+template <class Iterator>
+struct iterator_traits {
+  typedef typename Iterator::iterator_category iterator_category;
+  typedef typename Iterator::value_type        value_type;
+  typedef typename Iterator::difference_type   difference_type;
+  typedef typename Iterator::pointer           pointer;
+  typedef typename Iterator::reference         reference;
+};
+
+template <class T>
+struct iterator_traits<T*> {
+  typedef random_access_iterator_tag iterator_category;
+  typedef T                          value_type;
+  typedef ptrdiff_t                  difference_type;
+  typedef T*                         pointer;
+  typedef T&                         reference;
+};
+
+template <class T>
+struct iterator_traits<const T*> {
+  typedef random_access_iterator_tag iterator_category;
+  typedef T                          value_type;
+  typedef ptrdiff_t                  difference_type;
+  typedef const T*                   pointer;
+  typedef const T&                   reference;
+};
+
+template <class Iterator>
+inline typename iterator_traits<Iterator>::iterator_category
+iterator_category(const Iterator&) {
+  typedef typename iterator_traits<Iterator>::iterator_category category;
+  return category();
+}
+
+template <class Iterator>
+inline typename iterator_traits<Iterator>::difference_type*
+distance_type(const Iterator&) {
+  return static_cast<typename iterator_traits<Iterator>::difference_type*>(0);
+}
+
+template <class Iterator>
+inline typename iterator_traits<Iterator>::value_type*
+value_type(const Iterator&) {
+  return static_cast<typename iterator_traits<Iterator>::value_type*>(0);
+}
+
+#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+template <class T, class Distance> 
+inline input_iterator_tag 
+iterator_category(const input_iterator<T, Distance>&) {
+  return input_iterator_tag();
+}
+
+inline output_iterator_tag iterator_category(const output_iterator&) {
+  return output_iterator_tag();
+}
+
+template <class T, class Distance> 
+inline forward_iterator_tag
+iterator_category(const forward_iterator<T, Distance>&) {
+  return forward_iterator_tag();
+}
+
+template <class T, class Distance> 
+inline bidirectional_iterator_tag
+iterator_category(const bidirectional_iterator<T, Distance>&) {
+  return bidirectional_iterator_tag();
+}
+
+template <class T, class Distance> 
+inline random_access_iterator_tag
+iterator_category(const random_access_iterator<T, Distance>&) {
+  return random_access_iterator_tag();
+}
+
+template <class T>
+inline random_access_iterator_tag iterator_category(const T*) {
+  return random_access_iterator_tag();
+}
+
+template <class T, class Distance> 
+inline T* value_type(const input_iterator<T, Distance>&) {
+  return (T*)(0); 
+}
+
+template <class T, class Distance> 
+inline T* value_type(const forward_iterator<T, Distance>&) {
+  return (T*)(0);
+}
+
+template <class T, class Distance> 
+inline T* value_type(const bidirectional_iterator<T, Distance>&) {
+  return (T*)(0);
+}
+
+template <class T, class Distance> 
+inline T* value_type(const random_access_iterator<T, Distance>&) {
+  return (T*)(0);
+}
+
+template <class T>
+inline T* value_type(const T*) { return (T*)(0); }
+
+template <class T, class Distance> 
+inline Distance* distance_type(const input_iterator<T, Distance>&) {
+  return (Distance*)(0);
+}
+
+template <class T, class Distance> 
+inline Distance* distance_type(const forward_iterator<T, Distance>&) {
+  return (Distance*)(0);
+}
+
+template <class T, class Distance> 
+inline Distance* 
+distance_type(const bidirectional_iterator<T, Distance>&) {
+  return (Distance*)(0);
+}
+
+template <class T, class Distance> 
+inline Distance* 
+distance_type(const random_access_iterator<T, Distance>&) {
+  return (Distance*)(0);
+}
+
+template <class T>
+inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); }
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+template <class InputIterator, class Distance>
+inline void __distance(InputIterator first, InputIterator last, Distance& n, 
+                       input_iterator_tag) {
+  while (first != last) { ++first; ++n; }
+}
+
+template <class RandomAccessIterator, class Distance>
+inline void __distance(RandomAccessIterator first, RandomAccessIterator last, 
+                       Distance& n, random_access_iterator_tag) {
+  n += last - first;
+}
+
+template <class InputIterator, class Distance>
+inline void distance(InputIterator first, InputIterator last, Distance& n) {
+  __distance(first, last, n, iterator_category(first));
+}
+
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+template <class InputIterator>
+inline iterator_traits<InputIterator>::difference_type
+__distance(InputIterator first, InputIterator last, input_iterator_tag) {
+  iterator_traits<InputIterator>::difference_type n = 0;
+  while (first != last) {
+    ++first; ++n;
+  }
+  return n;
+}
+
+template <class RandomAccessIterator>
+inline iterator_traits<RandomAccessIterator>::difference_type
+__distance(RandomAccessIterator first, RandomAccessIterator last,
+           random_access_iterator_tag) {
+  return last - first;
+}
+
+template <class InputIterator>
+inline iterator_traits<InputIterator>::difference_type
+distance(InputIterator first, InputIterator last) {
+  typedef typename iterator_traits<InputIterator>::iterator_category category;
+  return __distance(first, last, category());
+}
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+template <class InputIterator, class Distance>
+inline void __advance(InputIterator& i, Distance n, input_iterator_tag) {
+  while (n--) ++i;
+}
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1183
+#endif
+
+template <class BidirectionalIterator, class Distance>
+inline void __advance(BidirectionalIterator& i, Distance n, 
+                      bidirectional_iterator_tag) {
+  if (n >= 0)
+    while (n--) ++i;
+  else
+    while (n++) --i;
+}
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1183
+#endif
+
+template <class RandomAccessIterator, class Distance>
+inline void __advance(RandomAccessIterator& i, Distance n, 
+                      random_access_iterator_tag) {
+  i += n;
+}
+
+template <class InputIterator, class Distance>
+inline void advance(InputIterator& i, Distance n) {
+  __advance(i, n, iterator_category(i));
+}
+
+template <class Container>
+class back_insert_iterator {
+protected:
+  Container* container;
+public:
+  typedef output_iterator_tag iterator_category;
+  typedef void                value_type;
+  typedef void                difference_type;
+  typedef void                pointer;
+  typedef void                reference;
+
+  explicit back_insert_iterator(Container& x) : container(&x) {}
+  back_insert_iterator<Container>&
+  operator=(const typename Container::value_type& value) { 
+    container->push_back(value);
+    return *this;
+  }
+  back_insert_iterator<Container>& operator*() { return *this; }
+  back_insert_iterator<Container>& operator++() { return *this; }
+  back_insert_iterator<Container>& operator++(int) { return *this; }
+};
+
+#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+template <class Container>
+inline output_iterator_tag
+iterator_category(const back_insert_iterator<Container>&)
+{
+  return output_iterator_tag();
+}
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+template <class Container>
+inline back_insert_iterator<Container> back_inserter(Container& x) {
+  return back_insert_iterator<Container>(x);
+}
+
+template <class Container>
+class front_insert_iterator {
+protected:
+  Container* container;
+public:
+  typedef output_iterator_tag iterator_category;
+  typedef void                value_type;
+  typedef void                difference_type;
+  typedef void                pointer;
+  typedef void                reference;
+
+  explicit front_insert_iterator(Container& x) : container(&x) {}
+  front_insert_iterator<Container>&
+  operator=(const typename Container::value_type& value) { 
+    container->push_front(value);
+    return *this;
+  }
+  front_insert_iterator<Container>& operator*() { return *this; }
+  front_insert_iterator<Container>& operator++() { return *this; }
+  front_insert_iterator<Container>& operator++(int) { return *this; }
+};
+
+#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+template <class Container>
+inline output_iterator_tag
+iterator_category(const front_insert_iterator<Container>&)
+{
+  return output_iterator_tag();
+}
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+template <class Container>
+inline front_insert_iterator<Container> front_inserter(Container& x) {
+  return front_insert_iterator<Container>(x);
+}
+
+template <class Container>
+class insert_iterator {
+protected:
+  Container* container;
+  typename Container::iterator iter;
+public:
+  typedef output_iterator_tag iterator_category;
+  typedef void                value_type;
+  typedef void                difference_type;
+  typedef void                pointer;
+  typedef void                reference;
+
+  insert_iterator(Container& x, typename Container::iterator i) 
+    : container(&x), iter(i) {}
+  insert_iterator<Container>&
+  operator=(const typename Container::value_type& value) { 
+    iter = container->insert(iter, value);
+    ++iter;
+    return *this;
+  }
+  insert_iterator<Container>& operator*() { return *this; }
+  insert_iterator<Container>& operator++() { return *this; }
+  insert_iterator<Container>& operator++(int) { return *this; }
+};
+
+#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+template <class Container>
+inline output_iterator_tag
+iterator_category(const insert_iterator<Container>&)
+{
+  return output_iterator_tag();
+}
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+template <class Container, class Iterator>
+inline insert_iterator<Container> inserter(Container& x, Iterator i) {
+  typedef typename Container::iterator iter;
+  return insert_iterator<Container>(x, iter(i));
+}
+
+#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
+template <class BidirectionalIterator, class T, class Reference = T&, 
+          class Distance = ptrdiff_t> 
+#else
+template <class BidirectionalIterator, class T, class Reference, 
+          class Distance> 
+#endif
+class reverse_bidirectional_iterator {
+  typedef reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
+                                         Distance> self;
+protected:
+  BidirectionalIterator current;
+public:
+  typedef bidirectional_iterator_tag iterator_category;
+  typedef T                          value_type;
+  typedef Distance                   difference_type;
+  typedef T*                         pointer;
+  typedef Reference                  reference;
+
+  reverse_bidirectional_iterator() {}
+  explicit reverse_bidirectional_iterator(BidirectionalIterator x)
+    : current(x) {}
+  BidirectionalIterator base() const { return current; }
+  Reference operator*() const {
+    BidirectionalIterator tmp = current;
+    return *--tmp;
+  }
+#ifndef __SGI_STL_NO_ARROW_OPERATOR
+  pointer operator->() const { return &(operator*()); }
+#endif /* __SGI_STL_NO_ARROW_OPERATOR */
+  self& operator++() {
+    --current;
+    return *this;
+  }
+  self operator++(int) {
+    self tmp = *this;
+    --current;
+    return tmp;
+  }
+  self& operator--() {
+    ++current;
+    return *this;
+  }
+  self operator--(int) {
+    self tmp = *this;
+    ++current;
+    return tmp;
+  }
+};
+
+#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+template <class BidirectionalIterator, class T, class Reference, 
+          class Distance>
+inline bidirectional_iterator_tag
+iterator_category(const reverse_bidirectional_iterator<BidirectionalIterator,
+                                                       T,
+                                                       Reference, Distance>&) {
+  return bidirectional_iterator_tag();
+}
+
+template <class BidirectionalIterator, class T, class Reference, 
+          class Distance>
+inline T*
+value_type(const reverse_bidirectional_iterator<BidirectionalIterator, T,
+                                               Reference, Distance>&) {
+  return (T*) 0;
+}
+
+template <class BidirectionalIterator, class T, class Reference, 
+          class Distance>
+inline Distance*
+distance_type(const reverse_bidirectional_iterator<BidirectionalIterator, T,
+                                                  Reference, Distance>&) {
+  return (Distance*) 0;
+}
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+template <class BidirectionalIterator, class T, class Reference,
+          class Distance>
+inline bool operator==(
+    const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
+                                         Distance>& x, 
+    const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
+                                         Distance>& y) {
+  return x.base() == y.base();
+}
+
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+// This is the new version of reverse_iterator, as defined in the
+//  draft C++ standard.  It relies on the iterator_traits template,
+//  which in turn relies on partial specialization.  The class
+//  reverse_bidirectional_iterator is no longer part of the draft
+//  standard, but it is retained for backward compatibility.
+
+template <class Iterator>
+class reverse_iterator 
+{
+protected:
+  Iterator current;
+public:
+  typedef typename iterator_traits<Iterator>::iterator_category
+          iterator_category;
+  typedef typename iterator_traits<Iterator>::value_type
+          value_type;
+  typedef typename iterator_traits<Iterator>::difference_type
+          difference_type;
+  typedef typename iterator_traits<Iterator>::pointer
+          pointer;
+  typedef typename iterator_traits<Iterator>::reference
+          reference;
+
+  typedef Iterator iterator_type;
+  typedef reverse_iterator<Iterator> self;
+
+public:
+  reverse_iterator() {}
+  explicit reverse_iterator(iterator_type x) : current(x) {}
+
+  reverse_iterator(const self& x) : current(x.current) {}
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class Iter>
+  reverse_iterator(const reverse_iterator<Iter>& x) : current(x.current) {}
+#endif /* __STL_MEMBER_TEMPLATES */
+    
+  iterator_type base() const { return current; }
+  reference operator*() const {
+    Iterator tmp = current;
+    return *--tmp;
+  }
+#ifndef __SGI_STL_NO_ARROW_OPERATOR
+  pointer operator->() const { return &(operator*()); }
+#endif /* __SGI_STL_NO_ARROW_OPERATOR */
+
+  self& operator++() {
+    --current;
+    return *this;
+  }
+  self operator++(int) {
+    self tmp = *this;
+    --current;
+    return tmp;
+  }
+  self& operator--() {
+    ++current;
+    return *this;
+  }
+  self operator--(int) {
+    self tmp = *this;
+    ++current;
+    return tmp;
+  }
+
+  self operator+(difference_type n) const {
+    return self(current - n);
+  }
+  self& operator+=(difference_type n) {
+    current -= n;
+    return *this;
+  }
+  self operator-(difference_type n) const {
+    return self(current + n);
+  }
+  self& operator-=(difference_type n) {
+    current += n;
+    return *this;
+  }
+  reference operator[](difference_type n) const { return *(*this + n); }  
+}; 
+template <class Iterator>
+inline bool operator==(const reverse_iterator<Iterator>& x, 
+                       const reverse_iterator<Iterator>& y) {
+  return x.base() == y.base();
+}
+
+template <class Iterator>
+inline bool operator<(const reverse_iterator<Iterator>& x, 
+                      const reverse_iterator<Iterator>& y) {
+  return y.base() < x.base();
+}
+
+template <class Iterator>
+inline typename reverse_iterator<Iterator>::difference_type
+operator-(const reverse_iterator<Iterator>& x, 
+          const reverse_iterator<Iterator>& y) {
+  return y.base() - x.base();
+}
+
+template <class Iterator>
+inline reverse_iterator<Iterator> 
+operator+(reverse_iterator<Iterator>::difference_type n,
+          const reverse_iterator<Iterator>& x) {
+  return reverse_iterator<Iterator>(x.base() - n);
+}
+
+#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+// This is the old version of reverse_iterator, as found in the original
+//  HP STL.  It does not use partial specialization.
+
+#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
+template <class RandomAccessIterator, class T, class Reference = T&,
+          class Distance = ptrdiff_t> 
+#else
+template <class RandomAccessIterator, class T, class Reference,
+          class Distance> 
+#endif
+class reverse_iterator {
+  typedef reverse_iterator<RandomAccessIterator, T, Reference, Distance>
+        self;
+protected:
+  RandomAccessIterator current;
+public:
+  typedef random_access_iterator_tag iterator_category;
+  typedef T                          value_type;
+  typedef Distance                   difference_type;
+  typedef T*                         pointer;
+  typedef Reference                  reference;
+
+  reverse_iterator() {}
+  explicit reverse_iterator(RandomAccessIterator x) : current(x) {}
+  RandomAccessIterator base() const { return current; }
+  Reference operator*() const { return *(current - 1); }
+#ifndef __SGI_STL_NO_ARROW_OPERATOR
+  pointer operator->() const { return &(operator*()); }
+#endif /* __SGI_STL_NO_ARROW_OPERATOR */
+  self& operator++() {
+    --current;
+    return *this;
+  }
+  self operator++(int) {
+    self tmp = *this;
+    --current;
+    return tmp;
+  }
+  self& operator--() {
+    ++current;
+    return *this;
+  }
+  self operator--(int) {
+    self tmp = *this;
+    ++current;
+    return tmp;
+  }
+  self operator+(Distance n) const {
+    return self(current - n);
+  }
+  self& operator+=(Distance n) {
+    current -= n;
+    return *this;
+  }
+  self operator-(Distance n) const {
+    return self(current + n);
+  }
+  self& operator-=(Distance n) {
+    current += n;
+    return *this;
+  }
+  Reference operator[](Distance n) const { return *(*this + n); }
+};
+
+template <class RandomAccessIterator, class T, class Reference, class Distance>
+inline random_access_iterator_tag
+iterator_category(const reverse_iterator<RandomAccessIterator, T,
+                                         Reference, Distance>&) {
+  return random_access_iterator_tag();
+}
+
+template <class RandomAccessIterator, class T, class Reference, class Distance>
+inline T* value_type(const reverse_iterator<RandomAccessIterator, T,
+                                            Reference, Distance>&) {
+  return (T*) 0;
+}
+
+template <class RandomAccessIterator, class T, class Reference, class Distance>
+inline Distance* distance_type(const reverse_iterator<RandomAccessIterator, T,
+                                                      Reference, Distance>&) {
+  return (Distance*) 0;
+}
+
+
+template <class RandomAccessIterator, class T, class Reference, class Distance>
+inline bool operator==(const reverse_iterator<RandomAccessIterator, T,
+                                              Reference, Distance>& x, 
+                       const reverse_iterator<RandomAccessIterator, T,
+                                              Reference, Distance>& y) {
+  return x.base() == y.base();
+}
+
+template <class RandomAccessIterator, class T, class Reference, class Distance>
+inline bool operator<(const reverse_iterator<RandomAccessIterator, T,
+                                             Reference, Distance>& x, 
+                      const reverse_iterator<RandomAccessIterator, T,
+                                             Reference, Distance>& y) {
+  return y.base() < x.base();
+}
+
+template <class RandomAccessIterator, class T, class Reference, class Distance>
+inline Distance operator-(const reverse_iterator<RandomAccessIterator, T,
+                                                 Reference, Distance>& x, 
+                          const reverse_iterator<RandomAccessIterator, T,
+                                                 Reference, Distance>& y) {
+  return y.base() - x.base();
+}
+
+template <class RandomAccessIter, class T, class Ref, class Dist>
+inline reverse_iterator<RandomAccessIter, T, Ref, Dist> 
+operator+(Dist n, const reverse_iterator<RandomAccessIter, T, Ref, Dist>& x) {
+  return reverse_iterator<RandomAccessIter, T, Ref, Dist>(x.base() - n);
+}
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+template <class T, class Distance = ptrdiff_t> 
+class istream_iterator {
+  friend bool
+  operator== __STL_NULL_TMPL_ARGS (const istream_iterator<T, Distance>& x,
+                                   const istream_iterator<T, Distance>& y);
+protected:
+  istream* stream;
+  T value;
+  bool end_marker;
+  void read() {
+    end_marker = (*stream) ? true : false;
+    if (end_marker) *stream >> value;
+    end_marker = (*stream) ? true : false;
+  }
+public:
+  typedef input_iterator_tag iterator_category;
+  typedef T                  value_type;
+  typedef Distance           difference_type;
+  typedef const T*           pointer;
+  typedef const T&           reference;
+
+  istream_iterator() : stream(&cin), end_marker(false) {}
+  istream_iterator(istream& s) : stream(&s) { read(); }
+  reference operator*() const { return value; }
+#ifndef __SGI_STL_NO_ARROW_OPERATOR
+  pointer operator->() const { return &(operator*()); }
+#endif /* __SGI_STL_NO_ARROW_OPERATOR */
+  istream_iterator<T, Distance>& operator++() { 
+    read(); 
+    return *this;
+  }
+  istream_iterator<T, Distance> operator++(int)  {
+    istream_iterator<T, Distance> tmp = *this;
+    read();
+    return tmp;
+  }
+};
+
+#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+template <class T, class Distance>
+inline input_iterator_tag 
+iterator_category(const istream_iterator<T, Distance>&) {
+  return input_iterator_tag();
+}
+
+template <class T, class Distance>
+inline T* value_type(const istream_iterator<T, Distance>&) { return (T*) 0; }
+
+template <class T, class Distance>
+inline Distance* distance_type(const istream_iterator<T, Distance>&) {
+  return (Distance*) 0;
+}
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+template <class T, class Distance>
+inline bool operator==(const istream_iterator<T, Distance>& x,
+                       const istream_iterator<T, Distance>& y) {
+  return x.stream == y.stream && x.end_marker == y.end_marker ||
+         x.end_marker == false && y.end_marker == false;
+}
+
+template <class T>
+class ostream_iterator {
+protected:
+  ostream* stream;
+  const char* string;
+public:
+  typedef output_iterator_tag iterator_category;
+  typedef void                value_type;
+  typedef void                difference_type;
+  typedef void                pointer;
+  typedef void                reference;
+
+  ostream_iterator(ostream& s) : stream(&s), string(0) {}
+  ostream_iterator(ostream& s, const char* c) : stream(&s), string(c)  {}
+  ostream_iterator<T>& operator=(const T& value) { 
+    *stream << value;
+    if (string) *stream << string;
+    return *this;
+  }
+  ostream_iterator<T>& operator*() { return *this; }
+  ostream_iterator<T>& operator++() { return *this; } 
+  ostream_iterator<T>& operator++(int) { return *this; } 
+};
+
+#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+template <class T>
+inline output_iterator_tag 
+iterator_category(const ostream_iterator<T>&) {
+  return output_iterator_tag();
+}
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_ITERATOR_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_list.h b/libstdc++/stl/stl_list.h
new file mode 100644 (file)
index 0000000..ac836b6
--- /dev/null
@@ -0,0 +1,617 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_LIST_H
+#define __SGI_STL_INTERNAL_LIST_H
+
+__STL_BEGIN_NAMESPACE
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1174
+#endif
+
+template <class T>
+struct __list_node {
+  typedef void* void_pointer;
+  void_pointer next;
+  void_pointer prev;
+  T data;
+};
+
+template<class T, class Ref, class Ptr>
+struct __list_iterator {
+  typedef __list_iterator<T, T&, T*>             iterator;
+  typedef __list_iterator<T, const T&, const T*> const_iterator;
+  typedef __list_iterator<T, Ref, Ptr>           self;
+
+  typedef bidirectional_iterator_tag iterator_category;
+  typedef T value_type;
+  typedef Ptr pointer;
+  typedef Ref reference;
+  typedef __list_node<T>* link_type;
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+
+  link_type node;
+
+  __list_iterator(link_type x) : node(x) {}
+  __list_iterator() {}
+  __list_iterator(const iterator& x) : node(x.node) {}
+
+  bool operator==(const self& x) const { return node == x.node; }
+  bool operator!=(const self& x) const { return node != x.node; }
+  reference operator*() const { return (*node).data; }
+
+#ifndef __SGI_STL_NO_ARROW_OPERATOR
+  pointer operator->() const { return &(operator*()); }
+#endif /* __SGI_STL_NO_ARROW_OPERATOR */
+
+  self& operator++() { 
+    node = (link_type)((*node).next);
+    return *this;
+  }
+  self operator++(int) { 
+    self tmp = *this;
+    ++*this;
+    return tmp;
+  }
+  self& operator--() { 
+    node = (link_type)((*node).prev);
+    return *this;
+  }
+  self operator--(int) { 
+    self tmp = *this;
+    --*this;
+    return tmp;
+  }
+};
+
+#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+template <class T, class Ref, class Ptr>
+inline bidirectional_iterator_tag
+iterator_category(const __list_iterator<T, Ref, Ptr>&) {
+  return bidirectional_iterator_tag();
+}
+
+template <class T, class Ref, class Ptr>
+inline T*
+value_type(const __list_iterator<T, Ref, Ptr>&) {
+  return 0;
+}
+
+template <class T, class Ref, class Ptr>
+inline ptrdiff_t*
+distance_type(const __list_iterator<T, Ref, Ptr>&) {
+  return 0;
+}
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+template <class T, class Alloc = alloc>
+class list {
+protected:
+  typedef void* void_pointer;
+  typedef __list_node<T> list_node;
+  typedef simple_alloc<list_node, Alloc> list_node_allocator;
+public:      
+  typedef T value_type;
+  typedef value_type* pointer;
+  typedef const value_type* const_pointer;
+  typedef value_type& reference;
+  typedef const value_type& const_reference;
+  typedef list_node* link_type;
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+
+public:
+  typedef __list_iterator<T, T&, T*>             iterator;
+  typedef __list_iterator<T, const T&, const T*> const_iterator;
+
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+  typedef reverse_iterator<const_iterator> const_reverse_iterator;
+  typedef reverse_iterator<iterator> reverse_iterator;
+#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+  typedef reverse_bidirectional_iterator<const_iterator, value_type,
+  const_reference, difference_type>
+  const_reverse_iterator;
+  typedef reverse_bidirectional_iterator<iterator, value_type, reference,
+  difference_type>
+  reverse_iterator; 
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+protected:
+  link_type get_node() { return list_node_allocator::allocate(); }
+  void put_node(link_type p) { list_node_allocator::deallocate(p); }
+
+  link_type create_node(const T& x) {
+    link_type p = get_node();
+    __STL_TRY {
+      construct(&p->data, x);
+    }
+    __STL_UNWIND(put_node(p));
+    return p;
+  }
+  void destroy_node(link_type p) {
+    destroy(&p->data);
+    put_node(p);
+  }
+
+protected:
+  void empty_initialize() { 
+    node = get_node();
+    node->next = node;
+    node->prev = node;
+  }
+
+  void fill_initialize(size_type n, const T& value) {
+    empty_initialize();
+    __STL_TRY {
+      insert(begin(), n, value);
+    }
+    __STL_UNWIND(clear(); put_node(node));
+  }
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  void range_initialize(InputIterator first, InputIterator last) {
+    empty_initialize();
+    __STL_TRY {
+      insert(begin(), first, last);
+    }
+    __STL_UNWIND(clear(); put_node(node));
+  }
+#else  /* __STL_MEMBER_TEMPLATES */
+  void range_initialize(const T* first, const T* last) {
+    empty_initialize();
+    __STL_TRY {
+      insert(begin(), first, last);
+    }
+    __STL_UNWIND(clear(); put_node(node));
+  }
+  void range_initialize(const_iterator first, const_iterator last) {
+    empty_initialize();
+    __STL_TRY {
+      insert(begin(), first, last);
+    }
+    __STL_UNWIND(clear(); put_node(node));
+  }
+#endif /* __STL_MEMBER_TEMPLATES */
+
+protected:
+  link_type node;
+
+public:
+  list() { empty_initialize(); }
+
+  iterator begin() { return (link_type)((*node).next); }
+  const_iterator begin() const { return (link_type)((*node).next); }
+  iterator end() { return node; }
+  const_iterator end() const { return node; }
+  reverse_iterator rbegin() { return reverse_iterator(end()); }
+  const_reverse_iterator rbegin() const { 
+    return const_reverse_iterator(end()); 
+  }
+  reverse_iterator rend() { return reverse_iterator(begin()); }
+  const_reverse_iterator rend() const { 
+    return const_reverse_iterator(begin());
+  } 
+  bool empty() const { return node->next == node; }
+  size_type size() const {
+    size_type result = 0;
+    distance(begin(), end(), result);
+    return result;
+  }
+  size_type max_size() const { return size_type(-1); }
+  reference front() { return *begin(); }
+  const_reference front() const { return *begin(); }
+  reference back() { return *(--end()); }
+  const_reference back() const { return *(--end()); }
+  void swap(list<T, Alloc>& x) { __STD::swap(node, x.node); }
+  iterator insert(iterator position, const T& x) {
+    link_type tmp = create_node(x);
+    tmp->next = position.node;
+    tmp->prev = position.node->prev;
+    (link_type(position.node->prev))->next = tmp;
+    position.node->prev = tmp;
+    return tmp;
+  }
+  iterator insert(iterator position) { return insert(position, T()); }
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  void insert(iterator position, InputIterator first, InputIterator last);
+#else /* __STL_MEMBER_TEMPLATES */
+  void insert(iterator position, const T* first, const T* last);
+  void insert(iterator position,
+              const_iterator first, const_iterator last);
+#endif /* __STL_MEMBER_TEMPLATES */
+  void insert(iterator pos, size_type n, const T& x);
+  void insert(iterator pos, int n, const T& x) {
+    insert(pos, (size_type)n, x);
+  }
+  void insert(iterator pos, long n, const T& x) {
+    insert(pos, (size_type)n, x);
+  }
+
+  void push_front(const T& x) { insert(begin(), x); }
+  void push_back(const T& x) { insert(end(), x); }
+  iterator erase(iterator position) {
+    link_type next_node = link_type(position.node->next);
+    link_type prev_node = link_type(position.node->prev);
+    prev_node->next = next_node;
+    next_node->prev = prev_node;
+    destroy_node(position.node);
+    return iterator(next_node);
+  }
+  iterator erase(iterator first, iterator last);
+  void resize(size_type new_size, const T& x);
+  void resize(size_type new_size) { resize(new_size, T()); }
+  void clear();
+
+  void pop_front() { erase(begin()); }
+  void pop_back() { 
+    iterator tmp = end();
+    erase(--tmp);
+  }
+  list(size_type n, const T& value) { fill_initialize(n, value); }
+  list(int n, const T& value) { fill_initialize(n, value); }
+  list(long n, const T& value) { fill_initialize(n, value); }
+  explicit list(size_type n) { fill_initialize(n, T()); }
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  list(InputIterator first, InputIterator last) {
+    range_initialize(first, last);
+  }
+
+#else /* __STL_MEMBER_TEMPLATES */
+  list(const T* first, const T* last) { range_initialize(first, last); }
+  list(const_iterator first, const_iterator last) {
+    range_initialize(first, last);
+  }
+#endif /* __STL_MEMBER_TEMPLATES */
+  list(const list<T, Alloc>& x) {
+    range_initialize(x.begin(), x.end());
+  }
+  ~list() {
+    clear();
+    put_node(node);
+  }
+  list<T, Alloc>& operator=(const list<T, Alloc>& x);
+
+protected:
+  void transfer(iterator position, iterator first, iterator last) {
+    if (position != last) {
+      (*(link_type((*last.node).prev))).next = position.node;
+      (*(link_type((*first.node).prev))).next = last.node;
+      (*(link_type((*position.node).prev))).next = first.node;  
+      link_type tmp = link_type((*position.node).prev);
+      (*position.node).prev = (*last.node).prev;
+      (*last.node).prev = (*first.node).prev; 
+      (*first.node).prev = tmp;
+    }
+  }
+
+public:
+  void splice(iterator position, list& x) {
+    if (!x.empty()) 
+      transfer(position, x.begin(), x.end());
+  }
+  void splice(iterator position, list&, iterator i) {
+    iterator j = i;
+    ++j;
+    if (position == i || position == j) return;
+    transfer(position, i, j);
+  }
+  void splice(iterator position, list&, iterator first, iterator last) {
+    if (first != last) 
+      transfer(position, first, last);
+  }
+  void remove(const T& value);
+  void unique();
+  void merge(list& x);
+  void reverse();
+  void sort();
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class Predicate> void remove_if(Predicate);
+  template <class BinaryPredicate> void unique(BinaryPredicate);
+  template <class StrictWeakOrdering> void merge(list&, StrictWeakOrdering);
+  template <class StrictWeakOrdering> void sort(StrictWeakOrdering);
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  friend bool operator== __STL_NULL_TMPL_ARGS (const list& x, const list& y);
+};
+
+template <class T, class Alloc>
+inline bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y) {
+  typedef typename list<T,Alloc>::link_type link_type;
+  link_type e1 = x.node;
+  link_type e2 = y.node;
+  link_type n1 = (link_type) e1->next;
+  link_type n2 = (link_type) e2->next;
+  for ( ; n1 != e1 && n2 != e2 ;
+          n1 = (link_type) n1->next, n2 = (link_type) n2->next)
+    if (n1->data != n2->data)
+      return false;
+  return n1 == e1 && n2 == e2;
+}
+
+template <class T, class Alloc>
+inline bool operator<(const list<T, Alloc>& x, const list<T, Alloc>& y) {
+  return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
+
+template <class T, class Alloc>
+inline void swap(list<T, Alloc>& x, list<T, Alloc>& y) {
+  x.swap(y);
+}
+
+#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
+
+#ifdef __STL_MEMBER_TEMPLATES
+
+template <class T, class Alloc> template <class InputIterator>
+void list<T, Alloc>::insert(iterator position,
+                            InputIterator first, InputIterator last) {
+  for ( ; first != last; ++first)
+    insert(position, *first);
+}
+
+#else /* __STL_MEMBER_TEMPLATES */
+
+template <class T, class Alloc>
+void list<T, Alloc>::insert(iterator position, const T* first, const T* last) {
+  for ( ; first != last; ++first)
+    insert(position, *first);
+}
+
+template <class T, class Alloc>
+void list<T, Alloc>::insert(iterator position,
+                            const_iterator first, const_iterator last) {
+  for ( ; first != last; ++first)
+    insert(position, *first);
+}
+
+#endif /* __STL_MEMBER_TEMPLATES */
+
+template <class T, class Alloc>
+void list<T, Alloc>::insert(iterator position, size_type n, const T& x) {
+  for ( ; n > 0; --n)
+    insert(position, x);
+}
+
+template <class T, class Alloc>
+list<T,Alloc>::iterator list<T, Alloc>::erase(iterator first, iterator last) {
+  while (first != last) erase(first++);
+  return last;
+}
+
+template <class T, class Alloc>
+void list<T, Alloc>::resize(size_type new_size, const T& 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 <class T, class Alloc> 
+void list<T, Alloc>::clear()
+{
+  link_type cur = (link_type) node->next;
+  while (cur != node) {
+    link_type tmp = cur;
+    cur = (link_type) cur->next;
+    destroy_node(tmp);
+  }
+  node->next = node;
+  node->prev = node;
+}
+
+template <class T, class Alloc>
+list<T, Alloc>& list<T, Alloc>::operator=(const list<T, Alloc>& x) {
+  if (this != &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);
+  }
+  return *this;
+}
+
+template <class T, class Alloc>
+void list<T, Alloc>::remove(const T& value) {
+  iterator first = begin();
+  iterator last = end();
+  while (first != last) {
+    iterator next = first;
+    ++next;
+    if (*first == value) erase(first);
+    first = next;
+  }
+}
+
+template <class T, class Alloc>
+void list<T, Alloc>::unique() {
+  iterator first = begin();
+  iterator last = end();
+  if (first == last) return;
+  iterator next = first;
+  while (++next != last) {
+    if (*first == *next)
+      erase(next);
+    else
+      first = next;
+    next = first;
+  }
+}
+
+template <class T, class Alloc>
+void list<T, Alloc>::merge(list<T, Alloc>& x) {
+  iterator first1 = begin();
+  iterator last1 = end();
+  iterator first2 = x.begin();
+  iterator last2 = x.end();
+  while (first1 != last1 && first2 != last2)
+    if (*first2 < *first1) {
+      iterator next = first2;
+      transfer(first1, first2, ++next);
+      first2 = next;
+    }
+    else
+      ++first1;
+  if (first2 != last2) transfer(last1, first2, last2);
+}
+
+template <class T, class Alloc>
+void list<T, Alloc>::reverse() {
+  if (node->next == node || link_type(node->next)->next == node) return;
+  iterator first = begin();
+  ++first;
+  while (first != end()) {
+    iterator old = first;
+    ++first;
+    transfer(begin(), old, first);
+  }
+}    
+
+template <class T, class Alloc>
+void list<T, Alloc>::sort() {
+  if (node->next == node || link_type(node->next)->next == node) return;
+  list<T, Alloc> carry;
+  list<T, Alloc> 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);
+      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]);
+  swap(counter[fill-1]);
+}
+
+#ifdef __STL_MEMBER_TEMPLATES
+
+template <class T, class Alloc> template <class Predicate>
+void list<T, 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 <class T, class Alloc> template <class BinaryPredicate>
+void list<T, 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 <class T, class Alloc> template <class StrictWeakOrdering>
+void list<T, Alloc>::merge(list<T, Alloc>& 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;
+      transfer(first1, first2, ++next);
+      first2 = next;
+    }
+    else
+      ++first1;
+  if (first2 != last2) transfer(last1, first2, last2);
+}
+
+template <class T, class Alloc> template <class StrictWeakOrdering>
+void list<T, Alloc>::sort(StrictWeakOrdering comp) {
+  if (node->next == node || link_type(node->next)->next == node) return;
+  list<T, Alloc> carry;
+  list<T, Alloc> 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]);
+}
+
+#endif /* __STL_MEMBER_TEMPLATES */
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1174
+#endif
+
+__STL_END_NAMESPACE 
+
+#endif /* __SGI_STL_INTERNAL_LIST_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_map.h b/libstdc++/stl/stl_map.h
new file mode 100644 (file)
index 0000000..2a830cc
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_MAP_H
+#define __SGI_STL_INTERNAL_MAP_H
+
+__STL_BEGIN_NAMESPACE
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1174
+#endif
+
+#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
+template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
+#else
+template <class Key, class T, class Compare, class Alloc = alloc>
+#endif
+class map {
+public:
+
+// typedefs:
+
+  typedef Key key_type;
+  typedef T data_type;
+  typedef T mapped_type;
+  typedef pair<const Key, T> value_type;
+  typedef Compare key_compare;
+    
+  class value_compare
+    : public binary_function<value_type, value_type, bool> {
+  friend class map<Key, T, 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:
+  typedef rb_tree<key_type, value_type, 
+                  select1st<value_type>, key_compare, Alloc> rep_type;
+  rep_type t;  // red-black tree representing map
+public:
+  typedef typename rep_type::pointer pointer;
+  typedef typename rep_type::const_pointer const_pointer;
+  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::reverse_iterator reverse_iterator;
+  typedef typename rep_type::const_reverse_iterator const_reverse_iterator;
+  typedef typename rep_type::size_type size_type;
+  typedef typename rep_type::difference_type difference_type;
+
+  // allocation/deallocation
+
+  map() : t(Compare()) {}
+  explicit map(const Compare& comp) : t(comp) {}
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  map(InputIterator first, InputIterator last)
+    : t(Compare()) { t.insert_unique(first, last); }
+
+  template <class InputIterator>
+  map(InputIterator first, InputIterator last, const Compare& comp)
+    : t(comp) { t.insert_unique(first, last); }
+#else
+  map(const value_type* first, const value_type* last)
+    : t(Compare()) { t.insert_unique(first, last); }
+  map(const value_type* first, const value_type* last, const Compare& comp)
+    : t(comp) { t.insert_unique(first, last); }
+
+  map(const_iterator first, const_iterator last)
+    : t(Compare()) { t.insert_unique(first, last); }
+  map(const_iterator first, const_iterator last, const Compare& comp)
+    : t(comp) { t.insert_unique(first, last); }
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  map(const map<Key, T, Compare, Alloc>& x) : t(x.t) {}
+  map<Key, T, Compare, Alloc>& operator=(const map<Key, T, Compare, Alloc>& x)
+  {
+    t = x.t;
+    return *this; 
+  }
+
+  // accessors:
+
+  key_compare key_comp() const { return t.key_comp(); }
+  value_compare value_comp() const { return value_compare(t.key_comp()); }
+  iterator begin() { return t.begin(); }
+  const_iterator begin() const { return t.begin(); }
+  iterator end() { return t.end(); }
+  const_iterator end() const { return t.end(); }
+  reverse_iterator rbegin() { return t.rbegin(); }
+  const_reverse_iterator rbegin() const { return t.rbegin(); }
+  reverse_iterator rend() { return t.rend(); }
+  const_reverse_iterator rend() const { return t.rend(); }
+  bool empty() const { return t.empty(); }
+  size_type size() const { return t.size(); }
+  size_type max_size() const { return t.max_size(); }
+  T& operator[](const key_type& k) {
+    return (*((insert(value_type(k, T()))).first)).second;
+  }
+  void swap(map<Key, T, Compare, Alloc>& x) { t.swap(x.t); }
+
+  // insert/erase
+
+  pair<iterator,bool> insert(const value_type& x) { return t.insert_unique(x); }
+  iterator insert(iterator position, const value_type& x) {
+    return t.insert_unique(position, x);
+  }
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  void insert(InputIterator first, InputIterator last) {
+    t.insert_unique(first, last);
+  }
+#else
+  void insert(const value_type* first, const value_type* last) {
+    t.insert_unique(first, last);
+  }
+  void insert(const_iterator first, const_iterator last) {
+    t.insert_unique(first, last);
+  }
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  void erase(iterator position) { t.erase(position); }
+  size_type erase(const key_type& x) { return t.erase(x); }
+  void erase(iterator first, iterator last) { t.erase(first, last); }
+  void clear() { t.clear(); }
+
+  // map operations:
+
+  iterator find(const key_type& x) { return t.find(x); }
+  const_iterator find(const key_type& x) const { return t.find(x); }
+  size_type count(const key_type& x) const { return t.count(x); }
+  iterator lower_bound(const key_type& x) {return t.lower_bound(x); }
+  const_iterator lower_bound(const key_type& x) const {
+    return t.lower_bound(x); 
+  }
+  iterator upper_bound(const key_type& x) {return t.upper_bound(x); }
+  const_iterator upper_bound(const key_type& x) const {
+    return t.upper_bound(x); 
+  }
+  
+  pair<iterator,iterator> equal_range(const key_type& x) {
+    return t.equal_range(x);
+  }
+  pair<const_iterator,const_iterator> equal_range(const key_type& x) const {
+    return t.equal_range(x);
+  }
+  friend bool operator== __STL_NULL_TMPL_ARGS (const map&, const map&);
+  friend bool operator< __STL_NULL_TMPL_ARGS (const map&, const map&);
+};
+
+template <class Key, class T, class Compare, class Alloc>
+inline bool operator==(const map<Key, T, Compare, Alloc>& x, 
+                       const map<Key, T, Compare, Alloc>& y) {
+  return x.t == y.t;
+}
+
+template <class Key, class T, class Compare, class Alloc>
+inline bool operator<(const map<Key, T, Compare, Alloc>& x, 
+                      const map<Key, T, Compare, Alloc>& y) {
+  return x.t < y.t;
+}
+
+#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
+
+template <class Key, class T, class Compare, class Alloc>
+inline void swap(map<Key, T, Compare, Alloc>& x, 
+                 map<Key, T, Compare, Alloc>& y) {
+  x.swap(y);
+}
+
+#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1174
+#endif
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_MAP_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_multimap.h b/libstdc++/stl/stl_multimap.h
new file mode 100644 (file)
index 0000000..b82159b
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_MULTIMAP_H
+#define __SGI_STL_INTERNAL_MULTIMAP_H
+
+__STL_BEGIN_NAMESPACE
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1174
+#endif
+
+#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
+template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
+#else
+template <class Key, class T, class Compare, class Alloc = alloc>
+#endif
+class multimap {
+public:
+
+// typedefs:
+
+  typedef Key key_type;
+  typedef T data_type;
+  typedef T mapped_type;
+  typedef pair<const Key, T> value_type;
+  typedef Compare key_compare;
+
+  class value_compare : public binary_function<value_type, value_type, bool> {
+  friend class multimap<Key, T, 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:
+  typedef rb_tree<key_type, value_type, 
+                  select1st<value_type>, key_compare, Alloc> rep_type;
+  rep_type t;  // red-black tree representing multimap
+public:
+  typedef typename rep_type::pointer pointer;
+  typedef typename rep_type::const_pointer const_pointer;
+  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::reverse_iterator reverse_iterator;
+  typedef typename rep_type::const_reverse_iterator const_reverse_iterator;
+  typedef typename rep_type::size_type size_type;
+  typedef typename rep_type::difference_type difference_type;
+
+// allocation/deallocation
+
+  multimap() : t(Compare()) { }
+  explicit multimap(const Compare& comp) : t(comp) { }
+
+#ifdef __STL_MEMBER_TEMPLATES  
+  template <class InputIterator>
+  multimap(InputIterator first, InputIterator last)
+    : t(Compare()) { t.insert_equal(first, last); }
+
+  template <class InputIterator>
+  multimap(InputIterator first, InputIterator last, const Compare& comp)
+    : t(comp) { t.insert_equal(first, last); }
+#else
+  multimap(const value_type* first, const value_type* last)
+    : t(Compare()) { t.insert_equal(first, last); }
+  multimap(const value_type* first, const value_type* last,
+           const Compare& comp)
+    : t(comp) { t.insert_equal(first, last); }
+
+  multimap(const_iterator first, const_iterator last)
+    : t(Compare()) { t.insert_equal(first, last); }
+  multimap(const_iterator first, const_iterator last, const Compare& comp)
+    : t(comp) { t.insert_equal(first, last); }
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  multimap(const multimap<Key, T, Compare, Alloc>& x) : t(x.t) { }
+  multimap<Key, T, Compare, Alloc>&
+  operator=(const multimap<Key, T, Compare, Alloc>& x) {
+    t = x.t;
+    return *this; 
+  }
+
+  // accessors:
+
+  key_compare key_comp() const { return t.key_comp(); }
+  value_compare value_comp() const { return value_compare(t.key_comp()); }
+  iterator begin() { return t.begin(); }
+  const_iterator begin() const { return t.begin(); }
+  iterator end() { return t.end(); }
+  const_iterator end() const { return t.end(); }
+  reverse_iterator rbegin() { return t.rbegin(); }
+  const_reverse_iterator rbegin() const { return t.rbegin(); }
+  reverse_iterator rend() { return t.rend(); }
+  const_reverse_iterator rend() const { return t.rend(); }
+  bool empty() const { return t.empty(); }
+  size_type size() const { return t.size(); }
+  size_type max_size() const { return t.max_size(); }
+  void swap(multimap<Key, T, Compare, Alloc>& x) { t.swap(x.t); }
+
+  // insert/erase
+
+  iterator insert(const value_type& x) { return t.insert_equal(x); }
+  iterator insert(iterator position, const value_type& x) {
+    return t.insert_equal(position, x);
+  }
+#ifdef __STL_MEMBER_TEMPLATES  
+  template <class InputIterator>
+  void insert(InputIterator first, InputIterator last) {
+    t.insert_equal(first, last);
+  }
+#else
+  void insert(const value_type* first, const value_type* last) {
+    t.insert_equal(first, last);
+  }
+  void insert(const_iterator first, const_iterator last) {
+    t.insert_equal(first, last);
+  }
+#endif /* __STL_MEMBER_TEMPLATES */
+  void erase(iterator position) { t.erase(position); }
+  size_type erase(const key_type& x) { return t.erase(x); }
+  void erase(iterator first, iterator last) { t.erase(first, last); }
+  void clear() { t.clear(); }
+
+  // multimap operations:
+
+  iterator find(const key_type& x) { return t.find(x); }
+  const_iterator find(const key_type& x) const { return t.find(x); }
+  size_type count(const key_type& x) const { return t.count(x); }
+  iterator lower_bound(const key_type& x) {return t.lower_bound(x); }
+  const_iterator lower_bound(const key_type& x) const {
+    return t.lower_bound(x); 
+  }
+  iterator upper_bound(const key_type& x) {return t.upper_bound(x); }
+  const_iterator upper_bound(const key_type& x) const {
+    return t.upper_bound(x); 
+  }
+   pair<iterator,iterator> equal_range(const key_type& x) {
+    return t.equal_range(x);
+  }
+  pair<const_iterator,const_iterator> equal_range(const key_type& x) const {
+    return t.equal_range(x);
+  }
+  friend bool operator== __STL_NULL_TMPL_ARGS (const multimap&,
+                                               const multimap&);
+  friend bool operator< __STL_NULL_TMPL_ARGS (const multimap&,
+                                              const multimap&);
+};
+
+template <class Key, class T, class Compare, class Alloc>
+inline bool operator==(const multimap<Key, T, Compare, Alloc>& x, 
+                       const multimap<Key, T, Compare, Alloc>& y) {
+  return x.t == y.t;
+}
+
+template <class Key, class T, class Compare, class Alloc>
+inline bool operator<(const multimap<Key, T, Compare, Alloc>& x, 
+                      const multimap<Key, T, Compare, Alloc>& y) {
+  return x.t < y.t;
+}
+
+#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
+
+template <class Key, class T, class Compare, class Alloc>
+inline void swap(multimap<Key, T, Compare, Alloc>& x, 
+                 multimap<Key, T, Compare, Alloc>& y) {
+  x.swap(y);
+}
+
+#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1174
+#endif
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_MULTIMAP_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_multiset.h b/libstdc++/stl/stl_multiset.h
new file mode 100644 (file)
index 0000000..ff5947e
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_MULTISET_H
+#define __SGI_STL_INTERNAL_MULTISET_H
+
+__STL_BEGIN_NAMESPACE
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1174
+#endif
+
+#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
+template <class Key, class Compare = less<Key>, class Alloc = alloc>
+#else
+template <class Key, class Compare, class Alloc = alloc>
+#endif
+class multiset {
+public:
+  // typedefs:
+
+  typedef Key key_type;
+  typedef Key value_type;
+  typedef Compare key_compare;
+  typedef Compare value_compare;
+private:
+  typedef rb_tree<key_type, value_type, 
+                  identity<value_type>, key_compare, Alloc> rep_type;
+  rep_type t;  // red-black tree representing multiset
+public:
+  typedef typename rep_type::const_pointer pointer;
+  typedef typename rep_type::const_pointer const_pointer;
+  typedef typename rep_type::const_reference reference;
+  typedef typename rep_type::const_reference const_reference;
+  typedef typename rep_type::const_iterator iterator;
+  typedef typename rep_type::const_iterator const_iterator;
+  typedef typename rep_type::const_reverse_iterator reverse_iterator;
+  typedef typename rep_type::const_reverse_iterator const_reverse_iterator;
+  typedef typename rep_type::size_type size_type;
+  typedef typename rep_type::difference_type difference_type;
+
+  // allocation/deallocation
+
+  multiset() : t(Compare()) {}
+  explicit multiset(const Compare& comp) : t(comp) {}
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  multiset(InputIterator first, InputIterator last)
+    : t(Compare()) { t.insert_equal(first, last); }
+  template <class InputIterator>
+  multiset(InputIterator first, InputIterator last, const Compare& comp)
+    : t(comp) { t.insert_equal(first, last); }
+#else
+  multiset(const value_type* first, const value_type* last)
+    : t(Compare()) { t.insert_equal(first, last); }
+  multiset(const value_type* first, const value_type* last,
+           const Compare& comp)
+    : t(comp) { t.insert_equal(first, last); }
+
+  multiset(const_iterator first, const_iterator last)
+    : t(Compare()) { t.insert_equal(first, last); }
+  multiset(const_iterator first, const_iterator last, const Compare& comp)
+    : t(comp) { t.insert_equal(first, last); }
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  multiset(const multiset<Key, Compare, Alloc>& x) : t(x.t) {}
+  multiset<Key, Compare, Alloc>&
+  operator=(const multiset<Key, Compare, Alloc>& x) {
+    t = x.t; 
+    return *this;
+  }
+
+  // accessors:
+
+  key_compare key_comp() const { return t.key_comp(); }
+  value_compare value_comp() const { return t.key_comp(); }
+  iterator begin() const { return t.begin(); }
+  iterator end() const { return t.end(); }
+  reverse_iterator rbegin() const { return t.rbegin(); } 
+  reverse_iterator rend() const { return t.rend(); }
+  bool empty() const { return t.empty(); }
+  size_type size() const { return t.size(); }
+  size_type max_size() const { return t.max_size(); }
+  void swap(multiset<Key, Compare, Alloc>& x) { t.swap(x.t); }
+
+  // insert/erase
+  iterator insert(const value_type& x) { 
+    return t.insert_equal(x);
+  }
+  iterator insert(iterator position, const value_type& x) {
+    typedef typename rep_type::iterator rep_iterator;
+    return t.insert_equal((rep_iterator&)position, x);
+  }
+
+#ifdef __STL_MEMBER_TEMPLATES  
+  template <class InputIterator>
+  void insert(InputIterator first, InputIterator last) {
+    t.insert_equal(first, last);
+  }
+#else
+  void insert(const value_type* first, const value_type* last) {
+    t.insert_equal(first, last);
+  }
+  void insert(const_iterator first, const_iterator last) {
+    t.insert_equal(first, last);
+  }
+#endif /* __STL_MEMBER_TEMPLATES */
+  void erase(iterator position) { 
+    typedef typename rep_type::iterator rep_iterator;
+    t.erase((rep_iterator&)position); 
+  }
+  size_type erase(const key_type& x) { 
+    return t.erase(x); 
+  }
+  void erase(iterator first, iterator last) { 
+    typedef typename rep_type::iterator rep_iterator;
+    t.erase((rep_iterator&)first, (rep_iterator&)last); 
+  }
+  void clear() { t.clear(); }
+
+  // multiset operations:
+
+  iterator find(const key_type& x) const { return t.find(x); }
+  size_type count(const key_type& x) const { return t.count(x); }
+  iterator lower_bound(const key_type& x) const {
+    return t.lower_bound(x);
+  }
+  iterator upper_bound(const key_type& x) const {
+    return t.upper_bound(x); 
+  }
+  pair<iterator,iterator> equal_range(const key_type& x) const {
+    return t.equal_range(x);
+  }
+  friend bool operator== __STL_NULL_TMPL_ARGS (const multiset&,
+                                               const multiset&);
+  friend bool operator< __STL_NULL_TMPL_ARGS (const multiset&,
+                                              const multiset&);
+};
+
+template <class Key, class Compare, class Alloc>
+inline bool operator==(const multiset<Key, Compare, Alloc>& x, 
+                       const multiset<Key, Compare, Alloc>& y) {
+  return x.t == y.t;
+}
+
+template <class Key, class Compare, class Alloc>
+inline bool operator<(const multiset<Key, Compare, Alloc>& x, 
+                      const multiset<Key, Compare, Alloc>& y) {
+  return x.t < y.t;
+}
+
+#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
+
+template <class Key, class Compare, class Alloc>
+inline void swap(multiset<Key, Compare, Alloc>& x, 
+                 multiset<Key, Compare, Alloc>& y) {
+  x.swap(y);
+}
+
+#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1174
+#endif
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_MULTISET_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_numeric.h b/libstdc++/stl/stl_numeric.h
new file mode 100644 (file)
index 0000000..57fee2b
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+
+#ifndef __SGI_STL_INTERNAL_NUMERIC_H
+#define __SGI_STL_INTERNAL_NUMERIC_H
+
+__STL_BEGIN_NAMESPACE
+
+template <class InputIterator, class T>
+T accumulate(InputIterator first, InputIterator last, T init) {
+  for ( ; first != last; ++first)
+    init = init + *first;
+  return init;
+}
+
+template <class InputIterator, class T, class BinaryOperation>
+T accumulate(InputIterator first, InputIterator last, T init,
+             BinaryOperation binary_op) {
+  for ( ; first != last; ++first)
+    init = binary_op(init, *first);
+  return init;
+}
+
+template <class InputIterator1, class InputIterator2, class T>
+T inner_product(InputIterator1 first1, InputIterator1 last1,
+                InputIterator2 first2, T init) {
+  for ( ; first1 != last1; ++first1, ++first2)
+    init = init + (*first1 * *first2);
+  return init;
+}
+
+template <class InputIterator1, class InputIterator2, class T,
+          class BinaryOperation1, class BinaryOperation2>
+T inner_product(InputIterator1 first1, InputIterator1 last1,
+                InputIterator2 first2, T init, BinaryOperation1 binary_op1,
+                BinaryOperation2 binary_op2) {
+  for ( ; first1 != last1; ++first1, ++first2)
+    init = binary_op1(init, binary_op2(*first1, *first2));
+  return init;
+}
+
+template <class InputIterator, class OutputIterator, class T>
+OutputIterator __partial_sum(InputIterator first, InputIterator last,
+                             OutputIterator result, T*) {
+  T value = *first;
+  while (++first != last) {
+    value = value + *first;
+    *++result = value;
+  }
+  return ++result;
+}
+
+template <class InputIterator, class OutputIterator>
+OutputIterator partial_sum(InputIterator first, InputIterator last,
+                           OutputIterator result) {
+  if (first == last) return result;
+  *result = *first;
+  return __partial_sum(first, last, result, value_type(first));
+}
+
+template <class InputIterator, class OutputIterator, class T,
+          class BinaryOperation>
+OutputIterator __partial_sum(InputIterator first, InputIterator last,
+                             OutputIterator result, T*,
+                             BinaryOperation binary_op) {
+  T value = *first;
+  while (++first != last) {
+    value = binary_op(value, *first);
+    *++result = value;
+  }
+  return ++result;
+}
+
+template <class InputIterator, class OutputIterator, class BinaryOperation>
+OutputIterator partial_sum(InputIterator first, InputIterator last,
+                           OutputIterator result, BinaryOperation binary_op) {
+  if (first == last) return result;
+  *result = *first;
+  return __partial_sum(first, last, result, value_type(first), binary_op);
+}
+
+template <class InputIterator, class OutputIterator, class T>
+OutputIterator __adjacent_difference(InputIterator first, InputIterator last, 
+                                     OutputIterator result, T*) {
+  T value = *first;
+  while (++first != last) {
+    T tmp = *first;
+    *++result = tmp - value;
+    value = tmp;
+  }
+  return ++result;
+}
+
+template <class InputIterator, class OutputIterator>
+OutputIterator adjacent_difference(InputIterator first, InputIterator last, 
+                                   OutputIterator result) {
+  if (first == last) return result;
+  *result = *first;
+  return __adjacent_difference(first, last, result, value_type(first));
+}
+
+template <class InputIterator, class OutputIterator, class T, 
+          class BinaryOperation>
+OutputIterator __adjacent_difference(InputIterator first, InputIterator last, 
+                                     OutputIterator result, T*,
+                                     BinaryOperation binary_op) {
+  T value = *first;
+  while (++first != last) {
+    T tmp = *first;
+    *++result = binary_op(tmp, value);
+    value = tmp;
+  }
+  return ++result;
+}
+
+template <class InputIterator, class OutputIterator, class BinaryOperation>
+OutputIterator adjacent_difference(InputIterator first, InputIterator last,
+                                   OutputIterator result,
+                                   BinaryOperation binary_op) {
+  if (first == last) return result;
+  *result = *first;
+  return __adjacent_difference(first, last, result, value_type(first),
+                               binary_op);
+}
+
+// Returns x ** n, where n >= 0.  Note that "multiplication"
+//  is required to be associative, but not necessarily commutative.
+    
+template <class T, class Integer, class MonoidOperation>
+T power(T x, Integer n, MonoidOperation op) {
+  if (n == 0)
+    return identity_element(op);
+  else {
+    while ((n & 1) == 0) {
+      n >>= 1;
+      x = op(x, x);
+    }
+
+    T result = x;
+    n >>= 1;
+    while (n != 0) {
+      x = op(x, x);
+      if ((n & 1) != 0)
+        result = op(result, x);
+      n >>= 1;
+    }
+    return result;
+  }
+}
+
+template <class T, class Integer>
+inline T power(T x, Integer n) {
+  return power(x, n, multiplies<T>());
+}
+
+
+template <class ForwardIterator, class T>
+void iota(ForwardIterator first, ForwardIterator last, T value) {
+  while (first != last) *first++ = value++;
+}
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_NUMERIC_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_pair.h b/libstdc++/stl/stl_pair.h
new file mode 100644 (file)
index 0000000..10a9cb0
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_PAIR_H
+#define __SGI_STL_INTERNAL_PAIR_H
+
+__STL_BEGIN_NAMESPACE
+
+template <class T1, class T2>
+struct pair {
+  typedef T1 first_type;
+  typedef T2 second_type;
+
+  T1 first;
+  T2 second;
+  pair() : first(T1()), second(T2()) {}
+  pair(const T1& a, const T2& b) : first(a), second(b) {}
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class U1, class U2>
+  pair(const pair<U1, U2>& p) : first(p.first), second(p.second) {}
+#endif
+};
+
+template <class T1, class T2>
+inline bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y) { 
+  return x.first == y.first && x.second == y.second; 
+}
+
+template <class T1, class T2>
+inline bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y) { 
+  return x.first < y.first || (!(y.first < x.first) && x.second < y.second); 
+}
+
+template <class T1, class T2>
+inline pair<T1, T2> make_pair(const T1& x, const T2& y) {
+  return pair<T1, T2>(x, y);
+}
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_PAIR_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_queue.h b/libstdc++/stl/stl_queue.h
new file mode 100644 (file)
index 0000000..ff6eede
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_QUEUE_H
+#define __SGI_STL_INTERNAL_QUEUE_H
+
+__STL_BEGIN_NAMESPACE
+
+#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
+template <class T, class Sequence = deque<T> >
+#else
+template <class T, class Sequence>
+#endif
+class queue {
+  friend bool operator== __STL_NULL_TMPL_ARGS (const queue& x, const queue& y);
+  friend bool operator< __STL_NULL_TMPL_ARGS (const queue& x, const queue& y);
+public:
+  typedef typename Sequence::value_type value_type;
+  typedef typename Sequence::size_type size_type;
+  typedef typename Sequence::reference reference;
+  typedef typename Sequence::const_reference const_reference;
+protected:
+  Sequence c;
+public:
+  bool empty() const { return c.empty(); }
+  size_type size() const { return c.size(); }
+  reference front() { return c.front(); }
+  const_reference front() const { return c.front(); }
+  reference back() { return c.back(); }
+  const_reference back() const { return c.back(); }
+  void push(const value_type& x) { c.push_back(x); }
+  void pop() { c.pop_front(); }
+};
+
+template <class T, class Sequence>
+bool operator==(const queue<T, Sequence>& x, const queue<T, Sequence>& y) {
+  return x.c == y.c;
+}
+
+template <class T, class Sequence>
+bool operator<(const queue<T, Sequence>& x, const queue<T, Sequence>& y) {
+  return x.c < y.c;
+}
+
+#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
+template <class T, class Sequence = vector<T>, 
+          class Compare = less<typename Sequence::value_type> >
+#else
+template <class T, class Sequence, class Compare>
+#endif
+class  priority_queue {
+public:
+  typedef typename Sequence::value_type value_type;
+  typedef typename Sequence::size_type size_type;
+  typedef typename Sequence::reference reference;
+  typedef typename Sequence::const_reference const_reference;
+protected:
+  Sequence c;
+  Compare comp;
+public:
+  priority_queue() : c() {}
+  explicit priority_queue(const Compare& x) :  c(), comp(x) {}
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  priority_queue(InputIterator first, InputIterator last, const Compare& x)
+    : c(first, last), comp(x) { make_heap(c.begin(), c.end(), comp); }
+  template <class InputIterator>
+  priority_queue(InputIterator first, InputIterator last) 
+    : c(first, last) { make_heap(c.begin(), c.end(), comp); }
+#else /* __STL_MEMBER_TEMPLATES */
+  priority_queue(const value_type* first, const value_type* last, 
+                 const Compare& x) : c(first, last), comp(x) {
+    make_heap(c.begin(), c.end(), comp);
+  }
+  priority_queue(const value_type* first, const value_type* last) 
+    : c(first, last) { make_heap(c.begin(), c.end(), comp); }
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  bool empty() const { return c.empty(); }
+  size_type size() const { return c.size(); }
+  const_reference top() const { return c.front(); }
+  void push(const value_type& x) {
+    __STL_TRY {
+      c.push_back(x); 
+      push_heap(c.begin(), c.end(), comp);
+    }
+    __STL_UNWIND(c.clear());
+  }
+  void pop() {
+    __STL_TRY {
+      pop_heap(c.begin(), c.end(), comp);
+      c.pop_back();
+    }
+    __STL_UNWIND(c.clear());
+  }
+};
+
+// no equality is provided
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_QUEUE_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_raw_storage_iter.h b/libstdc++/stl/stl_raw_storage_iter.h
new file mode 100644 (file)
index 0000000..5d3d074
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H
+#define __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H
+
+__STL_BEGIN_NAMESPACE
+
+template <class ForwardIterator, class T>
+class raw_storage_iterator {
+protected:
+  ForwardIterator iter;
+public:
+  typedef output_iterator_tag iterator_category;
+  typedef void                value_type;
+  typedef void                difference_type;
+  typedef void                pointer;
+  typedef void                reference;
+
+  explicit raw_storage_iterator(ForwardIterator x) : iter(x) {}
+  raw_storage_iterator<ForwardIterator, T>& operator*() { return *this; }
+  raw_storage_iterator<ForwardIterator, T>& operator=(const T& element) {
+    construct(&*iter, element);
+    return *this;
+  }        
+  raw_storage_iterator<ForwardIterator, T>& operator++() {
+    ++iter;
+    return *this;
+  }
+  raw_storage_iterator<ForwardIterator, T> operator++(int) {
+    raw_storage_iterator<ForwardIterator, T> tmp = *this;
+    ++iter;
+    return tmp;
+  }
+};
+
+#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+template <class ForwardIterator, class T>
+inline output_iterator_tag
+iterator_category(const raw_storage_iterator<ForwardIterator, T>&)
+{
+  return output_iterator_tag();
+}
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+#endif /* __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H */
+
+__STL_END_NAMESPACE
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_relops.h b/libstdc++/stl/stl_relops.h
new file mode 100644 (file)
index 0000000..01a0c7c
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_RELOPS
+#define __SGI_STL_INTERNAL_RELOPS
+
+__STL_BEGIN_RELOPS_NAMESPACE
+
+template <class T>
+inline bool operator!=(const T& x, const T& y) {
+  return !(x == y);
+}
+
+template <class T>
+inline bool operator>(const T& x, const T& y) {
+  return y < x;
+}
+
+template <class T>
+inline bool operator<=(const T& x, const T& y) {
+  return !(y < x);
+}
+
+template <class T>
+inline bool operator>=(const T& x, const T& y) {
+  return !(x < y);
+}
+
+__STL_END_RELOPS_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_RELOPS */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_rope.h b/libstdc++/stl/stl_rope.h
new file mode 100644 (file)
index 0000000..620db6f
--- /dev/null
@@ -0,0 +1,2112 @@
+/*
+ * Copyright (c) 1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_ROPE_H
+# define __SGI_STL_INTERNAL_ROPE_H
+
+# ifdef __GC
+#   define __GC_CONST const
+# else
+#   define __GC_CONST   // constant except for deallocation
+# endif
+# ifdef __STL_SGI_THREADS
+#    include <mutex.h>
+# endif
+
+__STL_BEGIN_NAMESPACE
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1174
+#endif
+
+// The end-of-C-string character.
+// This is what the draft standard says it should be.
+template <class charT>
+inline charT __eos(charT*) { return charT(); }
+
+// Test for basic character types.
+// For basic character types leaves having a trailing eos.
+template <class charT>
+inline bool __is_basic_char_type(charT *) { return false; }
+template <class charT>
+inline bool __is_one_byte_char_type(charT *) { return false; }
+
+inline bool __is_basic_char_type(char *) { return true; }
+inline bool __is_one_byte_char_type(char *) { return true; }
+inline bool __is_basic_char_type(wchar_t *) { return true; }
+
+// Store an eos iff charT is a basic character type.
+// Do not reference __eos if it isn't.
+template <class charT>
+inline void __cond_store_eos(charT&) {}
+
+inline void __cond_store_eos(char& c) { c = 0; }
+inline void __cond_store_eos(wchar_t& c) { c = 0; }
+       
+
+// rope<charT,Alloc> is a sequence of charT.
+// Ropes appear to be mutable, but update operations
+// really copy enough of the data structure to leave the original
+// valid.  Thus ropes can be logically copied by just copying
+// a pointer value.
+// The __eos function is used for those functions that
+// convert to/from C-like strings to detect the end of the string.
+// __compare is used as the character comparison function.
+template <class charT>
+class char_producer {
+    public:
+       virtual ~char_producer() {};
+       virtual void operator()(size_t start_pos, size_t len, charT* buffer)
+               = 0;
+       // Buffer should really be an arbitrary output iterator.
+       // That way we could flatten directly into an ostream, etc.
+       // This is thoroughly impossible, since iterator types don't
+       // have runtime descriptions.
+};
+
+// Sequence buffers:
+//
+// Sequence must provide an append operation that appends an
+// array to the sequence.  Sequence buffers are useful only if
+// appending an entire array is cheaper than appending element by element.
+// This is true for many string representations.
+// This should  perhaps inherit from ostream<sequence::value_type>
+// and be implemented correspondingly, so that they can be used
+// for formatted.  For the sake of portability, we don't do this yet.
+//
+// For now, sequence buffers behave as output iterators.  But they also
+// behave a little like basic_ostringstream<sequence::value_type> and a
+// little like containers.
+
+template<class sequence, size_t buf_sz = 100
+#   if defined(__sgi) && !defined(__GNUC__)
+#       define __TYPEDEF_WORKAROUND
+         ,class v = typename sequence::value_type
+#   endif
+        >
+// The 3rd parameter works around a common compiler bug.
+class sequence_buffer : public output_iterator {
+    public:
+#       ifndef __TYPEDEF_WORKAROUND
+           typedef typename sequence::value_type value_type;
+#      else
+           typedef v value_type;
+#      endif
+    protected:
+       sequence *prefix;
+       value_type buffer[buf_sz];
+       size_t buf_count;
+    public:
+       void flush() {
+           prefix->append(buffer, buffer + buf_count);
+           buf_count = 0;
+       }
+       ~sequence_buffer() { flush(); }
+       sequence_buffer() : prefix(0), buf_count(0) {}
+       sequence_buffer(const sequence_buffer & x) {
+           prefix = x.prefix;
+            buf_count = x.buf_count;
+            copy(x.buffer, x.buffer + x.buf_count, buffer);
+       }
+       sequence_buffer(sequence_buffer & x) {
+           x.flush();
+           prefix = x.prefix;
+           buf_count = 0;
+       }
+       sequence_buffer(sequence& s) : prefix(&s), buf_count(0) {}
+       sequence_buffer& operator= (sequence_buffer& x) {
+           x.flush();
+           prefix = x.prefix;
+           buf_count = 0;
+           return *this;
+       }
+       sequence_buffer& operator= (const sequence_buffer& x) {
+           prefix = x.prefix;
+           buf_count = x.buf_count;
+           copy(x.buffer, x.buffer + x.buf_count, buffer);
+           return *this;
+       }
+       void push_back(value_type x)
+       {
+           if (buf_count < buf_sz) {
+               buffer[buf_count] = x;
+               ++buf_count;
+           } else {
+               flush();
+               buffer[0] = x;
+               buf_count = 1;
+           }
+       }
+       void append(value_type *s, size_t len)
+       {
+           if (len + buf_count <= buf_sz) {
+               size_t i, j;
+               for (i = buf_count, j = 0; j < len; i++, j++) {
+                   buffer[i] = s[j];
+               }
+               buf_count += len;
+           } else if (0 == buf_count) {
+               prefix->append(s, s + len);
+           } else {
+               flush();
+               append(s, len);
+           }
+       }
+       sequence_buffer& write(value_type *s, size_t len)
+       {
+           append(s, len);
+           return *this;
+       }
+       sequence_buffer& put(value_type x)
+       {
+           push_back(x);
+           return *this;
+       }
+       sequence_buffer& operator=(const value_type& rhs)
+       {
+           push_back(rhs);
+           return *this;
+       }
+       sequence_buffer& operator*() { return *this; }
+       sequence_buffer& operator++() { return *this; }
+       sequence_buffer& operator++(int) { return *this; }
+};
+
+// The following should be treated as private, at least for now.
+template<class charT>
+class __rope_char_consumer {
+    public:
+       // If we had member templates, these should not be virtual.
+       // For now we need to use run-time parametrization where
+       // compile-time would do.  Hence this should all be private
+       // for now.
+       // The symmetry with char_producer is accidental and temporary.
+       virtual ~__rope_char_consumer() {};
+       virtual bool operator()(const charT* buffer, size_t len) = 0;
+};
+
+//
+// What follows should really be local to rope.  Unfortunately,
+// that doesn't work, since it makes it impossible to define generic
+// equality on rope iterators.  According to the draft standard, the
+// template parameters for such an equality operator cannot be inferred
+// from the occurence of a member class as a parameter.
+// (SGI compilers in fact allow this, but the result wouldn't be
+// portable.)
+// Similarly, some of the static member functions are member functions
+// only to avoid polluting the global namespace, and to circumvent
+// restrictions on type inference for template functions.
+//
+
+template<class CharT, class Alloc=__ALLOC> class rope;
+template<class CharT, class Alloc> struct __rope_RopeConcatenation;
+template<class CharT, class Alloc> struct __rope_RopeLeaf;
+template<class CharT, class Alloc> struct __rope_RopeFunction;
+template<class CharT, class Alloc> struct __rope_RopeSubstring;
+template<class CharT, class Alloc> class __rope_iterator;
+template<class CharT, class Alloc> class __rope_const_iterator;
+template<class CharT, class Alloc> class __rope_charT_ref_proxy;
+template<class CharT, class Alloc> class __rope_charT_ptr_proxy;
+
+//
+// The internal data structure for representing a rope.  This is
+// private to the implementation.  A rope is really just a pointer
+// to one of these.
+//
+// A few basic functions for manipulating this data structure
+// are members of RopeBase.  Most of the more complex algorithms
+// are implemented as rope members.
+//
+// Some of the static member functions of RopeBase have identically
+// named functions in rope that simply invoke the RopeBase versions.
+//
+
+template<class charT, class Alloc>
+struct __rope_RopeBase {
+    typedef rope<charT,Alloc> my_rope;
+    typedef simple_alloc<charT, Alloc> DataAlloc;
+    typedef simple_alloc<__rope_RopeConcatenation<charT,Alloc>, Alloc> CAlloc;
+    typedef simple_alloc<__rope_RopeLeaf<charT,Alloc>, Alloc> LAlloc;
+    typedef simple_alloc<__rope_RopeFunction<charT,Alloc>, Alloc> FAlloc;
+    typedef simple_alloc<__rope_RopeSubstring<charT,Alloc>, Alloc> SAlloc;
+    public:
+    enum { max_rope_depth = 45 };
+    enum {leaf, concat, substringfn, function} tag:8;
+    bool is_balanced:8;
+    unsigned char depth;
+    size_t size;
+    __GC_CONST charT * c_string;
+                       /* Flattened version of string, if needed.  */
+                       /* typically 0.                             */
+                       /* If it's not 0, then the memory is owned  */
+                       /* by this node.                            */
+                       /* In the case of a leaf, this may point to */
+                       /* the same memory as the data field.       */
+#   ifndef __GC
+#       if defined(__STL_WIN32THREADS)
+           long refcount;      // InterlockedIncrement wants a long *
+#      else
+           size_t refcount;
+#      endif
+       // We count references from rope instances
+       // and references from other rope nodes.  We
+       // do not count const_iterator references.
+       // Iterator references are counted so that rope modifications
+       // can be detected after the fact.
+       // Generally function results are counted, i.e.
+       // a pointer returned by a function is included at the
+       // point at which the pointer is returned.
+       // The recipient should decrement the count if the
+       // result is not needed.
+       // Generally function arguments are not reflected
+       // in the reference count.  The callee should increment
+       // the count before saving the argument someplace that
+       // will outlive the call.
+#   endif
+#   ifndef __GC
+#       ifdef __STL_SGI_THREADS
+           // Reference counting with multiple threads and no
+           // hardware or thread package support is pretty awful.
+           // Mutexes are normally too expensive.
+           // We'll assume a COMPARE_AND_SWAP(destp, old, new)
+           // operation, which might be cheaper.
+#           if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64))
+#               define __add_and_fetch(l,v) add_then_test((unsigned long *)l,v)
+#           endif
+           void init_refcount_lock() {}
+           void incr_refcount ()
+           {
+               __add_and_fetch(&refcount, 1);
+           }
+           size_t decr_refcount ()
+           {
+               return __add_and_fetch(&refcount, (size_t)(-1));
+           }
+#       elif defined(__STL_WIN32THREADS)
+           void init_refcount_lock() {}
+            void incr_refcount ()
+            {
+                InterlockedIncrement(&refcount);
+            }
+            size_t decr_refcount ()
+            {
+                return InterlockedDecrement(&refcount);
+            }
+#      elif defined(_PTHREADS)
+           // This should be portable, but performance is expected
+           // to be quite awful.  This really needs platform specific
+           // code.
+           pthread_mutex_t refcount_lock;
+           void init_refcount_lock() {
+               pthread_mutex_init(&refcount_lock, 0);
+           }
+           void incr_refcount ()
+            {   
+               pthread_mutex_lock(&refcount_lock);
+                ++refcount;
+               pthread_mutex_unlock(&refcount_lock);
+            }
+            size_t decr_refcount ()
+            {   
+               size_t result;
+               pthread_mutex_lock(&refcount_lock);
+                result = --refcount;
+               pthread_mutex_unlock(&refcount_lock);
+                return result;
+            }
+#      else
+           void init_refcount_lock() {}
+           void incr_refcount ()
+           {
+               ++refcount;
+           }
+           size_t decr_refcount ()
+           {
+               --refcount;
+               return refcount;
+           }
+#       endif
+#   else
+       void incr_refcount () {}
+#   endif
+       static void free_string(charT *, size_t len);
+                       // Deallocate data section of a leaf.
+                       // This shouldn't be a member function.
+                       // But its hard to do anything else at the
+                       // moment, because it's templatized w.r.t.
+                       // an allocator.
+                       // Does nothing if __GC is defined.
+#   ifndef __GC
+         void free_c_string();
+         void free_tree();
+                       // Deallocate t. Assumes t is not 0.
+         void unref_nonnil()
+         {
+             if (0 == decr_refcount()) free_tree();
+         }
+         void ref_nonnil()
+         {
+             incr_refcount();
+         }
+         static void unref(__rope_RopeBase* t)
+         {
+             if (0 != t) {
+                 t -> unref_nonnil();
+             }
+         }
+         static void ref(__rope_RopeBase* t)
+         {
+             if (0 != t) t -> incr_refcount();
+         }
+         static void free_if_unref(__rope_RopeBase* t)
+         {
+             if (0 != t && 0 == t -> refcount) t -> free_tree();
+         }
+#   else /* __GC */
+         void unref_nonnil() {}
+         void ref_nonnil() {}
+         static void unref(__rope_RopeBase* t) {}
+         static void ref(__rope_RopeBase* t) {}
+         static void fn_finalization_proc(void * tree, void *);
+         static void free_if_unref(__rope_RopeBase* t) {}
+#   endif
+
+    // The data fields of leaves are allocated with some
+    // extra space, to accomodate future growth and for basic
+    // character types, to hold a trailing eos character.
+    enum { alloc_granularity = 8 };
+    static size_t rounded_up_size(size_t n) {
+        size_t size_with_eos;
+            
+        if (__is_basic_char_type((charT *)0)) {
+           size_with_eos = n + 1;
+       } else {
+           size_with_eos = n;
+       }
+#       ifdef __GC
+          return size_with_eos;
+#      else
+          // Allow slop for in-place expansion.
+          return (size_with_eos + alloc_granularity-1)
+                       &~ (alloc_granularity-1);
+#      endif
+    }
+};
+
+template<class charT, class Alloc>
+struct __rope_RopeLeaf : public __rope_RopeBase<charT,Alloc> {
+  public:  // Apparently needed by VC++
+    __GC_CONST charT* data;     /* Not necessarily 0 terminated. */
+                               /* The allocated size is         */
+                               /* rounded_up_size(size), except */
+                               /* in the GC case, in which it   */
+                               /* doesn't matter.               */
+};
+
+template<class charT, class Alloc>
+struct __rope_RopeConcatenation : public __rope_RopeBase<charT,Alloc> {
+  public:
+    __rope_RopeBase<charT,Alloc>* left;
+    __rope_RopeBase<charT,Alloc>* right;
+};
+
+template<class charT, class Alloc>
+struct __rope_RopeFunction : public __rope_RopeBase<charT,Alloc> {
+  public:
+    char_producer<charT>* fn;
+#   ifndef __GC
+      bool delete_when_done;   // Char_producer is owned by the
+                               // rope and should be explicitly
+                               // deleted when the rope becomes
+                               // inaccessible.
+#   else
+      // In the GC case, we either register the rope for
+      // finalization, or not.  Thus the field is unnecessary;
+      // the information is stored in the collector data structures.
+#   endif
+};
+// Substring results are usually represented using just
+// concatenation nodes.  But in the case of very long flat ropes
+// or ropes with a functional representation that isn't practical.
+// In that case, we represent the result as a special case of
+// RopeFunction, whose char_producer points back to the rope itself.
+// In all cases except repeated substring operations and
+// deallocation, we treat the result as a RopeFunction.
+template<class charT, class Alloc>
+struct __rope_RopeSubstring: public __rope_RopeFunction<charT,Alloc>,
+                            public char_producer<charT> {
+  public:
+    __rope_RopeBase<charT,Alloc> * base;       // not 0
+    size_t start;
+    virtual ~__rope_RopeSubstring() {}
+    virtual void operator()(size_t start_pos, size_t req_len,
+                           charT *buffer) {
+       switch(base -> tag) {
+           case function:
+           case substringfn:
+             {
+               char_producer<charT> *fn =
+                       ((__rope_RopeFunction<charT,Alloc> *)base) -> fn;
+               __stl_assert(start_pos + req_len <= size);
+               __stl_assert(start + size <= base -> size);
+               (*fn)(start_pos + start, req_len, buffer);
+             }
+             break;
+           case leaf:
+             {
+               __GC_CONST charT * s =
+                       ((__rope_RopeLeaf<charT,Alloc> *)base) -> data;
+               uninitialized_copy_n(s + start_pos + start, req_len,
+                                    buffer);
+             }
+             break;
+           default:
+             __stl_assert(false);
+       }
+    }
+    __rope_RopeSubstring(__rope_RopeBase<charT,Alloc> * b, size_t s, size_t l) :
+       base(b), start(s) {
+#       ifndef __GC
+           refcount = 1;
+           init_refcount_lock();
+           base -> ref_nonnil();
+#       endif
+       size = l;
+       tag = substringfn;
+       depth = 0;
+       c_string = 0;
+       fn = this;
+    }
+};
+
+
+// Self-destructing pointers to RopeBase.
+// These are not conventional smart pointers.  Their
+// only purpose in life is to ensure that unref is called
+// on the pointer either at normal exit or if an exception
+// is raised.  It is the caller's responsibility to
+// adjust reference counts when these pointers are initialized
+// or assigned to.  (This convention significantly reduces
+// the number of potentially expensive reference count
+// updates.)
+#ifndef __GC
+  template<class charT, class Alloc>
+  struct __rope_self_destruct_ptr {
+    __rope_RopeBase<charT,Alloc> * ptr;
+    ~__rope_self_destruct_ptr() { __rope_RopeBase<charT,Alloc>::unref(ptr); }
+#   ifdef __STL_USE_EXCEPTIONS
+       __rope_self_destruct_ptr() : ptr(0) {};
+#   else
+       __rope_self_destruct_ptr() {};
+#   endif
+    __rope_self_destruct_ptr(__rope_RopeBase<charT,Alloc> * p) : ptr(p) {}
+    __rope_RopeBase<charT,Alloc> & operator*() { return *ptr; }
+    __rope_RopeBase<charT,Alloc> * operator->() { return ptr; }
+    operator __rope_RopeBase<charT,Alloc> *() { return ptr; }
+    __rope_self_destruct_ptr & operator= (__rope_RopeBase<charT,Alloc> * x)
+       { ptr = x; return *this; }
+  };
+#endif
+
+// Dereferencing a nonconst iterator has to return something
+// that behaves almost like a reference.  It's not possible to
+// return an actual reference since assignment requires extra
+// work.  And we would get into the same problems as with the
+// CD2 version of basic_string.
+template<class charT, class Alloc>
+class __rope_charT_ref_proxy {
+    friend class rope<charT,Alloc>;
+    friend class __rope_iterator<charT,Alloc>;
+    friend class __rope_charT_ptr_proxy<charT,Alloc>;
+#   ifdef __GC
+       typedef __rope_RopeBase<charT,Alloc> * self_destruct_ptr;
+#   else
+       typedef __rope_self_destruct_ptr<charT,Alloc> self_destruct_ptr;
+#   endif
+    typedef __rope_RopeBase<charT,Alloc> RopeBase;
+    typedef rope<charT,Alloc> my_rope;
+    size_t pos;
+    charT current;
+    bool current_valid;
+    my_rope * root;     // The whole rope.
+  public:
+    __rope_charT_ref_proxy(my_rope * r, size_t p) :
+       pos(p), root(r), current_valid(false) {}
+    __rope_charT_ref_proxy(my_rope * r, size_t p,
+                   charT c) :
+       pos(p), root(r), current(c), current_valid(true) {}
+    operator charT () const;
+    __rope_charT_ref_proxy& operator= (charT c);
+    __rope_charT_ptr_proxy<charT,Alloc> operator& () const;
+    __rope_charT_ref_proxy& operator= (const __rope_charT_ref_proxy& c) {
+       return operator=((charT)c); 
+    }
+};
+
+template<class charT, class Alloc>
+class __rope_charT_ptr_proxy {
+    friend class __rope_charT_ref_proxy<charT,Alloc>;
+    size_t pos;
+    charT current;
+    bool current_valid;
+    rope<charT,Alloc> * root;     // The whole rope.
+  public:
+    __rope_charT_ptr_proxy(const __rope_charT_ref_proxy<charT,Alloc> & x) :
+       pos(x.pos), root(x.root), current_valid(x.current_valid),
+       current(x.current) {}
+    __rope_charT_ptr_proxy(const __rope_charT_ptr_proxy & x) :
+       pos(x.pos), root(x.root), current_valid(x.current_valid),
+       current(x.current) {}
+    __rope_charT_ptr_proxy() {}
+    __rope_charT_ptr_proxy(charT * x) : root(0), pos(0) {
+       __stl_assert(0 == x);
+    }
+    __rope_charT_ptr_proxy& operator= (const __rope_charT_ptr_proxy& x) {
+       pos = x.pos;
+       current = x.current;
+       current_valid = x.current_valid;
+       root = x.root;
+       return *this;
+    }
+    friend bool operator== __STL_NULL_TMPL_ARGS
+                (const __rope_charT_ptr_proxy<charT,Alloc> & x,
+                 const __rope_charT_ptr_proxy<charT,Alloc> & y);
+    __rope_charT_ref_proxy<charT,Alloc> operator *() const {
+       if (current_valid) {
+           return __rope_charT_ref_proxy<charT,Alloc>(root, pos, current);
+       } else {
+           return __rope_charT_ref_proxy<charT,Alloc>(root, pos);
+       }
+    }
+};
+
+// Rope iterators:
+// Unlike in the C version, we cache only part of the stack
+// for rope iterators, since they must be efficiently copyable.
+// When we run out of cache, we have to reconstruct the iterator
+// value.
+// Pointers from iterators are not included in reference counts.
+// Iterators are assumed to be thread private.  Ropes can
+// be shared.
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1375
+#endif
+
+template<class charT, class Alloc>
+class __rope_iterator_base:
+  public random_access_iterator<charT, ptrdiff_t> {
+  friend class rope<charT, Alloc>;
+  public:
+    typedef __rope_RopeBase<charT,Alloc> RopeBase;
+       // Borland doesnt want this to be protected.
+  protected:
+    enum { path_cache_len = 4 }; // Must be <= 9.
+    enum { iterator_buf_len = 15 };
+    size_t current_pos;
+    RopeBase * root;     // The whole rope.
+    size_t leaf_pos;    // Starting position for current leaf
+    __GC_CONST charT * buf_start;
+                       // Buffer possibly
+                       // containing current char.
+    __GC_CONST charT * buf_ptr;
+                       // Pointer to current char in buffer.
+                       // != 0 ==> buffer valid.
+    __GC_CONST charT * buf_end;
+                       // One past last valid char in buffer.
+    // What follows is the path cache.  We go out of our
+    // way to make this compact.
+    // Path_end contains the bottom section of the path from
+    // the root to the current leaf.
+    const RopeBase * path_end[path_cache_len];
+    int leaf_index;     // Last valid pos in path_end;
+                       // path_end[0] ... path_end[leaf_index-1]
+                       // point to concatenation nodes.
+    unsigned char path_directions;
+                         // (path_directions >> i) & 1 is 1
+                         // iff we got from path_end[leaf_index - i - 1]
+                         // to path_end[leaf_index - i] by going to the
+                         // right. Assumes path_cache_len <= 9.
+    charT tmp_buf[iterator_buf_len];
+                       // Short buffer for surrounding chars.
+                       // This is useful primarily for 
+                       // RopeFunctions.  We put the buffer
+                       // here to avoid locking in the
+                       // multithreaded case.
+    // The cached path is generally assumed to be valid
+    // only if the buffer is valid.
+    static void setbuf(__rope_iterator_base &x);
+                                       // Set buffer contents given
+                                       // path cache.
+    static void setcache(__rope_iterator_base &x);
+                                       // Set buffer contents and
+                                       // path cache.
+    static void setcache_for_incr(__rope_iterator_base &x);
+                                       // As above, but assumes path
+                                       // cache is valid for previous posn.
+    __rope_iterator_base() {}
+    __rope_iterator_base(RopeBase * root, size_t pos):
+                  root(root), current_pos(pos), buf_ptr(0) {}
+    __rope_iterator_base(const __rope_iterator_base& x) {
+       if (0 != x.buf_ptr) {
+           *this = x;
+       } else {
+           current_pos = x.current_pos;
+           root = x.root;
+           buf_ptr = 0;
+       }
+    }
+    void incr(size_t n);
+    void decr(size_t n);
+  public:
+    size_t index() const { return current_pos; }
+};
+
+template<class charT, class Alloc> class __rope_iterator;
+
+template<class charT, class Alloc>
+class __rope_const_iterator : public __rope_iterator_base<charT,Alloc> {
+    friend class rope<charT,Alloc>;
+  protected:
+    __rope_const_iterator(const RopeBase * root, size_t pos):
+                  __rope_iterator_base<charT,Alloc>(
+                    const_cast<RopeBase *>(root), pos)
+                  // Only nonconst iterators modify root ref count
+    {}
+  public:
+    typedef charT reference;    // Really a value.  Returning a reference
+                               // Would be a mess, since it would have
+                               // to be included in refcount.
+    typedef const charT* pointer;
+
+  public:
+    __rope_const_iterator() {};
+    __rope_const_iterator(const __rope_const_iterator & x) :
+                               __rope_iterator_base<charT,Alloc>(x) { }
+    __rope_const_iterator(const __rope_iterator<charT,Alloc> & x);
+    __rope_const_iterator(const rope<charT,Alloc> &r, size_t pos) :
+       __rope_iterator_base<charT,Alloc>(r.tree_ptr, pos) {}
+    __rope_const_iterator& operator= (const __rope_const_iterator & x) {
+       if (0 != x.buf_ptr) {
+           *this = x;
+       } else {
+           current_pos = x.current_pos;
+           root = x.root;
+           buf_ptr = 0;
+       }
+       return(*this);
+    }
+    reference operator*() {
+       if (0 == buf_ptr) setcache(*this);
+       return *buf_ptr;
+    }
+    __rope_const_iterator& operator++() {
+       __GC_CONST charT * next;
+       if (0 != buf_ptr && (next = buf_ptr + 1) < buf_end) {
+           buf_ptr = next;
+           ++current_pos;
+       } else {
+           incr(1);
+       }
+       return *this;
+    }
+    __rope_const_iterator& operator+=(ptrdiff_t n) {
+       if (n >= 0) {
+           incr(n);
+       } else {
+           decr(-n);
+       }
+       return *this;
+    }
+    __rope_const_iterator& operator--() {
+       decr(1);
+       return *this;
+    }
+    __rope_const_iterator& operator-=(ptrdiff_t n) {
+       if (n >= 0) {
+           decr(n);
+       } else {
+           incr(-n);
+       }
+       return *this;
+    }
+    __rope_const_iterator operator++(int) {
+       size_t old_pos = current_pos;
+       incr(1);
+       return __rope_const_iterator<charT,Alloc>(root, old_pos);
+       // This makes a subsequent dereference expensive.
+       // Perhaps we should instead copy the iterator
+       // if it has a valid cache?
+    }
+    __rope_const_iterator operator--(int) {
+       size_t old_pos = current_pos;
+       decr(1);
+       return __rope_const_iterator<charT,Alloc>(root, old_pos);
+    }
+    friend __rope_const_iterator<charT,Alloc> operator- __STL_NULL_TMPL_ARGS
+       (const __rope_const_iterator<charT,Alloc> & x,
+        ptrdiff_t n);
+    friend __rope_const_iterator<charT,Alloc> operator+ __STL_NULL_TMPL_ARGS
+       (const __rope_const_iterator<charT,Alloc> & x,
+        ptrdiff_t n);
+    friend __rope_const_iterator<charT,Alloc> operator+ __STL_NULL_TMPL_ARGS
+       (ptrdiff_t n,
+        const __rope_const_iterator<charT,Alloc> & x);
+    reference operator[](size_t n) {
+       return rope<charT,Alloc>::fetch(root, current_pos + n);
+    }
+    friend bool operator== __STL_NULL_TMPL_ARGS
+       (const __rope_const_iterator<charT,Alloc> & x,
+        const __rope_const_iterator<charT,Alloc> & y);
+    friend bool operator< __STL_NULL_TMPL_ARGS
+       (const __rope_const_iterator<charT,Alloc> & x,
+        const __rope_const_iterator<charT,Alloc> & y);
+    friend ptrdiff_t operator- __STL_NULL_TMPL_ARGS
+       (const __rope_const_iterator<charT,Alloc> & x,
+        const __rope_const_iterator<charT,Alloc> & y);
+};
+
+template<class charT, class Alloc>
+class __rope_iterator : public __rope_iterator_base<charT,Alloc> {
+    friend class rope<charT,Alloc>;
+  protected:
+    rope<charT,Alloc> * root_rope;
+       // root is treated as a cached version of this,
+       // and is used to detect changes to the underlying
+       // rope.
+       // Root is included in the reference count.
+       // This is necessary so that we can detect changes reliably.
+       // Unfortunately, it requires careful bookkeeping for the
+       // nonGC case.
+    __rope_iterator(rope<charT,Alloc> * r, size_t pos):
+            __rope_iterator_base<charT,Alloc>(r -> tree_ptr, pos),
+            root_rope(r) {
+               RopeBase::ref(root);
+            }
+    void check();
+  public:
+    typedef __rope_charT_ref_proxy<charT,Alloc>  reference;
+    typedef __rope_charT_ref_proxy<charT,Alloc>* pointer;
+
+  public:
+    rope<charT,Alloc>& container() { return *root_rope; }
+    __rope_iterator() {
+       root = 0;  // Needed for reference counting.
+    };
+    __rope_iterator(const __rope_iterator & x) :
+       __rope_iterator_base<charT,Alloc>(x) {
+       root_rope = x.root_rope;
+       RopeBase::ref(root);
+    }
+    __rope_iterator(rope<charT,Alloc>& r, size_t pos);
+    ~__rope_iterator() {
+       RopeBase::unref(root);
+    }
+    __rope_iterator& operator= (const __rope_iterator & x) {
+       RopeBase *old = root;
+
+       RopeBase::ref(x.root);
+       if (0 != x.buf_ptr) {
+           *this = x;
+       } else {
+           current_pos = x.current_pos;
+           root = x.root;
+           root_rope = x.root_rope;
+           buf_ptr = 0;
+       }
+       RopeBase::unref(old);
+       return(*this);
+    }
+    reference operator*() {
+       check();
+       if (0 == buf_ptr) {
+           return __rope_charT_ref_proxy<charT,Alloc>(root_rope, current_pos);
+       } else {
+           return __rope_charT_ref_proxy<charT,Alloc>(root_rope,
+                                                      current_pos, *buf_ptr);
+       }
+    }
+    __rope_iterator& operator++() {
+       incr(1);
+       return *this;
+    }
+    __rope_iterator& operator+=(difference_type n) {
+       if (n >= 0) {
+           incr(n);
+       } else {
+           decr(-n);
+       }
+       return *this;
+    }
+    __rope_iterator& operator--() {
+       decr(1);
+       return *this;
+    }
+    __rope_iterator& operator-=(difference_type n) {
+       if (n >= 0) {
+           decr(n);
+       } else {
+           incr(-n);
+       }
+       return *this;
+    }
+    __rope_iterator operator++(int) {
+       size_t old_pos = current_pos;
+       incr(1);
+       return __rope_iterator<charT,Alloc>(root_rope, old_pos);
+    }
+    __rope_iterator operator--(int) {
+       size_t old_pos = current_pos;
+       decr(1);
+       return __rope_iterator<charT,Alloc>(root_rope, old_pos);
+    }
+    reference operator[](ptrdiff_t n) {
+       return __rope_charT_ref_proxy<charT,Alloc>(root_rope, current_pos + n);
+    }
+    friend bool operator== __STL_NULL_TMPL_ARGS
+       (const __rope_iterator<charT,Alloc> & x,
+        const __rope_iterator<charT,Alloc> & y);
+    friend bool operator< __STL_NULL_TMPL_ARGS
+       (const __rope_iterator<charT,Alloc> & x,
+        const __rope_iterator<charT,Alloc> & y);
+    friend ptrdiff_t operator- __STL_NULL_TMPL_ARGS
+       (const __rope_iterator<charT,Alloc> & x,
+        const __rope_iterator<charT,Alloc> & y);
+    friend __rope_iterator<charT,Alloc> operator- __STL_NULL_TMPL_ARGS
+       (const __rope_iterator<charT,Alloc> & x,
+        ptrdiff_t n);
+    friend __rope_iterator<charT,Alloc> operator+ __STL_NULL_TMPL_ARGS
+       (const __rope_iterator<charT,Alloc> & x,
+        ptrdiff_t n);
+    friend __rope_iterator<charT,Alloc> operator+ __STL_NULL_TMPL_ARGS
+       (ptrdiff_t n,
+        const __rope_iterator<charT,Alloc> & x);
+
+};
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1375
+#endif
+
+template <class charT, class Alloc>
+class rope {
+    public:
+       typedef charT value_type;
+       typedef ptrdiff_t difference_type;
+       typedef size_t size_type;
+       typedef charT const_reference;
+       typedef const charT* const_pointer;
+       typedef __rope_iterator<charT,Alloc> iterator;
+       typedef __rope_const_iterator<charT,Alloc> const_iterator;
+       typedef __rope_charT_ref_proxy<charT,Alloc> reference;
+       typedef __rope_charT_ptr_proxy<charT,Alloc> pointer;
+
+       friend class __rope_iterator<charT,Alloc>;
+       friend class __rope_const_iterator<charT,Alloc>;
+       friend struct __rope_RopeBase<charT,Alloc>;
+       friend class __rope_iterator_base<charT,Alloc>;
+       friend class __rope_charT_ptr_proxy<charT,Alloc>;
+       friend class __rope_charT_ref_proxy<charT,Alloc>;
+       friend struct __rope_RopeSubstring<charT,Alloc>;
+
+    protected:
+       typedef __GC_CONST charT * cstrptr;
+#       ifdef __STL_SGI_THREADS
+           static cstrptr atomic_swap(cstrptr *p, cstrptr q) {
+#               if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64))
+                    return (cstrptr) test_and_set((unsigned long *)p,
+                                                 (unsigned long)q);
+#              else
+                    return (cstrptr) __test_and_set((unsigned long *)p,
+                                                   (unsigned long)q);
+#              endif
+            }
+#       elif defined(__STL_WIN32THREADS)
+           static cstrptr atomic_swap(cstrptr *p, cstrptr q) {
+               return (cstrptr) InterlockedExchange((LPLONG)p, (LONG)q);
+           }
+#      elif defined(_PTHREADS)
+           // This should be portable, but performance is expected
+           // to be quite awful.  This really needs platform specific
+           // code.
+           static pthread_mutex_t swap_lock;
+           static cstrptr atomic_swap(cstrptr *p, cstrptr q) {
+               pthread_mutex_lock(&swap_lock);
+               cstrptr result = *p;
+               *p = q;
+               pthread_mutex_unlock(&swap_lock);
+               return result;
+            }
+#      else
+           static cstrptr atomic_swap(cstrptr *p, cstrptr q) {
+                cstrptr result = *p;
+                *p = q;
+               return result;
+           }
+#       endif
+
+       static charT empty_c_str[1];
+
+       typedef simple_alloc<charT, Alloc> DataAlloc;
+       typedef simple_alloc<__rope_RopeConcatenation<charT,Alloc>, Alloc> CAlloc;
+       typedef simple_alloc<__rope_RopeLeaf<charT,Alloc>, Alloc> LAlloc;
+       typedef simple_alloc<__rope_RopeFunction<charT,Alloc>, Alloc> FAlloc;
+       typedef simple_alloc<__rope_RopeSubstring<charT,Alloc>, Alloc> SAlloc;
+       static bool is0(charT c) { return c == __eos((charT *)0); }
+       enum { copy_max = 23 };
+               // For strings shorter than copy_max, we copy to
+               // concatenate.
+
+       typedef __rope_RopeBase<charT,Alloc> RopeBase;
+       typedef __rope_RopeConcatenation<charT,Alloc> RopeConcatenation;
+       typedef __rope_RopeLeaf<charT,Alloc> RopeLeaf;
+       typedef __rope_RopeFunction<charT,Alloc> RopeFunction;
+       typedef __rope_RopeSubstring<charT,Alloc> RopeSubstring;
+
+       // The only data member of a rope:
+       RopeBase *tree_ptr;
+
+       // Retrieve a character at the indicated position.
+       static charT fetch(RopeBase * r, size_type pos);
+
+#      ifndef __GC
+           // Obtain a pointer to the character at the indicated position.
+           // The pointer can be used to change the character.
+           // If such a pointer cannot be produced, as is frequently the
+           // case, 0 is returned instead.
+           // (Returns nonzero only if all nodes in the path have a refcount
+           // of 1.)
+           static charT * fetch_ptr(RopeBase * r, size_type pos);
+#      endif
+
+       static bool apply_to_pieces(
+                               // should be template parameter
+                               __rope_char_consumer<charT>& c,
+                               const RopeBase * r,
+                               size_t begin, size_t end);
+                               // begin and end are assumed to be in range.
+
+#      ifndef __GC
+         static void unref(RopeBase* t)
+         {
+             RopeBase::unref(t);
+         }
+         static void ref(RopeBase* t)
+         {
+             RopeBase::ref(t);
+         }
+#       else /* __GC */
+         static void unref(RopeBase* t) {}
+         static void ref(RopeBase* t) {}
+#       endif
+
+
+#       ifdef __GC
+           typedef __rope_RopeBase<charT,Alloc> * self_destruct_ptr;
+#      else
+           typedef __rope_self_destruct_ptr<charT,Alloc> self_destruct_ptr;
+#      endif
+
+       // Result is counted in refcount.
+       static RopeBase * substring(RopeBase * base,
+                                   size_t start, size_t endp1);
+
+       static RopeBase * concat_char_iter(RopeBase * r,
+                                         const charT *iter, size_t slen);
+               // Concatenate rope and char ptr, copying s.
+               // Should really take an arbitrary iterator.
+               // Result is counted in refcount.
+       static RopeBase * destr_concat_char_iter(RopeBase * r,
+                                                const charT *iter, size_t slen)
+               // As above, but one reference to r is about to be
+               // destroyed.  Thus the pieces may be recycled if all
+               // relevent reference counts are 1.
+#          ifdef __GC
+               // We can't really do anything since refcounts are unavailable.
+               { return concat_char_iter(r, iter, slen); }
+#          else
+               ;
+#          endif
+
+       static RopeBase * concat(RopeBase *left, RopeBase *right);
+               // General concatenation on RopeBase.  Result
+               // has refcount of 1.  Adjusts argument refcounts.
+
+   public:
+       void apply_to_pieces( size_t begin, size_t end,
+                             __rope_char_consumer<charT>& c) const {
+           apply_to_pieces(c, tree_ptr, begin, end);
+       }
+
+
+   protected:
+
+       static size_t rounded_up_size(size_t n) {
+           return RopeBase::rounded_up_size(n);
+       }
+
+       static size_t allocated_capacity(size_t n) {
+           if (__is_basic_char_type((charT *)0)) {
+               return rounded_up_size(n) - 1;
+           } else {
+               return rounded_up_size(n);
+           }
+       }
+               
+       // s should really be an arbitrary input iterator.
+       // Adds a trailing NULL for basic char types.
+       static charT * alloc_copy(const charT *s, size_t size)
+       {
+           charT * result = DataAlloc::allocate(rounded_up_size(size));
+
+           uninitialized_copy_n(s, size, result);
+           __cond_store_eos(result[size]);
+           return(result);
+       }
+
+       // Basic constructors for rope tree nodes.
+       // These return tree nodes with a 0 reference count.
+       static RopeLeaf * RopeLeaf_from_char_ptr(__GC_CONST charT *s,
+                                                size_t size);
+               // Takes ownership of its argument.
+               // Result has refcount 1.
+               // In the nonGC, basic_char_type  case it assumes that s
+               // is eos-terminated.
+               // In the nonGC case, it was allocated from Alloc with
+               // rounded_up_size(size).
+
+       static RopeLeaf * RopeLeaf_from_unowned_char_ptr(const charT *s,
+                                                        size_t size) {
+           charT * buf = alloc_copy(s, size);
+            __STL_TRY {
+              return RopeLeaf_from_char_ptr(buf, size);
+            }
+            __STL_UNWIND(RopeBase::free_string(buf, size))
+       }
+           
+
+       // Concatenation of nonempty strings.
+       // Always builds a concatenation node.
+       // Rebalances if the result is too deep.
+       // Result has refcount 1.
+       // Does not increment left and right ref counts even though
+       // they are referenced.
+       static RopeBase * tree_concat(RopeBase * left, RopeBase * right);
+
+       // Result has refcount 1.
+       // If delete_fn is true, then fn is deleted when the rope
+       // becomes inaccessible.
+       static RopeFunction * RopeFunction_from_fn
+                       (char_producer<charT> *fn, size_t size,
+                        bool delete_fn);
+
+       // Concatenation helper functions
+       static RopeLeaf * leaf_concat_char_iter
+                       (RopeLeaf * r, const charT * iter, size_t slen);
+               // Concatenate by copying leaf.
+               // should take an arbitrary iterator
+               // result has refcount 1.
+#      ifndef __GC
+         static RopeLeaf * destr_leaf_concat_char_iter
+                       (RopeLeaf * r, const charT * iter, size_t slen);
+         // A version that potentially clobbers r if r -> refcount == 1.
+#       endif
+
+       // A helper function for exponentiating strings.
+       // This uses a nonstandard refcount convention.
+       // The result has refcount 0.
+       struct concat_fn;
+       friend struct rope<charT,Alloc>::concat_fn;
+
+       struct concat_fn
+               : public binary_function<rope<charT,Alloc>, rope<charT,Alloc>,
+                                        rope<charT,Alloc> > {
+               rope operator() (const rope& x, const rope& y) {
+                   return x + y;
+               }
+       };
+
+        friend rope identity_element(concat_fn) { return rope<charT,Alloc>(); }
+
+       static size_t char_ptr_len(const charT * s);
+                       // slightly generalized strlen
+
+       rope(RopeBase *t) : tree_ptr(t) { }
+
+
+       // Copy r to the CharT buffer.
+       // Returns buffer + r -> size.
+       // Assumes that buffer is uninitialized.
+       static charT * flatten(RopeBase * r, charT * buffer);
+
+       // Again, with explicit starting position and length.
+       // Assumes that buffer is uninitialized.
+       static charT * flatten(RopeBase * r,
+                              size_t start, size_t len,
+                              charT * buffer);
+
+       static const unsigned long min_len[RopeBase::max_rope_depth + 1];
+
+       static bool is_balanced(RopeBase *r)
+               { return (r -> size >= min_len[r -> depth]); }
+
+       static bool is_almost_balanced(RopeBase *r)
+               { return (r -> depth == 0 ||
+                         r -> size >= min_len[r -> depth - 1]); }
+
+       static bool is_roughly_balanced(RopeBase *r)
+               { return (r -> depth <= 1 ||
+                         r -> size >= min_len[r -> depth - 2]); }
+
+       // Assumes the result is not empty.
+       static RopeBase * concat_and_set_balanced(RopeBase *left,
+                                                 RopeBase *right)
+       {
+           RopeBase * result = concat(left, right);
+           if (is_balanced(result)) result -> is_balanced = true;
+           return result;
+       }
+
+       // The basic rebalancing operation.  Logically copies the
+       // rope.  The result has refcount of 1.  The client will
+       // usually decrement the reference count of r.
+       // The result isd within height 2 of balanced by the above
+       // definition.
+       static RopeBase * balance(RopeBase * r);
+
+       // Add all unbalanced subtrees to the forest of balanceed trees.
+       // Used only by balance.
+       static void add_to_forest(RopeBase *r, RopeBase **forest);
+       
+       // Add r to forest, assuming r is already balanced.
+       static void add_leaf_to_forest(RopeBase *r, RopeBase **forest);
+
+       // Print to stdout, exposing structure
+       static void dump(RopeBase * r, int indent = 0);
+
+       // Return -1, 0, or 1 if x < y, x == y, or x > y resp.
+       static int compare(const RopeBase *x, const RopeBase *y);
+
+   public:
+       bool empty() const { return 0 == tree_ptr; }
+
+       // Comparison member function.  This is public only for those
+       // clients that need a ternary comparison.  Others
+       // should use the comparison operators below.
+       int compare(const rope &y) const {
+           return compare(tree_ptr, y.tree_ptr);
+       }
+
+       rope(const charT *s)
+       {
+           size_t len = char_ptr_len(s);
+
+           if (0 == len) {
+               tree_ptr = 0;
+           } else {
+               tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len);
+#              ifndef __GC
+                 __stl_assert(1 == tree_ptr -> refcount);
+#              endif
+           }
+       }
+
+       rope(const charT *s, size_t len)
+       {
+           if (0 == len) {
+               tree_ptr = 0;
+           } else {
+               tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len);
+           }
+       }
+
+       rope(const charT *s, charT *e)
+       {
+           size_t len = e - s;
+
+           if (0 == len) {
+               tree_ptr = 0;
+           } else {
+               tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len);
+           }
+       }
+
+       rope(const const_iterator& s, const const_iterator& e)
+       {
+           tree_ptr = substring(s.root, s.current_pos, e.current_pos);
+       }
+
+       rope(const iterator& s, const iterator& e)
+       {
+           tree_ptr = substring(s.root, s.current_pos, e.current_pos);
+       }
+
+       rope(charT c)
+       {
+           charT * buf = DataAlloc::allocate(rounded_up_size(1));
+
+           construct(buf, c);
+           __STL_TRY {
+               tree_ptr = RopeLeaf_from_char_ptr(buf, 1);
+            }
+            __STL_UNWIND(RopeBase::free_string(buf, 1))
+       }
+
+       rope(size_t n, charT c);
+
+       // Should really be templatized with respect to the iterator type
+       // and use sequence_buffer.  (It should perhaps use sequence_buffer
+       // even now.)
+       rope(const charT *i, const charT *j)
+       {
+           if (i == j) {
+               tree_ptr = 0;
+           } else {
+               size_t len = j - i;
+               tree_ptr = RopeLeaf_from_unowned_char_ptr(i, len);
+           }
+       }
+
+       rope()
+       {
+           tree_ptr = 0;
+       }
+
+       // Construct a rope from a function that can compute its members
+       rope(char_producer<charT> *fn, size_t len, bool delete_fn)
+       {
+           tree_ptr = RopeFunction_from_fn(fn, len, delete_fn);
+       }
+
+       rope(const rope &x)
+       {
+           tree_ptr = x.tree_ptr;
+           ref(tree_ptr);
+       }
+
+       ~rope()
+       {
+           unref(tree_ptr);
+       }
+
+       rope& operator=(const rope& x)
+       {
+           RopeBase *old = tree_ptr;
+           tree_ptr = x.tree_ptr;
+           ref(tree_ptr);
+           unref(old);
+           return(*this);
+       }
+
+       void push_back(charT x)
+       {
+           RopeBase *old = tree_ptr;
+           tree_ptr = concat_char_iter(tree_ptr, &x, 1);
+           unref(old);
+       }
+
+       void pop_back()
+       {
+           RopeBase *old = tree_ptr;
+           tree_ptr = substring(tree_ptr, 0, tree_ptr -> size - 1);
+           unref(old);
+       }
+
+       charT back() const
+       {
+           return fetch(tree_ptr, tree_ptr -> size - 1);
+       }
+
+       void push_front(charT x)
+       {
+           RopeBase *old = tree_ptr;
+           RopeBase *left;
+
+           left = RopeLeaf_from_unowned_char_ptr(&x, 1);
+           __STL_TRY {
+             tree_ptr = concat(left, tree_ptr);
+             unref(old);
+              unref(left);
+            }
+           __STL_UNWIND(unref(left))
+       }
+
+       void pop_front()
+       {
+           RopeBase *old = tree_ptr;
+           tree_ptr = substring(tree_ptr, 1, tree_ptr -> size);
+           unref(old);
+       }
+
+       charT front() const
+       {
+           return fetch(tree_ptr, 0);
+       }
+
+       void balance()
+       {
+           RopeBase *old = tree_ptr;
+           tree_ptr = balance(tree_ptr);
+           unref(old);
+       }
+
+       void copy(charT * buffer) const {
+           destroy(buffer, buffer + size());
+           flatten(tree_ptr, buffer);
+       }
+
+       // This is the copy function from the standard, but
+       // with the arguments reordered to make it consistent with the
+       // rest of the interface.
+       // Note that this guaranteed not to compile if the draft standard
+       // order is assumed.
+       size_type copy(size_type pos, size_type n, charT *buffer) const {
+           size_t sz = size();
+           size_t len = (pos + n > sz? sz - pos : n);
+
+           destroy(buffer, buffer + len);
+           flatten(tree_ptr, pos, len, buffer);
+           return len;
+       }
+
+       // Print to stdout, exposing structure.  May be useful for
+       // performance debugging.
+       void dump() {
+           dump(tree_ptr);
+       }
+
+       // Convert to 0 terminated string in new allocated memory.
+       // Embedded 0s in the input do not terminate the copy.
+       const charT * c_str() const;
+
+       // As above, but lso use the flattened representation as the
+       // the new rope representation.
+       const charT * replace_with_c_str();
+
+       // Reclaim memory for the c_str generated flattened string.
+       // Intentionally undocumented, since it's hard to say when this
+       // is safe for multiple threads.
+       void delete_c_str () {
+           if (0 == tree_ptr) return;
+           if (RopeBase::leaf == tree_ptr -> tag
+               && ((RopeLeaf *)tree_ptr) -> data == tree_ptr -> c_string) {
+               // Representation shared
+               return;
+           }
+#          ifndef __GC
+             tree_ptr -> free_c_string();
+#          endif
+           tree_ptr -> c_string = 0;
+       }
+
+       charT operator[] (size_type pos) const {
+           return fetch(tree_ptr, pos);
+       }
+
+       charT at(size_type pos) const {
+          // if (pos >= size()) throw out_of_range;
+          return (*this)[pos];
+       }
+
+       const_iterator begin() const {
+           return(const_iterator(tree_ptr, 0));
+       }
+
+       // An easy way to get a const iterator from a non-const container.
+       const_iterator const_begin() const {
+           return(const_iterator(tree_ptr, 0));
+       }
+
+       const_iterator end() const {
+           return(const_iterator(tree_ptr, size()));
+       }
+
+       const_iterator const_end() const {
+           return(const_iterator(tree_ptr, size()));
+       }
+
+       size_type size() const { 
+           return(0 == tree_ptr? 0 : tree_ptr -> size);
+       }
+
+       size_type length() const {
+           return size();
+       }
+
+       size_type max_size() const {
+           return min_len[RopeBase::max_rope_depth-1] - 1;
+           //  Guarantees that the result can be sufficirntly
+           //  balanced.  Longer ropes will probably still work,
+           //  but it's harder to make guarantees.
+       }
+
+#     ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+        typedef reverse_iterator<const_iterator> const_reverse_iterator;
+#     else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+       typedef reverse_iterator<const_iterator, value_type, const_reference,
+                                difference_type>  const_reverse_iterator;
+#     endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 
+
+       const_reverse_iterator rbegin() const {
+           return const_reverse_iterator(end());
+       }
+
+       const_reverse_iterator const_rbegin() const {
+           return const_reverse_iterator(end());
+       }
+
+       const_reverse_iterator rend() const {
+           return const_reverse_iterator(begin());
+       }
+
+       const_reverse_iterator const_rend() const {
+           return const_reverse_iterator(begin());
+       }
+
+       friend rope<charT,Alloc>
+        operator+ __STL_NULL_TMPL_ARGS (const rope<charT,Alloc> &left,
+                                        const rope<charT,Alloc> &right);
+       
+       friend rope<charT,Alloc>
+        operator+ __STL_NULL_TMPL_ARGS (const rope<charT,Alloc> &left,
+                                        const charT* right);
+       
+       friend rope<charT,Alloc>
+        operator+ __STL_NULL_TMPL_ARGS (const rope<charT,Alloc> &left,
+                                        charT right);
+       
+       // The symmetric cases are intentionally omitted, since they're presumed
+       // to be less common, and we don't handle them as well.
+
+       // The following should really be templatized.
+       // The first argument should be an input iterator or
+       // forward iterator with value_type charT.
+       rope& append(const charT* iter, size_t n) {
+           RopeBase* result = destr_concat_char_iter(tree_ptr, iter, n);
+           unref(tree_ptr);
+           tree_ptr = result;
+           return *this;
+       }
+
+       rope& append(const charT* c_string) {
+           size_t len = char_ptr_len(c_string);
+           append(c_string, len);
+           return(*this);
+       }
+
+       rope& append(const charT* s, const charT* e) {
+           RopeBase* result =
+                       destr_concat_char_iter(tree_ptr, s, e - s);
+           unref(tree_ptr);
+           tree_ptr = result;
+           return *this;
+       }
+
+       rope& append(const_iterator s, const_iterator e) {
+           __stl_assert(s.root == e.root);
+           self_destruct_ptr appendee(substring(s.root, s.current_pos,
+                                                e.current_pos));
+           RopeBase* result = concat(tree_ptr, (RopeBase *)appendee);
+           unref(tree_ptr);
+           tree_ptr = result;
+           return *this;
+       }
+
+       rope& append(charT c) {
+           RopeBase* result = destr_concat_char_iter(tree_ptr, &c, 1);
+           unref(tree_ptr);
+           tree_ptr = result;
+           return *this;
+       }
+
+       rope& append() { return append(charT()); }
+
+       rope& append(const rope& y) {
+           RopeBase* result = concat(tree_ptr, y.tree_ptr);
+           unref(tree_ptr);
+           tree_ptr = result;
+           return *this;
+       }
+
+       rope& append(size_t n, charT c) {
+           rope<charT,Alloc> last(n, c);
+           return append(last);
+       }
+
+       void swap(rope& b) {
+           RopeBase * tmp = tree_ptr;
+           tree_ptr = b.tree_ptr;
+           b.tree_ptr = tmp;
+       }
+
+
+    protected:
+       // Result is included in refcount.
+       static RopeBase * replace(RopeBase *old, size_t pos1,
+                                 size_t pos2, RopeBase *r) {
+           if (0 == old) { ref(r); return r; }
+           self_destruct_ptr left(substring(old, 0, pos1));
+           self_destruct_ptr right(substring(old, pos2, old -> size));
+           RopeBase * result;
+
+           if (0 == r) {
+               result = concat(left, right);
+           } else {
+               self_destruct_ptr left_result(concat(left, r));
+               result = concat(left_result, right);
+           }
+           return result;
+       }
+
+    public:
+       void insert(size_t p, const rope& r) {
+           RopeBase * result = replace(tree_ptr, p, p,
+                                              r.tree_ptr);
+           unref(tree_ptr);
+           tree_ptr = result;
+       }
+
+       void insert(size_t p, size_t n, charT c) {
+           rope<charT,Alloc> r(n,c);
+           insert(p, r);
+       }
+
+       void insert(size_t p, const charT * i, size_t n) {
+           self_destruct_ptr left(substring(tree_ptr, 0, p));
+           self_destruct_ptr right(substring(tree_ptr, p, size()));
+           self_destruct_ptr left_result(concat_char_iter(left, i, n));
+           RopeBase * result =
+                               concat(left_result, right);
+           unref(tree_ptr);
+           tree_ptr = result;
+       }
+
+       void insert(size_t p, const charT * c_string) {
+           insert(p, c_string, char_ptr_len(c_string));
+       }
+
+       void insert(size_t p, charT c) {
+           insert(p, &c, 1);
+       }
+
+       void insert(size_t p) {
+           charT c = charT();
+           insert(p, &c, 1);
+       }
+
+       void insert(size_t p, const charT *i, const charT *j) {
+           rope r(i, j);
+           insert(p, r);
+       }
+
+       void insert(size_t p, const const_iterator& i,
+                             const const_iterator& j) {
+           rope r(i, j);
+           insert(p, r);
+       }
+
+       void insert(size_t p, const iterator& i,
+                             const iterator& j) {
+           rope r(i, j);
+           insert(p, r);
+       }
+
+       // (position, length) versions of replace operations:
+
+       void replace(size_t p, size_t n, const rope& r) {
+           RopeBase * result = replace(tree_ptr, p, p + n,
+                                              r.tree_ptr);
+           unref(tree_ptr);
+           tree_ptr = result;
+       }
+
+       void replace(size_t p, size_t n, const charT *i, size_t i_len) {
+           rope r(i, i_len);
+           replace(p, n, r);
+       }
+
+       void replace(size_t p, size_t n, charT c) {
+           rope r(c);
+           replace(p, n, r);
+       }
+
+       void replace(size_t p, size_t n, const charT *c_string) {
+           rope r(c_string);
+           replace(p, n, r);
+       }
+
+       void replace(size_t p, size_t n, const charT *i, const charT *j) {
+           rope r(i, j);
+           replace(p, n, r);
+       }
+
+       void replace(size_t p, size_t n,
+                    const const_iterator& i, const const_iterator& j) {
+           rope r(i, j);
+           replace(p, n, r);
+       }
+
+       void replace(size_t p, size_t n,
+                    const iterator& i, const iterator& j) {
+           rope r(i, j);
+           replace(p, n, r);
+       }
+
+       // Single character variants:
+       void replace(size_t p, charT c) {
+           iterator i(this, p);
+           *i = c;
+       }
+
+       void replace(size_t p, const rope& r) {
+           replace(p, 1, r);
+       }
+
+       void replace(size_t p, const charT *i, size_t i_len) {
+           replace(p, 1, i, i_len);
+       }
+
+       void replace(size_t p, const charT *c_string) {
+           replace(p, 1, c_string);
+       }
+
+       void replace(size_t p, const charT *i, const charT *j) {
+           replace(p, 1, i, j);
+       }
+
+       void replace(size_t p, const const_iterator& i,
+                              const const_iterator& j) {
+           replace(p, 1, i, j);
+       }
+
+       void replace(size_t p, const iterator& i,
+                              const iterator& j) {
+           replace(p, 1, i, j);
+       }
+
+       // Erase, (position, size) variant.
+       void erase(size_t p, size_t n) {
+           RopeBase * result = replace(tree_ptr, p, p + n, 0);
+           unref(tree_ptr);
+           tree_ptr = result;
+       }
+
+       // Erase, single character
+       void erase(size_t p) {
+           erase(p, p + 1);
+       }
+
+       // Insert, iterator variants.  
+       iterator insert(const iterator& p, const rope& r)
+               { insert(p.index(), r); return p; }
+       iterator insert(const iterator& p, size_t n, charT c)
+               { insert(p.index(), n, c); return p; }
+       iterator insert(const iterator& p, charT c) 
+               { insert(p.index(), c); return p; }
+       iterator insert(const iterator& p ) 
+               { insert(p.index()); return p; }
+       iterator insert(const iterator& p, const charT *c_string) 
+               { insert(p.index(), c_string); return p; }
+       iterator insert(const iterator& p, const charT *i, size_t n)
+               { insert(p.index(), i, n); return p; }
+       iterator insert(const iterator& p, const charT *i, const charT *j)
+               { insert(p.index(), i, j);  return p; }
+       iterator insert(const iterator& p,
+                       const const_iterator& i, const const_iterator& j)
+               { insert(p.index(), i, j); return p; }
+       iterator insert(const iterator& p,
+                       const iterator& i, const iterator& j)
+               { insert(p.index(), i, j); return p; }
+
+       // Replace, range variants.
+       void replace(const iterator& p, const iterator& q,
+                    const rope& r)
+               { replace(p.index(), q.index() - p.index(), r); }
+       void replace(const iterator& p, const iterator& q, charT c)
+               { replace(p.index(), q.index() - p.index(), c); }
+       void replace(const iterator& p, const iterator& q,
+                    const charT * c_string)
+               { replace(p.index(), q.index() - p.index(), c_string); }
+       void replace(const iterator& p, const iterator& q,
+                    const charT *i, size_t n)
+               { replace(p.index(), q.index() - p.index(), i, n); }
+       void replace(const iterator& p, const iterator& q,
+                    const charT *i, const charT *j)
+               { replace(p.index(), q.index() - p.index(), i, j); }
+       void replace(const iterator& p, const iterator& q,
+                    const const_iterator& i, const const_iterator& j)
+               { replace(p.index(), q.index() - p.index(), i, j); }
+       void replace(const iterator& p, const iterator& q,
+                    const iterator& i, const iterator& j)
+               { replace(p.index(), q.index() - p.index(), i, j); }
+
+       // Replace, iterator variants.
+       void replace(const iterator& p, const rope& r)
+               { replace(p.index(), r); }
+       void replace(const iterator& p, charT c)
+               { replace(p.index(), c); }
+       void replace(const iterator& p, const charT * c_string)
+               { replace(p.index(), c_string); }
+       void replace(const iterator& p, const charT *i, size_t n)
+               { replace(p.index(), i, n); }
+       void replace(const iterator& p, const charT *i, const charT *j)
+               { replace(p.index(), i, j); }
+       void replace(const iterator& p, const_iterator i, const_iterator j)
+               { replace(p.index(), i, j); }
+       void replace(const iterator& p, iterator i, iterator j)
+               { replace(p.index(), i, j); }
+
+       // Iterator and range variants of erase
+       iterator erase(const iterator &p, const iterator &q) {
+            size_t p_index = p.index();
+            erase(p_index, q.index() - p_index);
+            return iterator(this, p_index);
+        }
+        iterator erase(const iterator &p) {
+            size_t p_index = p.index();
+            erase(p_index, 1);
+            return iterator(this, p_index);
+        }
+
+       rope substr(size_t start, size_t len = 1) const {
+           return rope<charT,Alloc>(
+                       substring(tree_ptr, start, start + len));
+       }
+
+       rope substr(iterator start, iterator end) const {
+           return rope<charT,Alloc>(
+                       substring(tree_ptr, start.index(), end.index()));
+       }
+       
+       rope substr(iterator start) const {
+           size_t pos = start.index();
+           return rope<charT,Alloc>(
+                       substring(tree_ptr, pos, pos + 1));
+       }
+       
+       rope substr(const_iterator start, const_iterator end) const {
+           // This might eventually take advantage of the cache in the
+           // iterator.
+           return rope<charT,Alloc>
+               (substring(tree_ptr, start.index(), end.index()));
+       }
+
+       rope<charT,Alloc> substr(const_iterator start) {
+           size_t pos = start.index();
+           return rope<charT,Alloc>(substring(tree_ptr, pos, pos + 1));
+       }
+
+       size_type find(charT c, size_type pos = 0) const;
+       size_type find(charT *s, size_type pos = 0) const {
+           const_iterator result = search(const_begin() + pos, const_end(),
+                                          s, s + char_ptr_len(s));
+           return result.index();
+       }
+
+       iterator mutable_begin() {
+           return(iterator(this, 0));
+       }
+
+       iterator mutable_end() {
+           return(iterator(this, size()));
+       }
+
+#     ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+        typedef reverse_iterator<iterator> reverse_iterator;
+#     else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+       typedef reverse_iterator<iterator, value_type, reference,
+                                difference_type>  reverse_iterator;
+#     endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 
+
+       reverse_iterator mutable_rbegin() {
+           return reverse_iterator(mutable_end());
+       }
+
+       reverse_iterator mutable_rend() {
+           return reverse_iterator(mutable_begin());
+       }
+
+       reference mutable_reference_at(size_type pos) {
+           return reference(this, pos);
+       }
+
+#      ifdef __STD_STUFF
+           reference operator[] (size_type pos) {
+               return charT_ref_proxy(this, pos);
+           }
+
+           reference at(size_type pos) {
+               // if (pos >= size()) throw out_of_range;
+               return (*this)[pos];
+           }
+
+           void resize(size_type n, charT c) {}
+           void resize(size_type n) {}
+           void reserve(size_type res_arg = 0) {}
+           size_type capacity() const {
+               return max_size();
+           }
+
+         // Stuff below this line is dangerous because it's error prone.
+         // I would really like to get rid of it.
+           // copy function with funny arg ordering.
+             size_type copy(charT *buffer, size_type n, size_type pos = 0)
+                                                               const {
+               return copy(pos, n, buffer);
+             }
+
+           iterator end() { return mutable_end(); }
+
+           iterator begin() { return mutable_begin(); }
+
+           reverse_iterator rend() { return mutable_rend(); }
+
+           reverse_iterator rbegin() { return mutable_rbegin(); }
+
+#      else
+
+           const_iterator end() { return const_end(); }
+
+           const_iterator begin() { return const_begin(); }
+
+           const_reverse_iterator rend() { return const_rend(); }
+  
+           const_reverse_iterator rbegin() { return const_rbegin(); }
+
+#      endif
+       
+};
+
+template <class charT, class Alloc>
+inline bool operator== (const __rope_const_iterator<charT,Alloc> & x,
+                       const __rope_const_iterator<charT,Alloc> & y) {
+       return (x.current_pos == y.current_pos && x.root == y.root);
+}
+
+template <class charT, class Alloc>
+inline bool operator< (const __rope_const_iterator<charT,Alloc> & x,
+                      const __rope_const_iterator<charT,Alloc> & y) {
+       return (x.current_pos < y.current_pos);
+}
+
+template <class charT, class Alloc>
+inline ptrdiff_t operator-(const __rope_const_iterator<charT,Alloc> & x,
+                          const __rope_const_iterator<charT,Alloc> & y) {
+       return x.current_pos - y.current_pos;
+}
+
+template <class charT, class Alloc>
+inline __rope_const_iterator<charT,Alloc>
+operator-(const __rope_const_iterator<charT,Alloc> & x,
+         ptrdiff_t n) {
+       return __rope_const_iterator<charT,Alloc>(x.root, x.current_pos - n);
+}
+
+template <class charT, class Alloc>
+inline __rope_const_iterator<charT,Alloc>
+operator+(const __rope_const_iterator<charT,Alloc> & x,
+         ptrdiff_t n) {
+       return __rope_const_iterator<charT,Alloc>(x.root, x.current_pos + n);
+}
+
+template <class charT, class Alloc>
+inline __rope_const_iterator<charT,Alloc>
+operator+(ptrdiff_t n,
+         const __rope_const_iterator<charT,Alloc> & x) {
+       return __rope_const_iterator<charT,Alloc>(x.root, x.current_pos + n);
+}
+
+template <class charT, class Alloc>
+inline bool operator== (const __rope_iterator<charT,Alloc> & x,
+                       const __rope_iterator<charT,Alloc> & y) {
+       return (x.current_pos == y.current_pos && x.root_rope == y.root_rope);
+}
+
+template <class charT, class Alloc>
+inline bool operator< (const __rope_iterator<charT,Alloc> & x,
+                       const __rope_iterator<charT,Alloc> & y) {
+       return (x.current_pos < y.current_pos);
+}
+
+template <class charT, class Alloc>
+inline ptrdiff_t operator-(const __rope_iterator<charT,Alloc> & x,
+                          const __rope_iterator<charT,Alloc> & y) {
+       return x.current_pos - y.current_pos;
+}
+
+template <class charT, class Alloc>
+inline __rope_iterator<charT,Alloc>
+operator-(const __rope_iterator<charT,Alloc> & x,
+         ptrdiff_t n) {
+       return __rope_iterator<charT,Alloc>(x.root_rope, x.current_pos - n);
+}
+
+template <class charT, class Alloc>
+inline __rope_iterator<charT,Alloc>
+operator+(const __rope_iterator<charT,Alloc> & x,
+         ptrdiff_t n) {
+       return __rope_iterator<charT,Alloc>(x.root_rope, x.current_pos + n);
+}
+
+template <class charT, class Alloc>
+inline __rope_iterator<charT,Alloc>
+operator+(ptrdiff_t n,
+         const __rope_iterator<charT,Alloc> & x) {
+       return __rope_iterator<charT,Alloc>(x.root_rope, x.current_pos + n);
+}
+
+template <class charT, class Alloc>
+inline
+rope<charT,Alloc>
+operator+ (const rope<charT,Alloc> &left,
+          const rope<charT,Alloc> &right)
+{
+    return rope<charT,Alloc>
+               (rope<charT,Alloc>::concat(left.tree_ptr, right.tree_ptr));
+    // Inlining this should make it possible to keep left and
+    // right in registers.
+}
+
+template <class charT, class Alloc>
+inline
+rope<charT,Alloc>&
+operator+= (rope<charT,Alloc> &left,
+           const rope<charT,Alloc> &right)
+{
+    left.append(right);
+    return left;
+}
+
+template <class charT, class Alloc>
+inline
+rope<charT,Alloc>
+operator+ (const rope<charT,Alloc> &left,
+          const charT* right) {
+    size_t rlen = rope<charT,Alloc>::char_ptr_len(right);
+    return rope<charT,Alloc>
+          (rope<charT,Alloc>::concat_char_iter(left.tree_ptr, right, rlen)); 
+}
+
+template <class charT, class Alloc>
+inline
+rope<charT,Alloc>&
+operator+= (rope<charT,Alloc> &left,
+           const charT* right) {
+    left.append(right);
+    return left;
+}
+
+template <class charT, class Alloc>
+inline
+rope<charT,Alloc>
+operator+ (const rope<charT,Alloc> &left, charT right) {
+    return rope<charT,Alloc>
+               (rope<charT,Alloc>::concat_char_iter(left.tree_ptr, &right, 1));
+}
+
+template <class charT, class Alloc>
+inline
+rope<charT,Alloc>&
+operator+= (rope<charT,Alloc> &left, charT right) {
+    left.append(right);
+    return left;
+}
+
+template <class charT, class Alloc>
+bool
+operator< (const rope<charT,Alloc> &left, const rope<charT,Alloc> &right) {
+    return left.compare(right) < 0;
+}
+       
+template <class charT, class Alloc>
+bool
+operator== (const rope<charT,Alloc> &left, const rope<charT,Alloc> &right) {
+    return left.compare(right) == 0;
+}
+
+template <class charT, class Alloc>
+inline bool operator== (const __rope_charT_ptr_proxy<charT,Alloc> & x,
+                       const __rope_charT_ptr_proxy<charT,Alloc> & y) {
+       return (x.pos == y.pos && x.root == y.root);
+}
+
+template<class charT, class Alloc>
+ostream& operator<< (ostream& o, const rope<charT, Alloc>& r);        
+       
+typedef rope<char, __ALLOC> crope;
+typedef rope<wchar_t, __ALLOC> wrope;
+
+inline crope::reference __mutable_reference_at(crope& c, size_t i)
+{
+    return c.mutable_reference_at(i);
+}
+
+inline wrope::reference __mutable_reference_at(wrope& c, size_t i)
+{
+    return c.mutable_reference_at(i);
+}
+
+#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
+
+template <class charT, class Alloc>
+inline void swap(rope<charT, Alloc>& x, rope<charT, Alloc>& y) {
+  x.swap(y);
+}
+
+#else
+
+inline void swap(crope x, crope y) { x.swap(y); }
+inline void swap(wrope x, wrope y) { x.swap(y); }
+
+#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
+
+// Hash functions should probably be revisited later:
+__STL_TEMPLATE_NULL struct hash<crope>
+{
+  size_t operator()(const crope& str) const
+  {
+    size_t sz = str.size();
+
+    if (0 == sz) return 0;
+    return 13*str[0] + 5*str[sz - 1] + sz;
+  }
+};
+
+
+__STL_TEMPLATE_NULL struct hash<wrope>
+{
+  size_t operator()(const wrope& str) const
+  {
+    size_t sz = str.size();
+
+    if (0 == sz) return 0;
+    return 13*str[0] + 5*str[sz - 1] + sz;
+  }
+};
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1174
+#endif
+
+__STL_END_NAMESPACE
+
+# include <ropeimpl.h>
+# endif /* __SGI_STL_INTERNAL_ROPE_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_set.h b/libstdc++/stl/stl_set.h
new file mode 100644 (file)
index 0000000..9ffeaa7
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_SET_H
+#define __SGI_STL_INTERNAL_SET_H
+
+__STL_BEGIN_NAMESPACE
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1174
+#endif
+
+#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
+template <class Key, class Compare = less<Key>, class Alloc = alloc>
+#else
+template <class Key, class Compare, class Alloc = alloc>
+#endif
+class set {
+public:
+  // typedefs:
+
+  typedef Key key_type;
+  typedef Key value_type;
+  typedef Compare key_compare;
+  typedef Compare value_compare;
+private:
+  typedef rb_tree<key_type, value_type, 
+                  identity<value_type>, key_compare, Alloc> rep_type;
+  rep_type t;  // red-black tree representing set
+public:
+  typedef typename rep_type::const_pointer pointer;
+  typedef typename rep_type::const_pointer const_pointer;
+  typedef typename rep_type::const_reference reference;
+  typedef typename rep_type::const_reference const_reference;
+  typedef typename rep_type::const_iterator iterator;
+  typedef typename rep_type::const_iterator const_iterator;
+  typedef typename rep_type::const_reverse_iterator reverse_iterator;
+  typedef typename rep_type::const_reverse_iterator const_reverse_iterator;
+  typedef typename rep_type::size_type size_type;
+  typedef typename rep_type::difference_type difference_type;
+
+  // allocation/deallocation
+
+  set() : t(Compare()) {}
+  explicit set(const Compare& comp) : t(comp) {}
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  set(InputIterator first, InputIterator last)
+    : t(Compare()) { t.insert_unique(first, last); }
+
+  template <class InputIterator>
+  set(InputIterator first, InputIterator last, const Compare& comp)
+    : t(comp) { t.insert_unique(first, last); }
+#else
+  set(const value_type* first, const value_type* last) 
+    : t(Compare()) { t.insert_unique(first, last); }
+  set(const value_type* first, const value_type* last, const Compare& comp)
+    : t(comp) { t.insert_unique(first, last); }
+
+  set(const_iterator first, const_iterator last)
+    : t(Compare()) { t.insert_unique(first, last); }
+  set(const_iterator first, const_iterator last, const Compare& comp)
+    : t(comp) { t.insert_unique(first, last); }
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  set(const set<Key, Compare, Alloc>& x) : t(x.t) {}
+  set<Key, Compare, Alloc>& operator=(const set<Key, Compare, Alloc>& x) { 
+    t = x.t; 
+    return *this;
+  }
+
+  // accessors:
+
+  key_compare key_comp() const { return t.key_comp(); }
+  value_compare value_comp() const { return t.key_comp(); }
+  iterator begin() const { return t.begin(); }
+  iterator end() const { return t.end(); }
+  reverse_iterator rbegin() const { return t.rbegin(); } 
+  reverse_iterator rend() const { return t.rend(); }
+  bool empty() const { return t.empty(); }
+  size_type size() const { return t.size(); }
+  size_type max_size() const { return t.max_size(); }
+  void swap(set<Key, Compare, Alloc>& x) { t.swap(x.t); }
+
+  // insert/erase
+  typedef  pair<iterator, bool> pair_iterator_bool; 
+  pair<iterator,bool> insert(const value_type& x) { 
+    pair<typename rep_type::iterator, bool> p = t.insert_unique(x); 
+    return pair<iterator, bool>(p.first, p.second);
+  }
+  iterator insert(iterator position, const value_type& x) {
+    typedef typename rep_type::iterator rep_iterator;
+    return t.insert_unique((rep_iterator&)position, x);
+  }
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  void insert(InputIterator first, InputIterator last) {
+    t.insert_unique(first, last);
+  }
+#else
+  void insert(const_iterator first, const_iterator last) {
+    t.insert_unique(first, last);
+  }
+  void insert(const value_type* first, const value_type* last) {
+    t.insert_unique(first, last);
+  }
+#endif /* __STL_MEMBER_TEMPLATES */
+  void erase(iterator position) { 
+    typedef typename rep_type::iterator rep_iterator;
+    t.erase((rep_iterator&)position); 
+  }
+  size_type erase(const key_type& x) { 
+    return t.erase(x); 
+  }
+  void erase(iterator first, iterator last) { 
+    typedef typename rep_type::iterator rep_iterator;
+    t.erase((rep_iterator&)first, (rep_iterator&)last); 
+  }
+  void clear() { t.clear(); }
+
+  // set operations:
+
+  iterator find(const key_type& x) const { return t.find(x); }
+  size_type count(const key_type& x) const { return t.count(x); }
+  iterator lower_bound(const key_type& x) const {
+    return t.lower_bound(x);
+  }
+  iterator upper_bound(const key_type& x) const {
+    return t.upper_bound(x); 
+  }
+  pair<iterator,iterator> equal_range(const key_type& x) const {
+    return t.equal_range(x);
+  }
+  friend bool operator== __STL_NULL_TMPL_ARGS (const set&, const set&);
+  friend bool operator< __STL_NULL_TMPL_ARGS (const set&, const set&);
+};
+
+template <class Key, class Compare, class Alloc>
+inline bool operator==(const set<Key, Compare, Alloc>& x, 
+                       const set<Key, Compare, Alloc>& y) {
+  return x.t == y.t;
+}
+
+template <class Key, class Compare, class Alloc>
+inline bool operator<(const set<Key, Compare, Alloc>& x, 
+                      const set<Key, Compare, Alloc>& y) {
+  return x.t < y.t;
+}
+
+#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
+
+template <class Key, class Compare, class Alloc>
+inline void swap(set<Key, Compare, Alloc>& x, 
+                 set<Key, Compare, Alloc>& y) {
+  x.swap(y);
+}
+
+#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1174
+#endif
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_SET_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_slist.h b/libstdc++/stl/stl_slist.h
new file mode 100644 (file)
index 0000000..f31ea9e
--- /dev/null
@@ -0,0 +1,740 @@
+/*
+ * Copyright (c) 1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_SLIST_H
+#define __SGI_STL_INTERNAL_SLIST_H
+
+
+__STL_BEGIN_NAMESPACE 
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1174
+#endif
+
+struct __slist_node_base
+{
+  __slist_node_base* next;
+};
+
+inline __slist_node_base* __slist_make_link(__slist_node_base* prev_node,
+                                            __slist_node_base* new_node)
+{
+  new_node->next = prev_node->next;
+  prev_node->next = new_node;
+  return new_node;
+}
+
+inline __slist_node_base* __slist_previous(__slist_node_base* head,
+                                           const __slist_node_base* node)
+{
+  while (head && head->next != node)
+    head = head->next;
+  return head;
+}
+
+inline const __slist_node_base* __slist_previous(const __slist_node_base* head,
+                                                 const __slist_node_base* node)
+{
+  while (head && head->next != node)
+    head = head->next;
+  return head;
+}
+
+inline void __slist_splice_after(__slist_node_base* pos,
+                                 __slist_node_base* before_first,
+                                 __slist_node_base* before_last)
+{
+  if (pos != before_first && pos != before_last) {
+    __slist_node_base* first = before_first->next;
+    __slist_node_base* after = pos->next;
+    before_first->next = before_last->next;
+    pos->next = first;
+    before_last->next = after;
+  }
+}
+
+inline __slist_node_base* __slist_reverse(__slist_node_base* node)
+{
+  __slist_node_base* result = node;
+  node = node->next;
+  result->next = 0;
+  while(node) {
+    __slist_node_base* next = node->next;
+    node->next = result;
+    result = node;
+    node = next;
+  }
+  return result;
+}
+
+template <class T>
+struct __slist_node : public __slist_node_base
+{
+  T data;
+};
+
+struct __slist_iterator_base
+{
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+  typedef forward_iterator_tag iterator_category;
+
+  __slist_node_base* node;
+
+  __slist_iterator_base(__slist_node_base* x) : node(x) {}
+  void incr() { node = node->next; }
+
+  bool operator==(const __slist_iterator_base& x) const {
+    return node == x.node;
+  }
+  bool operator!=(const __slist_iterator_base& x) const {
+    return node != x.node;
+  }
+};
+
+template <class T, class Ref, class Ptr>
+struct __slist_iterator : public __slist_iterator_base
+{
+  typedef __slist_iterator<T, T&, T*>             iterator;
+  typedef __slist_iterator<T, const T&, const T*> const_iterator;
+  typedef __slist_iterator<T, Ref, Ptr>           self;
+
+  typedef T value_type;
+  typedef Ptr pointer;
+  typedef Ref reference;
+  typedef __slist_node<T> list_node;
+
+  __slist_iterator(list_node* x) : __slist_iterator_base(x) {}
+  __slist_iterator() : __slist_iterator_base(0) {}
+  __slist_iterator(const iterator& x) : __slist_iterator_base(x.node) {}
+
+  reference operator*() const { return ((list_node*) node)->data; }
+#ifndef __SGI_STL_NO_ARROW_OPERATOR
+  pointer operator->() const { return &(operator*()); }
+#endif /* __SGI_STL_NO_ARROW_OPERATOR */
+
+  self& operator++()
+  {
+    incr();
+    return *this;
+  }
+  self operator++(int)
+  {
+    self tmp = *this;
+    incr();
+    return tmp;
+  }
+};
+
+#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+inline ptrdiff_t*
+distance_type(const __slist_iterator_base&)
+{
+  return 0;
+}
+
+inline forward_iterator_tag
+iterator_category(const __slist_iterator_base&)
+{
+  return forward_iterator_tag();
+}
+
+template <class T, class Ref, class Ptr> 
+inline T* 
+value_type(const __slist_iterator<T, Ref, Ptr>&) {
+  return 0;
+}
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+inline size_t __slist_size(__slist_node_base* node)
+{
+  size_t result = 0;
+  for ( ; node != 0; node = node->next)
+    ++result;
+  return result;
+}
+
+template <class T, class Alloc = alloc>
+class slist
+{
+public:
+  typedef T value_type;
+  typedef value_type* pointer;
+  typedef const value_type* const_pointer;
+  typedef value_type& reference;
+  typedef const value_type& const_reference;
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+
+  typedef __slist_iterator<T, T&, T*>             iterator;
+  typedef __slist_iterator<T, const T&, const T*> const_iterator;
+
+private:
+  typedef __slist_node<T> list_node;
+  typedef __slist_node_base list_node_base;
+  typedef __slist_iterator_base iterator_base;
+  typedef simple_alloc<list_node, Alloc> list_node_allocator;
+
+  static list_node* create_node(const value_type& x) {
+    list_node* node = list_node_allocator::allocate();
+    __STL_TRY {
+      construct(&node->data, x);
+      node->next = 0;
+    }
+    __STL_UNWIND(list_node_allocator::deallocate(node));
+    return node;
+  }
+  
+  static void destroy_node(list_node* node) {
+    destroy(&node->data);
+    list_node_allocator::deallocate(node);
+  }
+
+  void fill_initialize(size_type n, const value_type& x) {
+    head.next = 0;
+    __STL_TRY {
+      _insert_after_fill(&head, n, x);
+    }
+    __STL_UNWIND(clear());
+  }    
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  void range_initialize(InputIterator first, InputIterator last) {
+    head.next = 0;
+    __STL_TRY {
+      _insert_after_range(&head, first, last);
+    }
+    __STL_UNWIND(clear());
+  }
+#else /* __STL_MEMBER_TEMPLATES */
+  void range_initialize(const value_type* first, const value_type* last) {
+    head.next = 0;
+    __STL_TRY {
+      _insert_after_range(&head, first, last);
+    }
+    __STL_UNWIND(clear());
+  }
+  void range_initialize(const_iterator first, const_iterator last) {
+    head.next = 0;
+    __STL_TRY {
+      _insert_after_range(&head, first, last);
+    }
+    __STL_UNWIND(clear());
+  }
+#endif /* __STL_MEMBER_TEMPLATES */
+
+private:
+  list_node_base head;
+
+public:
+  slist() { head.next = 0; }
+
+  slist(size_type n, const value_type& x) { fill_initialize(n, x); }
+  slist(int n, const value_type& x) { fill_initialize(n, x); }
+  slist(long n, const value_type& x) { fill_initialize(n, x); }
+  explicit slist(size_type n) { fill_initialize(n, value_type()); }
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  slist(InputIterator first, InputIterator last) {
+    range_initialize(first, last);
+  }
+
+#else /* __STL_MEMBER_TEMPLATES */
+  slist(const_iterator first, const_iterator last) {
+    range_initialize(first, last);
+  }
+  slist(const value_type* first, const value_type* last) {
+    range_initialize(first, last);
+  }
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  slist(const slist& L) { range_initialize(L.begin(), L.end()); }
+
+  slist& operator= (const slist& L);
+
+  ~slist() { clear(); }
+
+public:
+
+  iterator begin() { return iterator((list_node*)head.next); }
+  const_iterator begin() const { return const_iterator((list_node*)head.next);}
+
+  iterator end() { return iterator(0); }
+  const_iterator end() const { return const_iterator(0); }
+
+  size_type size() const { return __slist_size(head.next); }
+  
+  size_type max_size() const { return size_type(-1); }
+
+  bool empty() const { return head.next == 0; }
+
+  void swap(slist& L)
+  {
+    list_node_base* tmp = head.next;
+    head.next = L.head.next;
+    L.head.next = tmp;
+  }
+
+public:
+  friend bool operator== __STL_NULL_TMPL_ARGS(const slist<T, Alloc>& L1,
+                                              const slist<T, Alloc>& L2);
+
+public:
+
+  reference front() { return ((list_node*) head.next)->data; }
+  const_reference front() const { return ((list_node*) head.next)->data; }
+  void push_front(const value_type& x)   {
+    __slist_make_link(&head, create_node(x));
+  }
+  void pop_front() {
+    list_node* node = (list_node*) head.next;
+    head.next = node->next;
+    destroy_node(node);
+  }
+
+  iterator previous(const_iterator pos) {
+    return iterator((list_node*) __slist_previous(&head, pos.node));
+  }
+  const_iterator previous(const_iterator pos) const {
+    return const_iterator((list_node*) __slist_previous(&head, pos.node));
+  }
+
+private:
+  list_node* _insert_after(list_node_base* pos, const value_type& x) {
+    return (list_node*) (__slist_make_link(pos, create_node(x)));
+  }
+
+  void _insert_after_fill(list_node_base* pos,
+                          size_type n, const value_type& x) {
+    for (size_type i = 0; i < n; ++i)
+      pos = __slist_make_link(pos, create_node(x));
+  }
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InIter>
+  void _insert_after_range(list_node_base* pos, InIter first, InIter last) {
+    while (first != last) {
+      pos = __slist_make_link(pos, create_node(*first));
+      ++first;
+    }
+  }
+#else /* __STL_MEMBER_TEMPLATES */
+  void _insert_after_range(list_node_base* pos,
+                           const_iterator first, const_iterator last) {
+    while (first != last) {
+      pos = __slist_make_link(pos, create_node(*first));
+      ++first;
+    }
+  }
+  void _insert_after_range(list_node_base* pos,
+                           const value_type* first, const value_type* last) {
+    while (first != last) {
+      pos = __slist_make_link(pos, create_node(*first));
+      ++first;
+    }
+  }
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  list_node_base* erase_after(list_node_base* pos) {
+    list_node* next = (list_node*) (pos->next);
+    list_node_base* next_next = next->next;
+    pos->next = next_next;
+    destroy_node(next);
+    return next_next;
+  }
+   
+  list_node_base* erase_after(list_node_base* before_first,
+                              list_node_base* last_node) {
+    list_node* cur = (list_node*) (before_first->next);
+    while (cur != last_node) {
+      list_node* tmp = cur;
+      cur = (list_node*) cur->next;
+      destroy_node(tmp);
+    }
+    before_first->next = last_node;
+    return last_node;
+  }
+
+
+public:
+
+  iterator insert_after(iterator pos, const value_type& x) {
+    return iterator(_insert_after(pos.node, x));
+  }
+
+  iterator insert_after(iterator pos) {
+    return insert_after(pos, value_type());
+  }
+
+  void insert_after(iterator pos, size_type n, const value_type& x) {
+    _insert_after_fill(pos.node, n, x);
+  }
+  void insert_after(iterator pos, int n, const value_type& x) {
+    _insert_after_fill(pos.node, (size_type) n, x);
+  }
+  void insert_after(iterator pos, long n, const value_type& x) {
+    _insert_after_fill(pos.node, (size_type) n, x);
+  }
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InIter>
+  void insert_after(iterator pos, InIter first, InIter last) {
+    _insert_after_range(pos.node, first, last);
+  }
+#else /* __STL_MEMBER_TEMPLATES */
+  void insert_after(iterator pos, const_iterator first, const_iterator last) {
+    _insert_after_range(pos.node, first, last);
+  }
+  void insert_after(iterator pos,
+                    const value_type* first, const value_type* last) {
+    _insert_after_range(pos.node, first, last);
+  }
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  iterator insert(iterator pos, const value_type& x) {
+    return iterator(_insert_after(__slist_previous(&head, pos.node), x));
+  }
+
+  iterator insert(iterator pos) {
+    return iterator(_insert_after(__slist_previous(&head, pos.node),
+                                  value_type()));
+  }
+
+  void insert(iterator pos, size_type n, const value_type& x) {
+    _insert_after_fill(__slist_previous(&head, pos.node), n, x);
+  } 
+  void insert(iterator pos, int n, const value_type& x) {
+    _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x);
+  } 
+  void insert(iterator pos, long n, const value_type& x) {
+    _insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x);
+  } 
+    
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InIter>
+  void insert(iterator pos, InIter first, InIter last) {
+    _insert_after_range(__slist_previous(&head, pos.node), first, last);
+  }
+#else /* __STL_MEMBER_TEMPLATES */
+  void insert(iterator pos, const_iterator first, const_iterator last) {
+    _insert_after_range(__slist_previous(&head, pos.node), first, last);
+  }
+  void insert(iterator pos, const value_type* first, const value_type* last) {
+    _insert_after_range(__slist_previous(&head, pos.node), first, last);
+  }
+#endif /* __STL_MEMBER_TEMPLATES */
+
+
+public:
+  iterator erase_after(iterator pos) {
+    return iterator((list_node*)erase_after(pos.node));
+  }
+  iterator erase_after(iterator before_first, iterator last) {
+    return iterator((list_node*)erase_after(before_first.node, last.node));
+  }
+
+  iterator erase(iterator pos) {
+    return (list_node*) erase_after(__slist_previous(&head, pos.node));
+  }
+  iterator erase(iterator first, iterator last) {
+    return (list_node*) erase_after(__slist_previous(&head, first.node),
+                                    last.node);
+  }
+
+  void resize(size_type new_size, const T& x);
+  void resize(size_type new_size) { resize(new_size, T()); }
+  void clear() { erase_after(&head, 0); }
+
+public:
+  // Moves the range [before_first + 1, before_last + 1) to *this,
+  //  inserting it immediately after pos.  This is constant time.
+  void splice_after(iterator pos, 
+                    iterator before_first, iterator before_last)
+  {
+    if (before_first != before_last) 
+      __slist_splice_after(pos.node, before_first.node, before_last.node);
+  }
+
+  // Moves the element that follows prev to *this, inserting it immediately
+  //  after pos.  This is constant time.
+  void splice_after(iterator pos, iterator prev)
+  {
+    __slist_splice_after(pos.node, prev.node, prev.node->next);
+  }
+
+
+  // Linear in distance(begin(), pos), and linear in L.size().
+  void splice(iterator pos, slist& L) {
+    if (L.head.next)
+      __slist_splice_after(__slist_previous(&head, pos.node),
+                           &L.head,
+                           __slist_previous(&L.head, 0));
+  }
+
+  // Linear in distance(begin(), pos), and in distance(L.begin(), i).
+  void splice(iterator pos, slist& L, iterator i) {
+    __slist_splice_after(__slist_previous(&head, pos.node),
+                         __slist_previous(&L.head, i.node),
+                         i.node);
+  }
+
+  // Linear in distance(begin(), pos), in distance(L.begin(), first),
+  // and in distance(first, last).
+  void splice(iterator pos, slist& L, iterator first, iterator last)
+  {
+    if (first != last)
+      __slist_splice_after(__slist_previous(&head, pos.node),
+                           __slist_previous(&L.head, first.node),
+                           __slist_previous(first.node, last.node));
+  }
+
+public:
+  void reverse() { if (head.next) head.next = __slist_reverse(head.next); }
+
+  void remove(const T& val); 
+  void unique(); 
+  void merge(slist& L);
+  void sort();     
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class Predicate> void remove_if(Predicate pred);
+  template <class BinaryPredicate> void unique(BinaryPredicate pred); 
+  template <class StrictWeakOrdering> void merge(slist&, StrictWeakOrdering); 
+  template <class StrictWeakOrdering> void sort(StrictWeakOrdering comp); 
+#endif /* __STL_MEMBER_TEMPLATES */
+};
+
+template <class T, class Alloc>
+slist<T, Alloc>& slist<T,Alloc>::operator=(const slist<T, Alloc>& L)
+{
+  if (&L != this) {
+    list_node_base* p1 = &head;
+    list_node* n1 = (list_node*) head.next;
+    const list_node* n2 = (const list_node*) L.head.next;
+    while (n1 && n2) {
+      n1->data = n2->data;
+      p1 = n1;
+      n1 = (list_node*) n1->next;
+      n2 = (const list_node*) n2->next;
+    }
+    if (n2 == 0)
+      erase_after(p1, 0);
+    else
+      _insert_after_range(p1,
+                          const_iterator((list_node*)n2), const_iterator(0));
+  }
+  return *this;
+} 
+
+template <class T, class Alloc>
+bool operator==(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2)
+{
+  typedef typename slist<T,Alloc>::list_node list_node;
+  list_node* n1 = (list_node*) L1.head.next;
+  list_node* n2 = (list_node*) L2.head.next;
+  while (n1 && n2 && n1->data == n2->data) {
+    n1 = (list_node*) n1->next;
+    n2 = (list_node*) n2->next;
+  }
+  return n1 == 0 && n2 == 0;
+}
+
+template <class T, class Alloc>
+inline bool operator<(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2)
+{
+  return lexicographical_compare(L1.begin(), L1.end(), L2.begin(), L2.end());
+}
+
+#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
+
+template <class T, class Alloc>
+inline void swap(slist<T, Alloc>& x, slist<T, Alloc>& y) {
+  x.swap(y);
+}
+
+#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
+
+
+template <class T, class Alloc>
+void slist<T, Alloc>::resize(size_type len, const T& x)
+{
+  list_node_base* cur = &head;
+  while (cur->next != 0 && len > 0) {
+    --len;
+    cur = cur->next;
+  }
+  if (cur->next) 
+    erase_after(cur, 0);
+  else
+    _insert_after_fill(cur, len, x);
+}
+
+template <class T, class Alloc>
+void slist<T,Alloc>::remove(const T& val)
+{
+  list_node_base* cur = &head;
+  while (cur && cur->next) {
+    if (((list_node*) cur->next)->data == val)
+      erase_after(cur);
+    else
+      cur = cur->next;
+  }
+}
+
+template <class T, class Alloc> 
+void slist<T,Alloc>::unique()
+{
+  list_node_base* cur = head.next;
+  if (cur) {
+    while (cur->next) {
+      if (((list_node*)cur)->data == ((list_node*)(cur->next))->data)
+        erase_after(cur);
+      else
+        cur = cur->next;
+    }
+  }
+}
+
+template <class T, class Alloc>
+void slist<T,Alloc>::merge(slist<T,Alloc>& L)
+{
+  list_node_base* n1 = &head;
+  while (n1->next && L.head.next) {
+    if (((list_node*) L.head.next)->data < ((list_node*) n1->next)->data) 
+      __slist_splice_after(n1, &L.head, L.head.next);
+    n1 = n1->next;
+  }
+  if (L.head.next) {
+    n1->next = L.head.next;
+    L.head.next = 0;
+  }
+}
+
+template <class T, class Alloc>
+void slist<T,Alloc>::sort()
+{
+  if (head.next && head.next->next) {
+    slist carry;
+    slist counter[64];
+    int fill = 0;
+    while (!empty()) {
+      __slist_splice_after(&carry.head, &head, head.next);
+      int i = 0;
+      while (i < fill && !counter[i].empty()) {
+        counter[i].merge(carry);
+        carry.swap(counter[i]);
+        ++i;
+      }
+      carry.swap(counter[i]);
+      if (i == fill)
+        ++fill;
+    }
+
+    for (int i = 1; i < fill; ++i)
+      counter[i].merge(counter[i-1]);
+    this->swap(counter[fill-1]);
+  }
+}
+
+#ifdef __STL_MEMBER_TEMPLATES
+
+template <class T, class Alloc> 
+template <class Predicate> void slist<T,Alloc>::remove_if(Predicate pred)
+{
+  list_node_base* cur = &head;
+  while (cur->next) {
+    if (pred(((list_node*) cur->next)->data))
+      erase_after(cur);
+    else
+      cur = cur->next;
+  }
+}
+
+template <class T, class Alloc> template <class BinaryPredicate> 
+void slist<T,Alloc>::unique(BinaryPredicate pred)
+{
+  list_node* cur = (list_node*) head.next;
+  if (cur) {
+    while (cur->next) {
+      if (pred(((list_node*)cur)->data, ((list_node*)(cur->next))->data))
+        erase_after(cur);
+      else
+        cur = (list_node*) cur->next;
+    }
+  }
+}
+
+template <class T, class Alloc> template <class StrictWeakOrdering>
+void slist<T,Alloc>::merge(slist<T,Alloc>& L, StrictWeakOrdering comp)
+{
+  list_node_base* n1 = &head;
+  while (n1->next && L.head.next) {
+    if (comp(((list_node*) L.head.next)->data,
+             ((list_node*) n1->next)->data))
+      __slist_splice_after(n1, &L.head, L.head.next);
+    n1 = n1->next;
+  }
+  if (L.head.next) {
+    n1->next = L.head.next;
+    L.head.next = 0;
+  }
+}
+
+template <class T, class Alloc> template <class StrictWeakOrdering> 
+void slist<T,Alloc>::sort(StrictWeakOrdering comp)
+{
+  if (head.next && head.next->next) {
+    slist carry;
+    slist counter[64];
+    int fill = 0;
+    while (!empty()) {
+      __slist_splice_after(&carry.head, &head, head.next);
+      int i = 0;
+      while (i < fill && !counter[i].empty()) {
+        counter[i].merge(carry, comp);
+        carry.swap(counter[i]);
+        ++i;
+      }
+      carry.swap(counter[i]);
+      if (i == fill)
+        ++fill;
+    }
+
+    for (int i = 1; i < fill; ++i)
+      counter[i].merge(counter[i-1], comp);
+    this->swap(counter[fill-1]);
+  }
+}
+
+#endif /* __STL_MEMBER_TEMPLATES */
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1174
+#endif
+
+__STL_END_NAMESPACE 
+
+#endif /* __SGI_STL_INTERNAL_SLIST_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_stack.h b/libstdc++/stl/stl_stack.h
new file mode 100644 (file)
index 0000000..d380e81
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_STACK_H
+#define __SGI_STL_INTERNAL_STACK_H
+
+__STL_BEGIN_NAMESPACE
+
+#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
+template <class T, class Sequence = deque<T> >
+#else
+template <class T, class Sequence>
+#endif
+class stack {
+  friend bool operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&);
+  friend bool operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&);
+public:
+  typedef typename Sequence::value_type value_type;
+  typedef typename Sequence::size_type size_type;
+  typedef typename Sequence::reference reference;
+  typedef typename Sequence::const_reference const_reference;
+protected:
+  Sequence c;
+public:
+  bool empty() const { return c.empty(); }
+  size_type size() const { return c.size(); }
+  reference top() { return c.back(); }
+  const_reference top() const { return c.back(); }
+  void push(const value_type& x) { c.push_back(x); }
+  void pop() { c.pop_back(); }
+};
+
+template <class T, class Sequence>
+bool operator==(const stack<T, Sequence>& x, const stack<T, Sequence>& y) {
+  return x.c == y.c;
+}
+
+template <class T, class Sequence>
+bool operator<(const stack<T, Sequence>& x, const stack<T, Sequence>& y) {
+  return x.c < y.c;
+}
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_STACK_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_tempbuf.h b/libstdc++/stl/stl_tempbuf.h
new file mode 100644 (file)
index 0000000..5c971e6
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_TEMPBUF_H
+#define __SGI_STL_INTERNAL_TEMPBUF_H
+
+
+__STL_BEGIN_NAMESPACE
+
+template <class T>
+pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t len, T*) {
+  if (len > ptrdiff_t(INT_MAX / sizeof(T)))
+    len = INT_MAX / sizeof(T);
+
+  while (len > 0) {
+    T* tmp = (T*) malloc((size_t)len * sizeof(T));
+    if (tmp != 0)
+      return pair<T*, ptrdiff_t>(tmp, len);
+    len /= 2;
+  }
+
+  return pair<T*, ptrdiff_t>((T*)0, 0);
+}
+
+template <class T>
+void return_temporary_buffer(T* p) {
+  free(p);
+}
+
+template <class ForwardIterator,
+          class T 
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+                  = iterator_traits<ForwardIterator>::value_type 
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+         >
+class temporary_buffer {
+private:
+  ptrdiff_t original_len;
+  ptrdiff_t len;
+  T* buffer;
+
+  void allocate_buffer() {
+    original_len = len;
+    buffer = 0;
+
+    if (len > (ptrdiff_t)(INT_MAX / sizeof(T)))
+      len = INT_MAX / sizeof(T);
+
+    while (len > 0) {
+      buffer = (T*) malloc(len * sizeof(T));
+      if (buffer)
+        break;
+      len /= 2;
+    }
+  }
+
+  void initialize_buffer(const T&, __true_type) {}
+  void initialize_buffer(const T& val, __false_type) {
+    uninitialized_fill_n(buffer, len, val);
+  }
+
+public:
+  ptrdiff_t size() const { return len; }
+  ptrdiff_t requested_size() const { return original_len; }
+  T* begin() { return buffer; }
+  T* end() { return buffer + len; }
+
+  temporary_buffer(ForwardIterator first, ForwardIterator last) {
+    __STL_TRY {
+      len = 0;
+      distance(first, last, len);
+      allocate_buffer();
+      if (len > 0)
+        initialize_buffer(*first,
+                          __type_traits<T>::has_trivial_default_constructor());
+    }
+    __STL_UNWIND(free(buffer); buffer = 0; len = 0);
+  }
+  ~temporary_buffer() {  
+    destroy(buffer, buffer + len);
+    free(buffer);
+  }
+
+private:
+  temporary_buffer(const temporary_buffer&) {}
+  void operator=(const temporary_buffer&) {}
+};
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_TEMPBUF_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_tree.h b/libstdc++/stl/stl_tree.h
new file mode 100644 (file)
index 0000000..55a6c0e
--- /dev/null
@@ -0,0 +1,1099 @@
+/*
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_TREE_H
+#define __SGI_STL_INTERNAL_TREE_H
+
+/*
+
+Red-black tree class, designed for use in implementing STL
+associative containers (set, multiset, map, and multimap). The
+insertion and deletion algorithms are based on those in Cormen,
+Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 1990),
+except that
+
+(1) the header cell is maintained with links not only to the root
+but also to the leftmost node of the tree, to enable constant time
+begin(), and to the rightmost node of the tree, to enable linear time
+performance when used with the generic set algorithms (set_union,
+etc.);
+
+(2) when a node being deleted has two children its successor node is
+relinked into its place, rather than copied, so that the only
+iterators invalidated are those referring to the deleted node.
+
+*/
+
+#include <stl_algobase.h>
+#include <stl_alloc.h>
+#include <stl_construct.h>
+#include <stl_function.h>
+
+__STL_BEGIN_NAMESPACE 
+
+typedef bool __rb_tree_color_type;
+const __rb_tree_color_type __rb_tree_red = false;
+const __rb_tree_color_type __rb_tree_black = true;
+
+struct __rb_tree_node_base
+{
+  typedef __rb_tree_color_type color_type;
+  typedef __rb_tree_node_base* base_ptr;
+
+  color_type color; 
+  base_ptr parent;
+  base_ptr left;
+  base_ptr right;
+
+  static base_ptr minimum(base_ptr x)
+  {
+    while (x->left != 0) x = x->left;
+    return x;
+  }
+
+  static base_ptr maximum(base_ptr x)
+  {
+    while (x->right != 0) x = x->right;
+    return x;
+  }
+};
+
+template <class Value>
+struct __rb_tree_node : public __rb_tree_node_base
+{
+  typedef __rb_tree_node<Value>* link_type;
+  Value value_field;
+};
+
+
+struct __rb_tree_base_iterator
+{
+  typedef __rb_tree_node_base::base_ptr base_ptr;
+  typedef bidirectional_iterator_tag iterator_category;
+  typedef ptrdiff_t difference_type;
+  base_ptr node;
+
+  void increment()
+  {
+    if (node->right != 0) {
+      node = node->right;
+      while (node->left != 0)
+        node = node->left;
+    }
+    else {
+      base_ptr y = node->parent;
+      while (node == y->right) {
+        node = y;
+        y = y->parent;
+      }
+      if (node->right != y)
+        node = y;
+    }
+  }
+
+  void decrement()
+  {
+    if (node->color == __rb_tree_red &&
+        node->parent->parent == node)
+      node = node->right;
+    else if (node->left != 0) {
+      base_ptr y = node->left;
+      while (y->right != 0)
+        y = y->right;
+      node = y;
+    }
+    else {
+      base_ptr y = node->parent;
+      while (node == y->left) {
+        node = y;
+        y = y->parent;
+      }
+      node = y;
+    }
+  }
+};
+
+template <class Value, class Ref, class Ptr>
+struct __rb_tree_iterator : public __rb_tree_base_iterator
+{
+  typedef Value value_type;
+  typedef Ref reference;
+  typedef Ptr pointer;
+  typedef __rb_tree_iterator<Value, Value&, Value*>             iterator;
+  typedef __rb_tree_iterator<Value, const Value&, const Value*> const_iterator;
+  typedef __rb_tree_iterator<Value, Ref, Ptr>                   self;
+  typedef __rb_tree_node<Value>* link_type;
+
+  __rb_tree_iterator() {}
+  __rb_tree_iterator(link_type x) { node = x; }
+  __rb_tree_iterator(const iterator& it) { node = it.node; }
+
+  reference operator*() const { return link_type(node)->value_field; }
+#ifndef __SGI_STL_NO_ARROW_OPERATOR
+  pointer operator->() const { return &(operator*()); }
+#endif /* __SGI_STL_NO_ARROW_OPERATOR */
+
+  self& operator++() { increment(); return *this; }
+  self operator++(int) {
+    self tmp = *this;
+    increment();
+    return tmp;
+  }
+    
+  self& operator--() { decrement(); return *this; }
+  self operator--(int) {
+    self tmp = *this;
+    decrement();
+    return tmp;
+  }
+};
+
+inline bool operator==(const __rb_tree_base_iterator& x,
+                       const __rb_tree_base_iterator& y) {
+  return x.node == y.node;
+}
+
+inline bool operator!=(const __rb_tree_base_iterator& x,
+                       const __rb_tree_base_iterator& y) {
+  return x.node != y.node;
+}
+
+#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
+
+inline bidirectional_iterator_tag
+iterator_category(const __rb_tree_base_iterator&) {
+  return bidirectional_iterator_tag();
+}
+
+inline __rb_tree_base_iterator::difference_type*
+distance_type(const __rb_tree_base_iterator&) {
+  return (__rb_tree_base_iterator::difference_type*) 0;
+}
+
+template <class Value, class Ref, class Ptr>
+inline Value* value_type(const __rb_tree_iterator<Value, Ref, Ptr>&) {
+  return (Value*) 0;
+}
+
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+
+inline void 
+__rb_tree_rotate_left(__rb_tree_node_base* x, __rb_tree_node_base*& root)
+{
+  __rb_tree_node_base* y = x->right;
+  x->right = y->left;
+  if (y->left !=0)
+    y->left->parent = x;
+  y->parent = x->parent;
+
+  if (x == root)
+    root = y;
+  else if (x == x->parent->left)
+    x->parent->left = y;
+  else
+    x->parent->right = y;
+  y->left = x;
+  x->parent = y;
+}
+
+inline void 
+__rb_tree_rotate_right(__rb_tree_node_base* x, __rb_tree_node_base*& root)
+{
+  __rb_tree_node_base* y = x->left;
+  x->left = y->right;
+  if (y->right != 0)
+    y->right->parent = x;
+  y->parent = x->parent;
+
+  if (x == root)
+    root = y;
+  else if (x == x->parent->right)
+    x->parent->right = y;
+  else
+    x->parent->left = y;
+  y->right = x;
+  x->parent = y;
+}
+
+inline void 
+__rb_tree_rebalance(__rb_tree_node_base* x, __rb_tree_node_base*& root)
+{
+  x->color = __rb_tree_red;
+  while (x != root && x->parent->color == __rb_tree_red) {
+    if (x->parent == x->parent->parent->left) {
+      __rb_tree_node_base* y = x->parent->parent->right;
+      if (y && y->color == __rb_tree_red) {
+        x->parent->color = __rb_tree_black;
+        y->color = __rb_tree_black;
+        x->parent->parent->color = __rb_tree_red;
+        x = x->parent->parent;
+      }
+      else {
+        if (x == x->parent->right) {
+          x = x->parent;
+          __rb_tree_rotate_left(x, root);
+        }
+        x->parent->color = __rb_tree_black;
+        x->parent->parent->color = __rb_tree_red;
+        __rb_tree_rotate_right(x->parent->parent, root);
+      }
+    }
+    else {
+      __rb_tree_node_base* y = x->parent->parent->left;
+      if (y && y->color == __rb_tree_red) {
+        x->parent->color = __rb_tree_black;
+        y->color = __rb_tree_black;
+        x->parent->parent->color = __rb_tree_red;
+        x = x->parent->parent;
+      }
+      else {
+        if (x == x->parent->left) {
+          x = x->parent;
+          __rb_tree_rotate_right(x, root);
+        }
+        x->parent->color = __rb_tree_black;
+        x->parent->parent->color = __rb_tree_red;
+        __rb_tree_rotate_left(x->parent->parent, root);
+      }
+    }
+  }
+  root->color = __rb_tree_black;
+}
+
+inline __rb_tree_node_base*
+__rb_tree_rebalance_for_erase(__rb_tree_node_base* z,
+                              __rb_tree_node_base*& root,
+                              __rb_tree_node_base*& leftmost,
+                              __rb_tree_node_base*& rightmost)
+{
+  __rb_tree_node_base* y = z;
+  __rb_tree_node_base* x = 0;
+  __rb_tree_node_base* x_parent = 0;
+  if (y->left == 0)             // z has at most one non-null child. y == z.
+    x = y->right;               // x might be null.
+  else
+    if (y->right == 0)          // z has exactly one non-null child.  y == z.
+      x = y->left;              // x is not null.
+    else {                      // z has two non-null children.  Set y to
+      y = y->right;             //   z's successor.  x might be null.
+      while (y->left != 0)
+        y = y->left;
+      x = y->right;
+    }
+  if (y != z) {                 // relink y in place of z.  y is z's successor
+    z->left->parent = y; 
+    y->left = z->left;
+    if (y != z->right) {
+      x_parent = y->parent;
+      if (x) x->parent = y->parent;
+      y->parent->left = x;      // y must be a left child
+      y->right = z->right;
+      z->right->parent = y;
+    }
+    else
+      x_parent = y;  
+    if (root == z)
+      root = y;
+    else if (z->parent->left == z)
+      z->parent->left = y;
+    else 
+      z->parent->right = y;
+    y->parent = z->parent;
+    __STD::swap(y->color, z->color);
+    y = z;
+    // y now points to node to be actually deleted
+  }
+  else {                        // y == z
+    x_parent = y->parent;
+    if (x) x->parent = y->parent;   
+    if (root == z)
+      root = x;
+    else 
+      if (z->parent->left == z)
+        z->parent->left = x;
+      else
+        z->parent->right = x;
+    if (leftmost == z) 
+      if (z->right == 0)        // z->left must be null also
+        leftmost = z->parent;
+    // makes leftmost == header if z == root
+      else
+        leftmost = __rb_tree_node_base::minimum(x);
+    if (rightmost == z)  
+      if (z->left == 0)         // z->right must be null also
+        rightmost = z->parent;  
+    // makes rightmost == header if z == root
+      else                      // x == z->left
+        rightmost = __rb_tree_node_base::maximum(x);
+  }
+  if (y->color != __rb_tree_red) { 
+    while (x != root && (x == 0 || x->color == __rb_tree_black))
+      if (x == x_parent->left) {
+        __rb_tree_node_base* w = x_parent->right;
+        if (w->color == __rb_tree_red) {
+          w->color = __rb_tree_black;
+          x_parent->color = __rb_tree_red;
+          __rb_tree_rotate_left(x_parent, root);
+          w = x_parent->right;
+        }
+        if ((w->left == 0 || w->left->color == __rb_tree_black) &&
+            (w->right == 0 || w->right->color == __rb_tree_black)) {
+          w->color = __rb_tree_red;
+          x = x_parent;
+          x_parent = x_parent->parent;
+        } else {
+          if (w->right == 0 || w->right->color == __rb_tree_black) {
+            if (w->left) w->left->color = __rb_tree_black;
+            w->color = __rb_tree_red;
+            __rb_tree_rotate_right(w, root);
+            w = x_parent->right;
+          }
+          w->color = x_parent->color;
+          x_parent->color = __rb_tree_black;
+          if (w->right) w->right->color = __rb_tree_black;
+          __rb_tree_rotate_left(x_parent, root);
+          break;
+        }
+      } else {                  // same as above, with right <-> left.
+        __rb_tree_node_base* w = x_parent->left;
+        if (w->color == __rb_tree_red) {
+          w->color = __rb_tree_black;
+          x_parent->color = __rb_tree_red;
+          __rb_tree_rotate_right(x_parent, root);
+          w = x_parent->left;
+        }
+        if ((w->right == 0 || w->right->color == __rb_tree_black) &&
+            (w->left == 0 || w->left->color == __rb_tree_black)) {
+          w->color = __rb_tree_red;
+          x = x_parent;
+          x_parent = x_parent->parent;
+        } else {
+          if (w->left == 0 || w->left->color == __rb_tree_black) {
+            if (w->right) w->right->color = __rb_tree_black;
+            w->color = __rb_tree_red;
+            __rb_tree_rotate_left(w, root);
+            w = x_parent->left;
+          }
+          w->color = x_parent->color;
+          x_parent->color = __rb_tree_black;
+          if (w->left) w->left->color = __rb_tree_black;
+          __rb_tree_rotate_right(x_parent, root);
+          break;
+        }
+      }
+    if (x) x->color = __rb_tree_black;
+  }
+  return y;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare,
+          class Alloc = alloc>
+class rb_tree {
+protected:
+  typedef void* void_pointer;
+  typedef __rb_tree_node_base* base_ptr;
+  typedef __rb_tree_node<Value> rb_tree_node;
+  typedef simple_alloc<rb_tree_node, Alloc> rb_tree_node_allocator;
+  typedef __rb_tree_color_type color_type;
+public:
+  typedef Key key_type;
+  typedef Value value_type;
+  typedef value_type* pointer;
+  typedef const value_type* const_pointer;
+  typedef value_type& reference;
+  typedef const value_type& const_reference;
+  typedef rb_tree_node* link_type;
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+protected:
+  link_type get_node() { return rb_tree_node_allocator::allocate(); }
+  void put_node(link_type p) { rb_tree_node_allocator::deallocate(p); }
+
+  link_type create_node(const value_type& x) {
+    link_type tmp = get_node();
+    __STL_TRY {
+      construct(&tmp->value_field, x);
+    }
+    __STL_UNWIND(put_node(tmp));
+    return tmp;
+  }
+
+  link_type clone_node(link_type x) {
+    link_type tmp = create_node(x->value_field);
+    tmp->color = x->color;
+    tmp->left = 0;
+    tmp->right = 0;
+    return tmp;
+  }
+
+  void destroy_node(link_type p) {
+    destroy(&p->value_field);
+    put_node(p);
+  }
+
+protected:
+  size_type node_count; // keeps track of size of tree
+  link_type header;  
+  Compare key_compare;
+
+  link_type& root() const { return (link_type&) header->parent; }
+  link_type& leftmost() const { return (link_type&) header->left; }
+  link_type& rightmost() const { return (link_type&) header->right; }
+
+  static link_type& left(link_type x) { return (link_type&)(x->left); }
+  static link_type& right(link_type x) { return (link_type&)(x->right); }
+  static link_type& parent(link_type x) { return (link_type&)(x->parent); }
+  static reference value(link_type x) { return x->value_field; }
+  static const Key& key(link_type x) { return KeyOfValue()(value(x)); }
+  static color_type& color(link_type x) { return (color_type&)(x->color); }
+
+  static link_type& left(base_ptr x) { return (link_type&)(x->left); }
+  static link_type& right(base_ptr x) { return (link_type&)(x->right); }
+  static link_type& parent(base_ptr x) { return (link_type&)(x->parent); }
+  static reference value(base_ptr x) { return ((link_type)x)->value_field; }
+  static const Key& key(base_ptr x) { return KeyOfValue()(value(link_type(x)));} 
+  static color_type& color(base_ptr x) { return (color_type&)(link_type(x)->color); }
+
+  static link_type minimum(link_type x) { 
+    return (link_type)  __rb_tree_node_base::minimum(x);
+  }
+  static link_type maximum(link_type x) {
+    return (link_type) __rb_tree_node_base::maximum(x);
+  }
+
+public:
+  typedef __rb_tree_iterator<value_type, reference, pointer> iterator;
+  typedef __rb_tree_iterator<value_type, const_reference, const_pointer> 
+          const_iterator;
+
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+  typedef reverse_iterator<const_iterator> const_reverse_iterator;
+  typedef reverse_iterator<iterator> reverse_iterator;
+#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+  typedef reverse_bidirectional_iterator<iterator, value_type, reference,
+                                         difference_type>
+          reverse_iterator; 
+  typedef reverse_bidirectional_iterator<const_iterator, value_type,
+                                         const_reference, difference_type>
+          const_reverse_iterator;
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 
+private:
+  iterator __insert(base_ptr x, base_ptr y, const value_type& v);
+  link_type __copy(link_type x, link_type p);
+  void __erase(link_type x);
+  void init() {
+    header = get_node();
+    color(header) = __rb_tree_red; // used to distinguish header from 
+                                   // root, in iterator.operator++
+    root() = 0;
+    leftmost() = header;
+    rightmost() = header;
+  }
+public:
+                                // allocation/deallocation
+  rb_tree(const Compare& comp = Compare())
+    : node_count(0), key_compare(comp) { init(); }
+
+  rb_tree(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x) 
+    : node_count(0), key_compare(x.key_compare)
+  { 
+    header = get_node();
+    color(header) = __rb_tree_red;
+    if (x.root() == 0) {
+      root() = 0;
+      leftmost() = header;
+      rightmost() = header;
+    }
+    else {
+      __STL_TRY {
+        root() = __copy(x.root(), header);
+      }
+      __STL_UNWIND(put_node(header));
+      leftmost() = minimum(root());
+      rightmost() = maximum(root());
+    }
+    node_count = x.node_count;
+  }
+  ~rb_tree() {
+    clear();
+    put_node(header);
+  }
+  rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& 
+  operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x);
+
+public:    
+                                // accessors:
+  Compare key_comp() const { return key_compare; }
+  iterator begin() { return leftmost(); }
+  const_iterator begin() const { return leftmost(); }
+  iterator end() { return header; }
+  const_iterator end() const { return header; }
+  reverse_iterator rbegin() { return reverse_iterator(end()); }
+  const_reverse_iterator rbegin() const { 
+    return const_reverse_iterator(end()); 
+  }
+  reverse_iterator rend() { return reverse_iterator(begin()); }
+  const_reverse_iterator rend() const { 
+    return const_reverse_iterator(begin());
+  } 
+  bool empty() const { return node_count == 0; }
+  size_type size() const { return node_count; }
+  size_type max_size() const { return size_type(-1); }
+
+  void swap(rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& t) {
+    __STD::swap(header, t.header);
+    __STD::swap(node_count, t.node_count);
+    __STD::swap(key_compare, t.key_compare);
+  }
+    
+public:
+                                // insert/erase
+  pair<iterator,bool> insert_unique(const value_type& x);
+  iterator insert_equal(const value_type& x);
+
+  iterator insert_unique(iterator position, const value_type& x);
+  iterator insert_equal(iterator position, const value_type& x);
+
+#ifdef __STL_MEMBER_TEMPLATES  
+  template <class InputIterator>
+  void insert_unique(InputIterator first, InputIterator last);
+  template <class InputIterator>
+  void insert_equal(InputIterator first, InputIterator last);
+#else /* __STL_MEMBER_TEMPLATES */
+  void insert_unique(const_iterator first, const_iterator last);
+  void insert_unique(const value_type* first, const value_type* last);
+  void insert_equal(const_iterator first, const_iterator last);
+  void insert_equal(const value_type* first, const value_type* last);
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  void erase(iterator position);
+  size_type erase(const key_type& x);
+  void erase(iterator first, iterator last);
+  void erase(const key_type* first, const key_type* last);
+  void clear() {
+    if (node_count != 0) {
+      __erase(root());
+      leftmost() = header;
+      root() = 0;
+      rightmost() = header;
+      node_count = 0;
+    }
+  }      
+
+public:
+                                // set operations:
+  iterator find(const key_type& x);
+  const_iterator find(const key_type& x) const;
+  size_type count(const key_type& x) const;
+  iterator lower_bound(const key_type& x);
+  const_iterator lower_bound(const key_type& x) const;
+  iterator upper_bound(const key_type& x);
+  const_iterator upper_bound(const key_type& x) const;
+  pair<iterator,iterator> equal_range(const key_type& x);
+  pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
+
+public:
+                                // Debugging.
+  bool __rb_verify() const;
+};
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+inline bool operator==(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x, 
+                       const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& y) {
+  return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+inline bool operator<(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x, 
+                      const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& y) {
+  return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+inline void swap(rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x, 
+                 rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& y) {
+  x.swap(y);
+}
+
+#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
+
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& 
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::
+operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x) {
+  if (this != &x) {
+                                // Note that Key may be a constant type.
+    clear();
+    node_count = 0;
+    key_compare = x.key_compare;        
+    if (x.root() == 0) {
+      root() = 0;
+      leftmost() = header;
+      rightmost() = header;
+    }
+    else {
+      root() = __copy(x.root(), header);
+      leftmost() = minimum(root());
+      rightmost() = maximum(root());
+      node_count = x.node_count;
+    }
+  }
+  return *this;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::
+__insert(base_ptr x_, base_ptr y_, const Value& v) {
+  link_type x = (link_type) x_;
+  link_type y = (link_type) y_;
+  link_type z;
+
+  if (y == header || x != 0 || key_compare(KeyOfValue()(v), key(y))) {
+    z = create_node(v);
+    left(y) = z;                // also makes leftmost() = z when y == header
+    if (y == header) {
+      root() = z;
+      rightmost() = z;
+    }
+    else if (y == leftmost())
+      leftmost() = z;           // maintain leftmost() pointing to min node
+  }
+  else {
+    z = create_node(v);
+    right(y) = z;
+    if (y == rightmost())
+      rightmost() = z;          // maintain rightmost() pointing to max node
+  }
+  parent(z) = y;
+  left(z) = 0;
+  right(z) = 0;
+  __rb_tree_rebalance(z, header->parent);
+  ++node_count;
+  return iterator(z);
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_equal(const Value& v)
+{
+  link_type y = header;
+  link_type x = root();
+  while (x != 0) {
+    y = x;
+    x = key_compare(KeyOfValue()(v), key(x)) ? left(x) : right(x);
+  }
+  return __insert(x, y, v);
+}
+
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+pair<typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator, bool>
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_unique(const Value& v)
+{
+  link_type y = header;
+  link_type x = root();
+  bool comp = true;
+  while (x != 0) {
+    y = x;
+    comp = key_compare(KeyOfValue()(v), key(x));
+    x = comp ? left(x) : right(x);
+  }
+  iterator j = iterator(y);   
+  if (comp)
+    if (j == begin())     
+      return pair<iterator,bool>(__insert(x, y, v), true);
+    else
+      --j;
+  if (key_compare(key(j.node), KeyOfValue()(v)))
+    return pair<iterator,bool>(__insert(x, y, v), true);
+  return pair<iterator,bool>(j, false);
+}
+
+
+template <class Key, class Val, class KeyOfValue, class Compare, class Alloc>
+typename rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::iterator 
+rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::insert_unique(iterator position,
+                                                             const Val& v) {
+  if (position.node == header->left) // begin()
+    if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node)))
+      return __insert(position.node, position.node, v);
+  // first argument just needs to be non-null 
+    else
+      return insert_unique(v).first;
+  else if (position.node == header) // end()
+    if (key_compare(key(rightmost()), KeyOfValue()(v)))
+      return __insert(0, rightmost(), v);
+    else
+      return insert_unique(v).first;
+  else {
+    iterator before = position;
+    --before;
+    if (key_compare(key(before.node), KeyOfValue()(v))
+        && key_compare(KeyOfValue()(v), key(position.node)))
+      if (right(before.node) == 0)
+        return __insert(0, before.node, v); 
+      else
+        return __insert(position.node, position.node, v);
+    // first argument just needs to be non-null 
+    else
+      return insert_unique(v).first;
+  }
+}
+
+template <class Key, class Val, class KeyOfValue, class Compare, class Alloc>
+typename rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::iterator 
+rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::insert_equal(iterator position,
+                                                            const Val& v) {
+  if (position.node == header->left) // begin()
+    if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node)))
+      return __insert(position.node, position.node, v);
+  // first argument just needs to be non-null 
+    else
+      return insert_equal(v);
+  else if (position.node == header) // end()
+    if (!key_compare(KeyOfValue()(v), key(rightmost())))
+      return __insert(0, rightmost(), v);
+    else
+      return insert_equal(v);
+  else {
+    iterator before = position;
+    --before;
+    if (!key_compare(KeyOfValue()(v), key(before.node))
+        && !key_compare(key(position.node), KeyOfValue()(v)))
+      if (right(before.node) == 0)
+        return __insert(0, before.node, v); 
+      else
+        return __insert(position.node, position.node, v);
+    // first argument just needs to be non-null 
+    else
+      return insert_equal(v);
+  }
+}
+
+#ifdef __STL_MEMBER_TEMPLATES  
+
+template <class K, class V, class KoV, class Cmp, class Al> template<class II>
+void rb_tree<K, V, KoV, Cmp, Al>::insert_equal(II first, II last) {
+  for ( ; first != last; ++first)
+    insert_equal(*first);
+}
+
+template <class K, class V, class KoV, class Cmp, class Al> template<class II>
+void rb_tree<K, V, KoV, Cmp, Al>::insert_unique(II first, II last) {
+  for ( ; first != last; ++first)
+    insert_unique(*first);
+}
+
+#else /* __STL_MEMBER_TEMPLATES */
+
+template <class K, class V, class KoV, class Cmp, class Al>
+void
+rb_tree<K, V, KoV, Cmp, Al>::insert_equal(const V* first, const V* last) {
+  for ( ; first != last; ++first)
+    insert_equal(*first);
+}
+
+template <class K, class V, class KoV, class Cmp, class Al>
+void
+rb_tree<K, V, KoV, Cmp, Al>::insert_equal(const_iterator first,
+                                          const_iterator last) {
+  for ( ; first != last; ++first)
+    insert_equal(*first);
+}
+
+template <class K, class V, class KoV, class Cmp, class A>
+void 
+rb_tree<K, V, KoV, Cmp, A>::insert_unique(const V* first, const V* last) {
+  for ( ; first != last; ++first)
+    insert_unique(*first);
+}
+
+template <class K, class V, class KoV, class Cmp, class A>
+void 
+rb_tree<K, V, KoV, Cmp, A>::insert_unique(const_iterator first,
+                                          const_iterator last) {
+  for ( ; first != last; ++first)
+    insert_unique(*first);
+}
+
+#endif /* __STL_MEMBER_TEMPLATES */
+         
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+inline void
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(iterator position) {
+  link_type y = (link_type) __rb_tree_rebalance_for_erase(position.node,
+                                                          header->parent,
+                                                          header->left,
+                                                          header->right);
+  destroy_node(y);
+  --node_count;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::size_type 
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(const Key& x) {
+  pair<iterator,iterator> p = equal_range(x);
+  size_type n = 0;
+  distance(p.first, p.second, n);
+  erase(p.first, p.second);
+  return n;
+}
+
+template <class K, class V, class KeyOfValue, class Compare, class Alloc>
+typename rb_tree<K, V, KeyOfValue, Compare, Alloc>::link_type 
+rb_tree<K, V, KeyOfValue, Compare, Alloc>::__copy(link_type x, link_type p) {
+                                // structural copy.  x and p must be non-null.
+  link_type top = clone_node(x);
+  top->parent = p;
+  __STL_TRY {
+    if (x->right)
+      top->right = __copy(right(x), top);
+    p = top;
+    x = left(x);
+
+    while (x != 0) {
+      link_type y = clone_node(x);
+      p->left = y;
+      y->parent = p;
+      if (x->right)
+        y->right = __copy(right(x), y);
+      p = y;
+      x = left(x);
+    }
+  }
+  __STL_UNWIND(__erase(top));
+
+  return top;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::__erase(link_type x) {
+                                // erase without rebalancing
+  while (x != 0) {
+    __erase(right(x));
+    link_type y = left(x);
+    destroy_node(x);
+    x = y;
+  }
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(iterator first, 
+                                                            iterator last) {
+  if (first == begin() && last == end())
+    clear();
+  else
+    while (first != last) erase(first++);
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(const Key* first, 
+                                                            const Key* last) {
+  while (first != last) erase(*first++);
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator 
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::find(const Key& k) {
+  link_type y = header;        // Last node which is not less than k. 
+  link_type x = root();        // Current node. 
+
+  while (x != 0) 
+    if (!key_compare(key(x), k))
+      y = x, x = left(x);
+    else
+      x = right(x);
+
+  iterator j = iterator(y);   
+  return (j == end() || key_compare(k, key(j.node))) ? end() : j;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator 
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::find(const Key& k) const {
+  link_type y = header; /* Last node which is not less than k. */
+  link_type x = root(); /* Current node. */
+
+  while (x != 0) {
+    if (!key_compare(key(x), k))
+      y = x, x = left(x);
+    else
+      x = right(x);
+  }
+  const_iterator j = const_iterator(y);   
+  return (j == end() || key_compare(k, key(j.node))) ? end() : j;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::size_type 
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::count(const Key& k) const {
+  pair<const_iterator, const_iterator> p = equal_range(k);
+  size_type n = 0;
+  distance(p.first, p.second, n);
+  return n;
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator 
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::lower_bound(const Key& k) {
+  link_type y = header; /* Last node which is not less than k. */
+  link_type x = root(); /* Current node. */
+
+  while (x != 0) 
+    if (!key_compare(key(x), k))
+      y = x, x = left(x);
+    else
+      x = right(x);
+
+  return iterator(y);
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator 
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::lower_bound(const Key& k) const {
+  link_type y = header; /* Last node which is not less than k. */
+  link_type x = root(); /* Current node. */
+
+  while (x != 0) 
+    if (!key_compare(key(x), k))
+      y = x, x = left(x);
+    else
+      x = right(x);
+
+  return const_iterator(y);
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator 
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::upper_bound(const Key& k) {
+  link_type y = header; /* Last node which is greater than k. */
+  link_type x = root(); /* Current node. */
+
+   while (x != 0) 
+     if (key_compare(k, key(x)))
+       y = x, x = left(x);
+     else
+       x = right(x);
+
+   return iterator(y);
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator 
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::upper_bound(const Key& k) const {
+  link_type y = header; /* Last node which is greater than k. */
+  link_type x = root(); /* Current node. */
+
+   while (x != 0) 
+     if (key_compare(k, key(x)))
+       y = x, x = left(x);
+     else
+       x = right(x);
+
+   return const_iterator(y);
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+inline pair<typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator,
+            typename rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator>
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::equal_range(const Key& k) {
+  return pair<iterator, iterator>(lower_bound(k), upper_bound(k));
+}
+
+template <class Key, class Value, class KoV, class Compare, class Alloc>
+inline pair<typename rb_tree<Key, Value, KoV, Compare, Alloc>::const_iterator,
+            typename rb_tree<Key, Value, KoV, Compare, Alloc>::const_iterator>
+rb_tree<Key, Value, KoV, Compare, Alloc>::equal_range(const Key& k) const {
+  return pair<const_iterator,const_iterator>(lower_bound(k), upper_bound(k));
+}
+
+inline int __black_count(__rb_tree_node_base* node, __rb_tree_node_base* root)
+{
+  if (node == 0)
+    return 0;
+  else {
+    int bc = node->color == __rb_tree_black ? 1 : 0;
+    if (node == root)
+      return bc;
+    else
+      return bc + __black_count(node->parent, root);
+  }
+}
+
+template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
+bool 
+rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::__rb_verify() const
+{
+  if (node_count == 0 || begin() == end())
+    return node_count == 0 && begin() == end() &&
+      header->left == header && header->right == header;
+  
+  int len = __black_count(leftmost(), root());
+  for (const_iterator it = begin(); it != end(); ++it) {
+    link_type x = (link_type) it.node;
+    link_type L = left(x);
+    link_type R = right(x);
+
+    if (x->color == __rb_tree_red)
+      if ((L && L->color == __rb_tree_red) ||
+          (R && R->color == __rb_tree_red))
+        return false;
+
+    if (L && key_compare(key(x), key(L)))
+      return false;
+    if (R && key_compare(key(R), key(x)))
+      return false;
+
+    if (!L && !R && __black_count(x, root()) != len)
+      return false;
+  }
+
+  if (leftmost() != __rb_tree_node_base::minimum(root()))
+    return false;
+  if (rightmost() != __rb_tree_node_base::maximum(root()))
+    return false;
+
+  return true;
+}
+
+__STL_END_NAMESPACE 
+
+#endif /* __SGI_STL_INTERNAL_TREE_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_uninitialized.h b/libstdc++/stl/stl_uninitialized.h
new file mode 100644 (file)
index 0000000..661bbe9
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H
+#define __SGI_STL_INTERNAL_UNINITIALIZED_H
+
+__STL_BEGIN_NAMESPACE
+
+// Valid if copy construction is equivalent to assignment, and if the
+//  destructor is trivial.
+template <class InputIterator, class ForwardIterator>
+inline ForwardIterator 
+__uninitialized_copy_aux(InputIterator first, InputIterator last,
+                         ForwardIterator result,
+                         __true_type) {
+  return copy(first, last, result);
+}
+
+template <class InputIterator, class ForwardIterator>
+ForwardIterator 
+__uninitialized_copy_aux(InputIterator first, InputIterator last,
+                         ForwardIterator result,
+                         __false_type) {
+  ForwardIterator cur = result;
+  __STL_TRY {
+    for ( ; first != last; ++first, ++cur)
+      construct(&*cur, *first);
+    return cur;
+  }
+  __STL_UNWIND(destroy(result, cur));
+}
+
+
+template <class InputIterator, class ForwardIterator, class T>
+inline ForwardIterator
+__uninitialized_copy(InputIterator first, InputIterator last,
+                     ForwardIterator result, T*) {
+  typedef typename __type_traits<T>::is_POD_type is_POD;
+  return __uninitialized_copy_aux(first, last, result, is_POD());
+}
+
+template <class InputIterator, class ForwardIterator>
+inline ForwardIterator
+  uninitialized_copy(InputIterator first, InputIterator last,
+                     ForwardIterator result) {
+  return __uninitialized_copy(first, last, result, value_type(result));
+}
+
+inline char* uninitialized_copy(const char* first, const char* last,
+                                char* result) {
+  memmove(result, first, last - first);
+  return result + (last - first);
+}
+
+inline wchar_t* uninitialized_copy(const wchar_t* first, const wchar_t* last,
+                                   wchar_t* result) {
+  memmove(result, first, sizeof(wchar_t) * (last - first));
+  return result + (last - first);
+}
+
+template <class InputIterator, class Size, class ForwardIterator>
+pair<InputIterator, ForwardIterator>
+__uninitialized_copy_n(InputIterator first, Size count,
+                       ForwardIterator result,
+                       input_iterator_tag) {
+  ForwardIterator cur = result;
+  __STL_TRY {
+    for ( ; count > 0 ; --count, ++first, ++cur) 
+      construct(&*cur, *first);
+    return pair<InputIterator, ForwardIterator>(first, cur);
+  }
+  __STL_UNWIND(destroy(result, cur));
+}
+
+template <class RandomAccessIterator, class Size, class ForwardIterator>
+inline pair<RandomAccessIterator, ForwardIterator>
+__uninitialized_copy_n(RandomAccessIterator first, Size count,
+                       ForwardIterator result,
+                       random_access_iterator_tag) {
+  RandomAccessIterator last = first + count;
+  return make_pair(last, uninitialized_copy(first, last, result));
+}
+
+template <class InputIterator, class Size, class ForwardIterator>
+inline pair<InputIterator, ForwardIterator>
+uninitialized_copy_n(InputIterator first, Size count,
+                     ForwardIterator result) {
+  return __uninitialized_copy_n(first, count, result,
+                                iterator_category(first));
+}
+
+// Valid if copy construction is equivalent to assignment, and if the
+//  destructor is trivial.
+template <class ForwardIterator, class T>
+inline void
+__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, 
+                         const T& x, __true_type)
+{
+  fill(first, last, x);
+}
+
+template <class ForwardIterator, class T>
+void
+__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, 
+                         const T& x, __false_type)
+{
+  ForwardIterator cur = first;
+  __STL_TRY {
+    for ( ; cur != last; ++cur)
+      construct(&*cur, x);
+  }
+  __STL_UNWIND(destroy(first, cur));
+}
+
+template <class ForwardIterator, class T, class T1>
+inline void __uninitialized_fill(ForwardIterator first, ForwardIterator last, 
+                                 const T& x, T1*) {
+  typedef typename __type_traits<T1>::is_POD_type is_POD;
+  __uninitialized_fill_aux(first, last, x, is_POD());
+                   
+}
+
+template <class ForwardIterator, class T>
+inline void uninitialized_fill(ForwardIterator first, ForwardIterator last, 
+                               const T& x) {
+  __uninitialized_fill(first, last, x, value_type(first));
+}
+
+// Valid if copy construction is equivalent to assignment, and if the
+//  destructor is trivial.
+template <class ForwardIterator, class Size, class T>
+inline ForwardIterator
+__uninitialized_fill_n_aux(ForwardIterator first, Size n,
+                           const T& x, __true_type) {
+  return fill_n(first, n, x);
+}
+
+template <class ForwardIterator, class Size, class T>
+ForwardIterator
+__uninitialized_fill_n_aux(ForwardIterator first, Size n,
+                           const T& x, __false_type) {
+  ForwardIterator cur = first;
+  __STL_TRY {
+    for ( ; n > 0; --n, ++cur)
+      construct(&*cur, x);
+    return cur;
+  }
+  __STL_UNWIND(destroy(first, cur));
+}
+
+template <class ForwardIterator, class Size, class T, class T1>
+inline ForwardIterator __uninitialized_fill_n(ForwardIterator first, Size n,
+                                              const T& x, T1*) {
+  typedef typename __type_traits<T1>::is_POD_type is_POD;
+  return __uninitialized_fill_n_aux(first, n, x, is_POD());
+                                    
+}
+
+template <class ForwardIterator, class Size, class T>
+inline ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n,
+                                            const T& x) {
+  return __uninitialized_fill_n(first, n, x, value_type(first));
+}
+
+// Copies [first1, last1) into [result, result + (last1 - first1)), and
+//  copies [first2, last2) into
+//  [result, result + (last1 - first1) + (last2 - first2)).
+
+template <class InputIterator1, class InputIterator2, class ForwardIterator>
+inline ForwardIterator
+__uninitialized_copy_copy(InputIterator1 first1, InputIterator1 last1,
+                          InputIterator2 first2, InputIterator2 last2,
+                          ForwardIterator result) {
+  ForwardIterator mid = uninitialized_copy(first1, last1, result);
+  __STL_TRY {
+    return uninitialized_copy(first2, last2, mid);
+  }
+  __STL_UNWIND(destroy(result, mid));
+}
+
+// Fills [result, mid) with x, and copies [first, last) into
+//  [mid, mid + (last - first)).
+template <class ForwardIterator, class T, class InputIterator>
+inline ForwardIterator 
+__uninitialized_fill_copy(ForwardIterator result, ForwardIterator mid,
+                          const T& x,
+                          InputIterator first, InputIterator last) {
+  uninitialized_fill(result, mid, x);
+  __STL_TRY {
+    return uninitialized_copy(first, last, mid);
+  }
+  __STL_UNWIND(destroy(result, mid));
+}
+
+// Copies [first1, last1) into [first2, first2 + (last1 - first1)), and
+//  fills [first2 + (last1 - first1), last2) with x.
+template <class InputIterator, class ForwardIterator, class T>
+inline void
+__uninitialized_copy_fill(InputIterator first1, InputIterator last1,
+                          ForwardIterator first2, ForwardIterator last2,
+                          const T& x) {
+  ForwardIterator mid2 = uninitialized_copy(first1, last1, first2);
+  __STL_TRY {
+    uninitialized_fill(mid2, last2, x);
+  }
+  __STL_UNWIND(destroy(first2, mid2));
+}
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_UNINITIALIZED_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/stl_vector.h b/libstdc++/stl/stl_vector.h
new file mode 100644 (file)
index 0000000..cfa7fdb
--- /dev/null
@@ -0,0 +1,534 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_VECTOR_H
+#define __SGI_STL_INTERNAL_VECTOR_H
+
+__STL_BEGIN_NAMESPACE 
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma set woff 1174
+#endif
+
+template <class T, class Alloc = alloc>
+class vector {
+public:
+  typedef T value_type;
+  typedef value_type* pointer;
+  typedef const value_type* const_pointer;
+  typedef value_type* iterator;
+  typedef const value_type* const_iterator;
+  typedef value_type& reference;
+  typedef const value_type& const_reference;
+  typedef size_t size_type;
+  typedef ptrdiff_t difference_type;
+
+#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
+  typedef reverse_iterator<const_iterator> const_reverse_iterator;
+  typedef reverse_iterator<iterator> reverse_iterator;
+#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+  typedef reverse_iterator<const_iterator, value_type, const_reference, 
+                           difference_type>  const_reverse_iterator;
+  typedef reverse_iterator<iterator, value_type, reference, difference_type>
+          reverse_iterator;
+#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
+protected:
+  typedef simple_alloc<value_type, Alloc> data_allocator;
+  iterator start;
+  iterator finish;
+  iterator end_of_storage;
+  void insert_aux(iterator position, const T& x);
+  void deallocate() {
+    if (start) data_allocator::deallocate(start, end_of_storage - start);
+  }
+
+  void fill_initialize(size_type n, const T& value) {
+    start = allocate_and_fill(n, value);
+    finish = start + n;
+    end_of_storage = finish;
+  }
+public:
+  iterator begin() { return start; }
+  const_iterator begin() const { return start; }
+  iterator end() { return finish; }
+  const_iterator end() const { return finish; }
+  reverse_iterator rbegin() { return reverse_iterator(end()); }
+  const_reverse_iterator rbegin() const { 
+    return const_reverse_iterator(end()); 
+  }
+  reverse_iterator rend() { return reverse_iterator(begin()); }
+  const_reverse_iterator rend() const { 
+    return const_reverse_iterator(begin()); 
+  }
+  size_type size() const { return size_type(end() - begin()); }
+  size_type max_size() const { return size_type(-1) / sizeof(T); }
+  size_type capacity() const { return size_type(end_of_storage - begin()); }
+  bool empty() const { return begin() == end(); }
+  reference operator[](size_type n) { return *(begin() + n); }
+  const_reference operator[](size_type n) const { return *(begin() + n); }
+
+  vector() : start(0), finish(0), end_of_storage(0) {}
+  vector(size_type n, const T& value) { fill_initialize(n, value); }
+  vector(int n, const T& value) { fill_initialize(n, value); }
+  vector(long n, const T& value) { fill_initialize(n, value); }
+  explicit vector(size_type n) { fill_initialize(n, T()); }
+
+  vector(const vector<T, Alloc>& x) {
+    start = allocate_and_copy(x.end() - x.begin(), x.begin(), x.end());
+    finish = start + (x.end() - x.begin());
+    end_of_storage = finish;
+  }
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  vector(InputIterator first, InputIterator last) :
+    start(0), finish(0), end_of_storage(0)
+  {
+    range_initialize(first, last, iterator_category(first));
+  }
+#else /* __STL_MEMBER_TEMPLATES */
+  vector(const_iterator first, const_iterator last) {
+    size_type n = 0;
+    distance(first, last, n);
+    start = allocate_and_copy(n, first, last);
+    finish = start + n;
+    end_of_storage = finish;
+  }
+#endif /* __STL_MEMBER_TEMPLATES */
+  ~vector() { 
+    destroy(start, finish);
+    deallocate();
+  }
+  vector<T, Alloc>& operator=(const vector<T, Alloc>& x);
+  void reserve(size_type n) {
+    if (capacity() < n) {
+      const size_type old_size = size();
+      iterator tmp = allocate_and_copy(n, start, finish);
+      destroy(start, finish);
+      deallocate();
+      start = tmp;
+      finish = tmp + old_size;
+      end_of_storage = start + n;
+    }
+  }
+  reference front() { return *begin(); }
+  const_reference front() const { return *begin(); }
+  reference back() { return *(end() - 1); }
+  const_reference back() const { return *(end() - 1); }
+  void push_back(const T& x) {
+    if (finish != end_of_storage) {
+      construct(finish, x);
+      ++finish;
+    }
+    else
+      insert_aux(end(), x);
+  }
+  void swap(vector<T, Alloc>& x) {
+    __STD::swap(start, x.start);
+    __STD::swap(finish, x.finish);
+    __STD::swap(end_of_storage, x.end_of_storage);
+  }
+  iterator insert(iterator position, const T& x) {
+    size_type n = position - begin();
+    if (finish != end_of_storage && position == end()) {
+      construct(finish, x);
+      ++finish;
+    }
+    else
+      insert_aux(position, x);
+    return begin() + n;
+  }
+  iterator insert(iterator position) { return insert(position, T()); }
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  void insert(iterator position, InputIterator first, InputIterator last) {
+    range_insert(position, first, last, iterator_category(first));
+  }
+#else /* __STL_MEMBER_TEMPLATES */
+  void insert(iterator position,
+              const_iterator first, const_iterator last);
+#endif /* __STL_MEMBER_TEMPLATES */
+
+  void insert (iterator pos, size_type n, const T& x);
+  void insert (iterator pos, int n, const T& x) {
+    insert(pos, (size_type) n, x);
+  }
+  void insert (iterator pos, long n, const T& x) {
+    insert(pos, (size_type) n, x);
+  }
+
+  void pop_back() {
+    --finish;
+    destroy(finish);
+  }
+  iterator erase(iterator position) {
+    if (position + 1 != end())
+      copy(position + 1, finish, position);
+    --finish;
+    destroy(finish);
+    return position;
+  }
+  iterator erase(iterator first, iterator last) {
+    iterator i = copy(last, finish, first);
+    destroy(i, finish);
+    finish = finish - (last - first);
+    return first;
+  }
+  void resize(size_type new_size, const T& x) {
+    if (new_size < size()) 
+      erase(begin() + new_size, end());
+    else
+      insert(end(), new_size - size(), x);
+  }
+  void resize(size_type new_size) { resize(new_size, T()); }
+  void clear() { erase(begin(), end()); }
+
+protected:
+  iterator allocate_and_fill(size_type n, const T& x) {
+    iterator result = data_allocator::allocate(n);
+    __STL_TRY {
+      uninitialized_fill_n(result, n, x);
+      return result;
+    }
+    __STL_UNWIND(data_allocator::deallocate(result, n));
+  }
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class ForwardIterator>
+  iterator allocate_and_copy(size_type n,
+                             ForwardIterator first, ForwardIterator last) {
+    iterator result = data_allocator::allocate(n);
+    __STL_TRY {
+      uninitialized_copy(first, last, result);
+      return result;
+    }
+    __STL_UNWIND(data_allocator::deallocate(result, n));
+  }
+#else /* __STL_MEMBER_TEMPLATES */
+  iterator allocate_and_copy(size_type n,
+                             const_iterator first, const_iterator last) {
+    iterator result = data_allocator::allocate(n);
+    __STL_TRY {
+      uninitialized_copy(first, last, result);
+      return result;
+    }
+    __STL_UNWIND(data_allocator::deallocate(result, n));
+  }
+#endif /* __STL_MEMBER_TEMPLATES */
+
+
+#ifdef __STL_MEMBER_TEMPLATES
+  template <class InputIterator>
+  void range_initialize(InputIterator first, InputIterator last,
+                        input_iterator_tag) {
+    for ( ; first != last; ++first)
+      push_back(*first);
+  }
+
+  // This function is only called by the constructor.  We have to worry
+  //  about resource leaks, but not about maintaining invariants.
+  template <class ForwardIterator>
+  void range_initialize(ForwardIterator first, ForwardIterator last,
+                        forward_iterator_tag) {
+    size_type n = 0;
+    distance(first, last, n);
+    start = allocate_and_copy(n, first, last);
+    finish = start + n;
+    end_of_storage = finish;
+  }
+
+  template <class InputIterator>
+  void range_insert(iterator pos,
+                    InputIterator first, InputIterator last,
+                    input_iterator_tag);
+
+  template <class ForwardIterator>
+  void range_insert(iterator pos,
+                    ForwardIterator first, ForwardIterator last,
+                    forward_iterator_tag);
+
+#endif /* __STL_MEMBER_TEMPLATES */
+};
+
+template <class T, class Alloc>
+inline bool operator==(const vector<T, Alloc>& x, const vector<T, Alloc>& y) {
+  return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+template <class T, class Alloc>
+inline bool operator<(const vector<T, Alloc>& x, const vector<T, Alloc>& y) {
+  return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
+
+template <class T, class Alloc>
+inline void swap(vector<T, Alloc>& x, vector<T, Alloc>& y) {
+  x.swap(y);
+}
+
+#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
+
+template <class T, class Alloc>
+vector<T, Alloc>& vector<T, Alloc>::operator=(const vector<T, Alloc>& x) {
+  if (&x != this) {
+    if (x.size() > capacity()) {
+      iterator tmp = allocate_and_copy(x.end() - x.begin(),
+                                       x.begin(), x.end());
+      destroy(start, finish);
+      deallocate();
+      start = tmp;
+      end_of_storage = start + (x.end() - x.begin());
+    }
+    else if (size() >= x.size()) {
+      iterator i = copy(x.begin(), x.end(), begin());
+      destroy(i, finish);
+    }
+    else {
+      copy(x.begin(), x.begin() + size(), start);
+      uninitialized_copy(x.begin() + size(), x.end(), finish);
+    }
+    finish = start + x.size();
+  }
+  return *this;
+}
+
+template <class T, class Alloc>
+void vector<T, Alloc>::insert_aux(iterator position, const T& x) {
+  if (finish != end_of_storage) {
+    construct(finish, *(finish - 1));
+    ++finish;
+    T x_copy = x;
+    copy_backward(position, finish - 2, 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 = data_allocator::allocate(len);
+    iterator new_finish = new_start;
+    __STL_TRY {
+      new_finish = uninitialized_copy(start, position, new_start);
+      construct(new_finish, x);
+      ++new_finish;
+      new_finish = uninitialized_copy(position, finish, new_finish);
+    }
+
+#       ifdef  __STL_USE_EXCEPTIONS 
+    catch(...) {
+      destroy(new_start, new_finish); 
+      data_allocator::deallocate(new_start, len);
+      throw;
+    }
+#       endif /* __STL_USE_EXCEPTIONS */
+    destroy(begin(), end());
+    deallocate();
+    start = new_start;
+    finish = new_finish;
+    end_of_storage = new_start + len;
+  }
+}
+
+template <class T, class Alloc>
+void vector<T, Alloc>::insert(iterator position, size_type n, const T& x) {
+  if (n != 0) {
+    if (size_type(end_of_storage - finish) >= n) {
+      T x_copy = x;
+      const size_type elems_after = finish - position;
+      iterator old_finish = finish;
+      if (elems_after > n) {
+        uninitialized_copy(finish - n, finish, finish);
+        finish += n;
+        copy_backward(position, old_finish - n, old_finish);
+        fill(position, position + n, x_copy);
+      }
+      else {
+        uninitialized_fill_n(finish, n - elems_after, x_copy);
+        finish += n - elems_after;
+        uninitialized_copy(position, old_finish, finish);
+        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 = data_allocator::allocate(len);
+      iterator new_finish = new_start;
+      __STL_TRY {
+        new_finish = uninitialized_copy(start, position, new_start);
+        new_finish = uninitialized_fill_n(new_finish, n, x);
+        new_finish = uninitialized_copy(position, finish, new_finish);
+      }
+#         ifdef  __STL_USE_EXCEPTIONS 
+      catch(...) {
+        destroy(new_start, new_finish);
+        data_allocator::deallocate(new_start, len);
+        throw;
+      }
+#         endif /* __STL_USE_EXCEPTIONS */
+      destroy(start, finish);
+      deallocate();
+      start = new_start;
+      finish = new_finish;
+      end_of_storage = new_start + len;
+    }
+  }
+}
+
+#ifdef __STL_MEMBER_TEMPLATES
+
+template <class T, class Alloc> template <class InputIterator>
+void vector<T, Alloc>::range_insert(iterator pos,
+                                    InputIterator first, InputIterator last,
+                                    input_iterator_tag) {
+  for ( ; first != last; ++first) {
+    pos = insert(pos, *first);
+    ++pos;
+  }
+}
+
+template <class T, class Alloc> template <class ForwardIterator>
+void vector<T, Alloc>::range_insert(iterator position,
+                                    ForwardIterator first,
+                                    ForwardIterator last,
+                                    forward_iterator_tag) {
+  if (first != last) {
+    size_type n = 0;
+    distance(first, last, n);
+    if (size_type(end_of_storage - finish) >= n) {
+      const size_type elems_after = finish - position;
+      iterator old_finish = finish;
+      if (elems_after > n) {
+        uninitialized_copy(finish - n, finish, finish);
+        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, finish);
+        finish += n - elems_after;
+        uninitialized_copy(position, old_finish, finish);
+        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 = data_allocator::allocate(len);
+      iterator new_finish = new_start;
+      __STL_TRY {
+        new_finish = uninitialized_copy(start, position, new_start);
+        new_finish = uninitialized_copy(first, last, new_finish);
+        new_finish = uninitialized_copy(position, finish, new_finish);
+      }
+#         ifdef __STL_USE_EXCEPTIONS
+      catch(...) {
+        destroy(new_start, new_finish);
+        data_allocator::deallocate(new_start, len);
+        throw;
+      }
+#         endif /* __STL_USE_EXCEPTIONS */
+      destroy(start, finish);
+      deallocate();
+      start = new_start;
+      finish = new_finish;
+      end_of_storage = new_start + len;
+    }
+  }
+}
+
+#else /* __STL_MEMBER_TEMPLATES */
+
+template <class T, class Alloc>
+void vector<T, Alloc>::insert(iterator position, 
+                              const_iterator first, 
+                              const_iterator last) {
+  if (first != last) {
+    size_type n = 0;
+    distance(first, last, n);
+    if (size_type(end_of_storage - finish) >= n) {
+      const size_type elems_after = finish - position;
+      iterator old_finish = finish;
+      if (elems_after > n) {
+        uninitialized_copy(finish - n, finish, finish);
+        finish += n;
+        copy_backward(position, old_finish - n, old_finish);
+        copy(first, last, position);
+      }
+      else {
+        uninitialized_copy(first + elems_after, last, finish);
+        finish += n - elems_after;
+        uninitialized_copy(position, old_finish, finish);
+        finish += elems_after;
+        copy(first, first + elems_after, position);
+      }
+    }
+    else {
+      const size_type old_size = size();
+      const size_type len = old_size + max(old_size, n);
+      iterator new_start = data_allocator::allocate(len);
+      iterator new_finish = new_start;
+      __STL_TRY {
+        new_finish = uninitialized_copy(start, position, new_start);
+        new_finish = uninitialized_copy(first, last, new_finish);
+        new_finish = uninitialized_copy(position, finish, new_finish);
+      }
+#         ifdef __STL_USE_EXCEPTIONS
+      catch(...) {
+        destroy(new_start, new_finish);
+        data_allocator::deallocate(new_start, len);
+        throw;
+      }
+#         endif /* __STL_USE_EXCEPTIONS */
+      destroy(start, finish);
+      deallocate();
+      start = new_start;
+      finish = new_finish;
+      end_of_storage = new_start + len;
+    }
+  }
+}
+
+#endif /* __STL_MEMBER_TEMPLATES */
+
+#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
+#pragma reset woff 1174
+#endif
+
+__STL_END_NAMESPACE 
+
+#endif /* __SGI_STL_INTERNAL_VECTOR_H */
+
+// Local Variables:
+// mode:C++
+// End:
index 18d9952..8799393 100644 (file)
 #ifndef __SGI_STL_TEMPBUF_H
 #define __SGI_STL_TEMPBUF_H
 
+#ifndef __SGI_STL_PAIR_H
+#include <pair.h>
+#endif
 #include <limits.h>
 #include <stddef.h>
 #include <stdlib.h>
-#include <pair.h>
+#ifndef __TYPE_TRAITS_H
 #include <type_traits.h>
+#endif
+#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H
+#include <stl_construct.h>
+#endif
+#ifndef __SGI_STL_INTERNAL_TEMPBUF_H
+#include <stl_tempbuf.h>
+#endif
 
-template <class T>
-pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t len, T*) {
-  if (len > ptrdiff_t(INT_MAX / sizeof(T)))
-    len = INT_MAX / sizeof(T);
-
-  while (len > 0) {
-    T* tmp = (T*) malloc((size_t)len * sizeof(T));
-    if (tmp != 0)
-      return pair<T*, ptrdiff_t>(tmp, len);
-    len /= 2;
-  }
-
-  return pair<T*, ptrdiff_t>((T*)0, 0);
-}
-
-template <class T>
-void return_temporary_buffer(T* p) {
-  free(p);
-}
-
-template <class ForwardIterator,
-          class T /* = iterator_traits<ForwardIterator>::value_type */>
-class temporary_buffer {
-private:
-  ptrdiff_t original_len;
-  ptrdiff_t len;
-  T* buffer;
+#ifdef __STL_USE_NAMESPACES
 
-  void allocate_buffer() {
-    original_len = len;
-    buffer = 0;
+using __STD::get_temporary_buffer;
+using __STD::return_temporary_buffer;
+using __STD::temporary_buffer;
 
-    if (len > (ptrdiff_t)(INT_MAX / sizeof(T)))
-      len = INT_MAX / sizeof(T);
-
-    while (len > 0) {
-      buffer = (T*) malloc(len * sizeof(T));
-      if (buffer)
-        break;
-      len /= 2;
-    }
-  }
-
-  void initialize_buffer(const T&, __true_type) {}
-  void initialize_buffer(const T& val, __false_type) {
-    uninitialized_fill_n(buffer, len, val);
-  }
-
-public:
-  ptrdiff_t size() const { return len; }
-  ptrdiff_t requested_size() const { return original_len; }
-  T* begin() { return buffer; }
-  T* end() { return buffer + len; }
-
-  temporary_buffer(ForwardIterator first, ForwardIterator last) {
-#ifdef __STL_USE_EXCEPTIONS
-    try {
-#endif      
-      len = 0;
-      distance(first, last, len);
-      allocate_buffer();
-      if (len > 0)
-        initialize_buffer(*first,
-                          __type_traits<T>::has_trivial_default_constructor());
-#ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      free(buffer);
-      buffer = 0;
-      len = 0;
-      throw;
-    }
-#endif      
-  }
-  ~temporary_buffer() {  
-    destroy(buffer, buffer + len);
-    free(buffer);
-  }
-
-private:
-  temporary_buffer(const temporary_buffer&) {}
-  void operator=(const temporary_buffer&) {}
-};
+#endif /* __STL_USE_NAMESPACES */
 
 #endif /* __SGI_STL_TEMPBUF_H */
+
+// Local Variables:
+// mode:C++
+// End:
index 80e0caf..77c57cb 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright (c) 1996
+ * Copyright (c) 1996,1997
  * Silicon Graphics Computer Systems, Inc.
  *
  * Permission to use, copy, modify, distribute and sell this software
 #ifndef __SGI_STL_TREE_H
 #define __SGI_STL_TREE_H
 
-/*
-
-Red-black tree class, designed for use in implementing STL
-associative containers (set, multiset, map, and multimap). The
-insertion and deletion algorithms are based on those in Cormen,
-Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 1990),
-except that
-
-(1) the header cell is maintained with links not only to the root
-but also to the leftmost node of the tree, to enable constant time
-begin(), and to the rightmost node of the tree, to enable linear time
-performance when used with the generic set algorithms (set_union,
-etc.);
-
-(2) when a node being deleted has two children its successor node is
-relinked into its place, rather than copied, so that the only
-iterators invalidated are those referring to the deleted node.
-
-*/
-
-#include <stddef.h>
+#ifndef __SGI_STL_INTERNAL_TREE_H
+#include <stl_tree.h>
+#endif
 #include <algobase.h>
-#include <iterator.h>
 #include <alloc.h>
 
-
-typedef bool __rb_tree_color_type;
-const __rb_tree_color_type __rb_tree_red = false;
-const __rb_tree_color_type __rb_tree_black = true;
-
-struct __rb_tree_node_base
-{
-  typedef __rb_tree_color_type color_type;
-  typedef __rb_tree_node_base* base_ptr;
-
-  color_type color; 
-  base_ptr parent;
-  base_ptr left;
-  base_ptr right;
-
-  static base_ptr minimum(base_ptr x)
-  {
-    while (x->left != 0) x = x->left;
-    return x;
-  }
-
-  static base_ptr maximum(base_ptr x)
-  {
-    while (x->right != 0) x = x->right;
-    return x;
-  }
-};
-
-template <class Value>
-struct __rb_tree_node : public __rb_tree_node_base
-{
-  typedef __rb_tree_node<Value>* link_type;
-  Value value_field;
-};
-
-
-struct __rb_tree_base_iterator
-{
-  typedef __rb_tree_node_base::base_ptr base_ptr;
-  typedef bidirectional_iterator_tag iterator_category;
-  typedef ptrdiff_t difference_type;
-  base_ptr node;
-
-  void increment()
-  {
-    if (node->right != 0) {
-      node = node->right;
-      while (node->left != 0)
-        node = node->left;
-    }
-    else {
-      base_ptr y = node->parent;
-      while (node == y->right) {
-        node = y;
-        y = y->parent;
-      }
-      if (node->right != y)
-        node = y;
-    }
-  }
-
-  void decrement()
-  {
-    if (node->color == __rb_tree_red &&
-        node->parent->parent == node)
-      node = node->right;
-    else if (node->left != 0) {
-      base_ptr y = node->left;
-      while (y->right != 0)
-        y = y->right;
-      node = y;
-    }
-    else {
-      base_ptr y = node->parent;
-      while (node == y->left) {
-        node = y;
-        y = y->parent;
-      }
-      node = y;
-    }
-  }
-};
-
-template <class Value, class Ref, class Ptr>
-struct __rb_tree_iterator : public __rb_tree_base_iterator
-{
-  typedef Value value_type;
-  typedef Value& reference;
-  typedef Value* pointer;
-  typedef __rb_tree_iterator<Value, Value&, Value*>             iterator;
-  typedef __rb_tree_iterator<Value, const Value&, const Value*> const_iterator;
-  typedef __rb_tree_iterator<Value, Ref, Ptr>                   self;
-  typedef __rb_tree_node<Value>* link_type;
-
-  __rb_tree_iterator() {}
-  __rb_tree_iterator(link_type x) { node = x; }
-  __rb_tree_iterator(const iterator& it) { node = it.node; }
-
-  reference operator*() const { return link_type(node)->value_field; }
-#ifndef __SGI_STL_NO_ARROW_OPERATOR
-  pointer operator->() const { return &(operator*()); }
-#endif /* __SGI_STL_NO_ARROW_OPERATOR */
-
-  self& operator++() { increment(); return *this; }
-  self operator++(int) {
-    self tmp = *this;
-    increment();
-    return tmp;
-  }
-    
-  self& operator--() { decrement(); return *this; }
-  self operator--(int) {
-    self tmp = *this;
-    decrement();
-    return tmp;
-  }
-};
-
-inline bool operator==(const __rb_tree_base_iterator& x,
-                       const __rb_tree_base_iterator& y) {
-  return x.node == y.node;
-}
-
-inline bool operator!=(const __rb_tree_base_iterator& x,
-                       const __rb_tree_base_iterator& y) {
-  return x.node != y.node;
-}
-
-#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
-
-inline bidirectional_iterator_tag
-iterator_category(const __rb_tree_base_iterator&) {
-  return bidirectional_iterator_tag();
-}
-
-inline __rb_tree_base_iterator::difference_type*
-distance_type(const __rb_tree_base_iterator&) {
-  return (__rb_tree_base_iterator::difference_type*) 0;
-}
-
-template <class Value, class Ref, class Ptr>
-inline Value* value_type(const __rb_tree_iterator<Value, Ref, Ptr>&) {
-  return (Value*) 0;
-}
-
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-
-inline void 
-__rb_tree_rotate_left(__rb_tree_node_base* x, __rb_tree_node_base*& root)
-{
-  __rb_tree_node_base* y = x->right;
-  x->right = y->left;
-  if (y->left !=0)
-    y->left->parent = x;
-  y->parent = x->parent;
-
-  if (x == root)
-    root = y;
-  else if (x == x->parent->left)
-    x->parent->left = y;
-  else
-    x->parent->right = y;
-  y->left = x;
-  x->parent = y;
-}
-
-inline void 
-__rb_tree_rotate_right(__rb_tree_node_base* x, __rb_tree_node_base*& root)
-{
-  __rb_tree_node_base* y = x->left;
-  x->left = y->right;
-  if (y->right != 0)
-    y->right->parent = x;
-  y->parent = x->parent;
-
-  if (x == root)
-    root = y;
-  else if (x == x->parent->right)
-    x->parent->right = y;
-  else
-    x->parent->left = y;
-  y->right = x;
-  x->parent = y;
-}
-
-inline void 
-__rb_tree_rebalance(__rb_tree_node_base* x, __rb_tree_node_base*& root)
-{
-  x->color = __rb_tree_red;
-  while (x != root && x->parent->color == __rb_tree_red) {
-    if (x->parent == x->parent->parent->left) {
-      __rb_tree_node_base* y = x->parent->parent->right;
-      if (y && y->color == __rb_tree_red) {
-        x->parent->color = __rb_tree_black;
-        y->color = __rb_tree_black;
-        x->parent->parent->color = __rb_tree_red;
-        x = x->parent->parent;
-      }
-      else {
-        if (x == x->parent->right) {
-          x = x->parent;
-          __rb_tree_rotate_left(x, root);
-        }
-        x->parent->color = __rb_tree_black;
-        x->parent->parent->color = __rb_tree_red;
-        __rb_tree_rotate_right(x->parent->parent, root);
-      }
-    }
-    else {
-      __rb_tree_node_base* y = x->parent->parent->left;
-      if (y && y->color == __rb_tree_red) {
-        x->parent->color = __rb_tree_black;
-        y->color = __rb_tree_black;
-        x->parent->parent->color = __rb_tree_red;
-        x = x->parent->parent;
-      }
-      else {
-        if (x == x->parent->left) {
-          x = x->parent;
-          __rb_tree_rotate_right(x, root);
-        }
-        x->parent->color = __rb_tree_black;
-        x->parent->parent->color = __rb_tree_red;
-        __rb_tree_rotate_left(x->parent->parent, root);
-      }
-    }
-  }
-  root->color = __rb_tree_black;
-}
-
-inline __rb_tree_node_base*
-__rb_tree_rebalance_for_erase(__rb_tree_node_base* z,
-                              __rb_tree_node_base*& root,
-                              __rb_tree_node_base*& leftmost,
-                              __rb_tree_node_base*& rightmost)
-{
-  __rb_tree_node_base* y = z;
-  __rb_tree_node_base* x = 0;
-  __rb_tree_node_base* x_parent = 0;
-  if (y->left == 0)             // z has at most one non-null child. y == z.
-    x = y->right;               // x might be null.
-  else
-    if (y->right == 0)          // z has exactly one non-null child.  y == z.
-      x = y->left;              // x is not null.
-    else {                      // z has two non-null children.  Set y to
-      y = y->right;             //   z's successor.  x might be null.
-      while (y->left != 0)
-        y = y->left;
-      x = y->right;
-    }
-  if (y != z) {                 // relink y in place of z.  y is z's successor
-    z->left->parent = y; 
-    y->left = z->left;
-    if (y != z->right) {
-      x_parent = y->parent;
-      if (x) x->parent = y->parent;
-      y->parent->left = x;      // y must be a left child
-      y->right = z->right;
-      z->right->parent = y;
-    }
-    else
-      x_parent = y;  
-    if (root == z)
-      root = y;
-    else if (z->parent->left == z)
-      z->parent->left = y;
-    else 
-      z->parent->right = y;
-    y->parent = z->parent;
-    ::swap(y->color, z->color);
-    y = z;
-    // y now points to node to be actually deleted
-  }
-  else {                        // y == z
-    x_parent = y->parent;
-    if (x) x->parent = y->parent;   
-    if (root == z)
-      root = x;
-    else 
-      if (z->parent->left == z)
-        z->parent->left = x;
-      else
-        z->parent->right = x;
-    if (leftmost == z) 
-      if (z->right == 0)        // z->left must be null also
-        leftmost = z->parent;
-    // makes leftmost == header if z == root
-      else
-        leftmost = __rb_tree_node_base::minimum(x);
-    if (rightmost == z)  
-      if (z->left == 0)         // z->right must be null also
-        rightmost = z->parent;  
-    // makes rightmost == header if z == root
-      else                      // x == z->left
-        rightmost = __rb_tree_node_base::maximum(x);
-  }
-  if (y->color != __rb_tree_red) { 
-    while (x != root && (x == 0 || x->color == __rb_tree_black))
-      if (x == x_parent->left) {
-        __rb_tree_node_base* w = x_parent->right;
-        if (w->color == __rb_tree_red) {
-          w->color = __rb_tree_black;
-          x_parent->color = __rb_tree_red;
-          __rb_tree_rotate_left(x_parent, root);
-          w = x_parent->right;
-        }
-        if ((w->left == 0 || w->left->color == __rb_tree_black) &&
-            (w->right == 0 || w->right->color == __rb_tree_black)) {
-          w->color = __rb_tree_red;
-          x = x_parent;
-          x_parent = x_parent->parent;
-        } else {
-          if (w->right == 0 || w->right->color == __rb_tree_black) {
-            if (w->left) w->left->color = __rb_tree_black;
-            w->color = __rb_tree_red;
-            __rb_tree_rotate_right(w, root);
-            w = x_parent->right;
-          }
-          w->color = x_parent->color;
-          x_parent->color = __rb_tree_black;
-          if (w->right) w->right->color = __rb_tree_black;
-          __rb_tree_rotate_left(x_parent, root);
-          break;
-        }
-      } else {                  // same as above, with right <-> left.
-        __rb_tree_node_base* w = x_parent->left;
-        if (w->color == __rb_tree_red) {
-          w->color = __rb_tree_black;
-          x_parent->color = __rb_tree_red;
-          __rb_tree_rotate_right(x_parent, root);
-          w = x_parent->left;
-        }
-        if ((w->right == 0 || w->right->color == __rb_tree_black) &&
-            (w->left == 0 || w->left->color == __rb_tree_black)) {
-          w->color = __rb_tree_red;
-          x = x_parent;
-          x_parent = x_parent->parent;
-        } else {
-          if (w->left == 0 || w->left->color == __rb_tree_black) {
-            if (w->right) w->right->color = __rb_tree_black;
-            w->color = __rb_tree_red;
-            __rb_tree_rotate_left(w, root);
-            w = x_parent->left;
-          }
-          w->color = x_parent->color;
-          x_parent->color = __rb_tree_black;
-          if (w->left) w->left->color = __rb_tree_black;
-          __rb_tree_rotate_right(x_parent, root);
-          break;
-        }
-      }
-    if (x) x->color = __rb_tree_black;
-  }
-  return y;
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare,
-          class Alloc = alloc>
-class rb_tree {
-protected:
-    typedef void* void_pointer;
-    typedef __rb_tree_node_base* base_ptr;
-    typedef __rb_tree_node<Value> rb_tree_node;
-    typedef simple_alloc<rb_tree_node, Alloc> rb_tree_node_allocator;
-    typedef __rb_tree_color_type color_type;
-public:
-    typedef Key key_type;
-    typedef Value value_type;
-    typedef value_type* pointer;
-    typedef const value_type* const_pointer;
-    typedef value_type& reference;
-    typedef const value_type& const_reference;
-    typedef rb_tree_node* link_type;
-    typedef size_t size_type;
-    typedef ptrdiff_t difference_type;
-protected:
-    link_type get_node() { return rb_tree_node_allocator::allocate(); }
-    void put_node(link_type p) { rb_tree_node_allocator::deallocate(p); }
-
-    link_type create_node(const value_type& x) {
-      link_type tmp = get_node();
-#         ifdef __STL_USE_EXCEPTIONS
-      try {
-#         endif /* __STL_USE_EXCEPTIONS */
-        construct(&tmp->value_field, x);
-        return tmp;
-#         ifdef __STL_USE_EXCEPTIONS
-      }
-      catch(...) {
-        put_node(tmp);
-        throw;
-      }
-#         endif /* __STL_USE_EXCEPTIONS */
-    }
-
-    link_type clone_node(link_type x) {
-      link_type tmp = create_node(x->value_field);
-      tmp->color = x->color;
-      tmp->left = 0;
-      tmp->right = 0;
-      return tmp;
-    }
-
-    void destroy_node(link_type p) {
-      destroy(&p->value_field);
-      put_node(p);
-    }
-
-protected:
-    size_type node_count; // keeps track of size of tree
-    link_type header;  
-    Compare key_compare;
-
-    link_type& root() const { return (link_type&) header->parent; }
-    link_type& leftmost() const { return (link_type&) header->left; }
-    link_type& rightmost() const { return (link_type&) header->right; }
-
-    static link_type& left(link_type x) { return (link_type&)(x->left); }
-    static link_type& right(link_type x) { return (link_type&)(x->right); }
-    static link_type& parent(link_type x) { return (link_type&)(x->parent); }
-    static reference value(link_type x) { return x->value_field; }
-    static const Key& key(link_type x) { return KeyOfValue()(value(x)); }
-    static color_type& color(link_type x) { return (color_type&)(x->color); }
-
-    static link_type& left(base_ptr x) { return (link_type&)(x->left); }
-    static link_type& right(base_ptr x) { return (link_type&)(x->right); }
-    static link_type& parent(base_ptr x) { return (link_type&)(x->parent); }
-    static reference value(base_ptr x) { return ((link_type)x)->value_field; }
-    static const Key& key(base_ptr x) { return KeyOfValue()(value(link_type(x)));} 
-    static color_type& color(base_ptr x) { return (color_type&)(link_type(x)->color); }
-
-    static link_type minimum(link_type x) { 
-        return (link_type)  __rb_tree_node_base::minimum(x);
-    }
-    static link_type maximum(link_type x) {
-        return (link_type) __rb_tree_node_base::maximum(x);
-    }
-
-public:
-    typedef __rb_tree_iterator<value_type, reference, pointer> iterator;
-    typedef __rb_tree_iterator<value_type, const_reference, const_pointer> 
-            const_iterator;
-
-#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
-    typedef reverse_iterator<const_iterator> const_reverse_iterator;
-    typedef reverse_iterator<iterator> reverse_iterator;
-#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-    typedef reverse_bidirectional_iterator<iterator, value_type, reference,
-                                           difference_type>
-        reverse_iterator; 
-    typedef reverse_bidirectional_iterator<const_iterator, value_type,
-                                           const_reference, difference_type>
-        const_reverse_iterator;
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ 
-private:
-    iterator __insert(base_ptr x, base_ptr y, const value_type& v);
-    link_type __copy(link_type x, link_type p);
-    void __erase(link_type x);
-    void init() {
-        header = get_node();
-        color(header) = __rb_tree_red; // used to distinguish header from 
-                                       // root, in iterator.operator++
-        root() = 0;
-        leftmost() = header;
-        rightmost() = header;
-    }
-public:
-                                // allocation/deallocation
-    rb_tree(const Compare& comp = Compare())
-      : node_count(0), key_compare(comp) { init(); }
-
-    rb_tree(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x) 
-      : node_count(0), key_compare(x.key_compare) { 
-        header = get_node();
-        color(header) = __rb_tree_red;
-        if (x.root() == 0) {
-          root() = 0;
-          leftmost() = header;
-          rightmost() = header;
-        }
-        else {
-#             ifdef __STL_USE_EXCEPTIONS
-          try {
-#             endif /* __STL_USE_EXCEPTIONS */
-            root() = __copy(x.root(), header);
-#             ifdef __STL_USE_EXCEPTIONS
-          }
-          catch(...) {
-            put_node(header);
-            throw;
-          }
-#             endif /* __STL_USE_EXCEPTIONS */
-          leftmost() = minimum(root());
-          rightmost() = maximum(root());
-        }
-        node_count = x.node_count;
-    }
-    ~rb_tree() {
-        clear();
-        put_node(header);
-    }
-    rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& 
-        operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x);
-
-public:    
-                                // accessors:
-    Compare key_comp() const { return key_compare; }
-    iterator begin() { return leftmost(); }
-    const_iterator begin() const { return leftmost(); }
-    iterator end() { return header; }
-    const_iterator end() const { return header; }
-    reverse_iterator rbegin() { return reverse_iterator(end()); }
-    const_reverse_iterator rbegin() const { 
-        return const_reverse_iterator(end()); 
-    }
-    reverse_iterator rend() { return reverse_iterator(begin()); }
-    const_reverse_iterator rend() const { 
-        return const_reverse_iterator(begin());
-    } 
-    bool empty() const { return node_count == 0; }
-    size_type size() const { return node_count; }
-    size_type max_size() const { return size_type(-1); }
-
-    void swap(rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& t) {
-        ::swap(header, t.header);
-        ::swap(node_count, t.node_count);
-        ::swap(key_compare, t.key_compare);
-    }
-    
-public:
-                                // insert/erase
-    pair<iterator,bool> insert_unique(const value_type& x);
-    iterator insert_equal(const value_type& x);
-
-    iterator insert_unique(iterator position, const value_type& x);
-    iterator insert_equal(iterator position, const value_type& x);
-
-#ifdef __STL_MEMBER_TEMPLATES  
-    template <class InputIterator>
-    void insert_unique(InputIterator first, InputIterator last);
-    template <class InputIterator>
-    void insert_equal(InputIterator first, InputIterator last);
-#else /* __STL_MEMBER_TEMPLATES */
-    void insert_unique(const_iterator first, const_iterator last);
-    void insert_unique(const value_type* first, const value_type* last);
-    void insert_equal(const_iterator first, const_iterator last);
-    void insert_equal(const value_type* first, const value_type* last);
-#endif /* __STL_MEMBER_TEMPLATES */
-
-    void erase(iterator position);
-    size_type erase(const key_type& x);
-    void erase(iterator first, iterator last);
-    void erase(const key_type* first, const key_type* last);
-    void clear() {
-      if (node_count != 0) {
-        __erase(root());
-        leftmost() = header;
-        root() = 0;
-        rightmost() = header;
-        node_count = 0;
-      }
-    }      
-
-public:
-                                // set operations:
-    iterator find(const key_type& x);
-    const_iterator find(const key_type& x) const;
-    size_type count(const key_type& x) const;
-    iterator lower_bound(const key_type& x);
-    const_iterator lower_bound(const key_type& x) const;
-    iterator upper_bound(const key_type& x);
-    const_iterator upper_bound(const key_type& x) const;
-    pair<iterator,iterator> equal_range(const key_type& x);
-    pair<const_iterator, const_iterator> equal_range(const key_type& x) const;
-
-public:
-                                // Debugging.
-  bool __rb_verify() const;
-};
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-inline bool operator==(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x, 
-                       const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& y) {
-    return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-inline bool operator<(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x, 
-                      const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& y) {
-    return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& 
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::
-operator=(const rb_tree<Key, Value, KeyOfValue, Compare, Alloc>& x) {
-  if (this != &x) {
-                                // Note that Key may be a constant type.
-    clear();
-    node_count = 0;
-    key_compare = x.key_compare;        
-    if (x.root() == 0) {
-      root() = 0;
-      leftmost() = header;
-      rightmost() = header;
-    }
-    else {
-      root() = __copy(x.root(), header);
-      leftmost() = minimum(root());
-      rightmost() = maximum(root());
-      node_count = x.node_count;
-    }
-  }
-  return *this;
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::
-__insert(base_ptr x_, base_ptr y_, const Value& v) {
-  link_type x = (link_type) x_;
-  link_type y = (link_type) y_;
-  link_type z;
-
-  if (y == header || x != 0 || key_compare(KeyOfValue()(v), key(y))) {
-    z = create_node(v);
-    left(y) = z;                // also makes leftmost() = z when y == header
-    if (y == header) {
-      root() = z;
-      rightmost() = z;
-    }
-    else if (y == leftmost())
-      leftmost() = z;           // maintain leftmost() pointing to min node
-  }
-  else {
-    z = create_node(v);
-    right(y) = z;
-    if (y == rightmost())
-      rightmost() = z;          // maintain rightmost() pointing to max node
-  }
-  parent(z) = y;
-  left(z) = 0;
-  right(z) = 0;
-  __rb_tree_rebalance(z, header->parent);
-  ++node_count;
-  return iterator(z);
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_equal(const Value& v)
-{
-    link_type y = header;
-    link_type x = root();
-    while (x != 0) {
-        y = x;
-        x = key_compare(KeyOfValue()(v), key(x)) ? left(x) : right(x);
-    }
-    return __insert(x, y, v);
-}
-
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-pair<rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator, bool>
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::insert_unique(const Value& v)
-{
-    link_type y = header;
-    link_type x = root();
-    bool comp = true;
-    while (x != 0) {
-        y = x;
-        comp = key_compare(KeyOfValue()(v), key(x));
-        x = comp ? left(x) : right(x);
-    }
-    iterator j = iterator(y);   
-    if (comp)
-        if (j == begin())     
-            return pair<iterator,bool>(__insert(x, y, v), true);
-        else
-            --j;
-    if (key_compare(key(j.node), KeyOfValue()(v)))
-        return pair<iterator,bool>(__insert(x, y, v), true);
-    return pair<iterator,bool>(j, false);
-}
-
-
-template <class Key, class Val, class KeyOfValue, class Compare, class Alloc>
-rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::iterator 
-rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::insert_unique(iterator position,
-                                                             const Val& v) {
-    if (position.node == header->left) // begin()
-        if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node)))
-            return __insert(position.node, position.node, v);
-                                // first argument just needs to be non-null 
-        else
-            return insert_unique(v).first;
-    else if (position.node == header) // end()
-        if (key_compare(key(rightmost()), KeyOfValue()(v)))
-            return __insert(0, rightmost(), v);
-        else
-            return insert_unique(v).first;
-    else {
-        iterator before = position;
-        --before;
-        if (key_compare(key(before.node), KeyOfValue()(v))
-            && key_compare(KeyOfValue()(v), key(position.node)))
-            if (right(before.node) == 0)
-                return __insert(0, before.node, v); 
-            else
-                return __insert(position.node, position.node, v);
-                                // first argument just needs to be non-null 
-        else
-            return insert_unique(v).first;
-    }
-}
-
-template <class Key, class Val, class KeyOfValue, class Compare, class Alloc>
-rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::iterator 
-rb_tree<Key, Val, KeyOfValue, Compare, Alloc>::insert_equal(iterator position,
-                                                            const Val& v) {
-    if (position.node == header->left) // begin()
-        if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node)))
-            return __insert(position.node, position.node, v);
-            // first argument just needs to be non-null 
-        else
-            return insert_equal(v);
-    else if (position.node == header) // end()
-        if (!key_compare(KeyOfValue()(v), key(rightmost())))
-            return __insert(0, rightmost(), v);
-        else
-            return insert_equal(v);
-    else {
-        iterator before = position;
-        --before;
-        if (!key_compare(KeyOfValue()(v), key(before.node))
-            && !key_compare(key(position.node), KeyOfValue()(v)))
-            if (right(before.node) == 0)
-                return __insert(0, before.node, v); 
-            else
-                return __insert(position.node, position.node, v);
-                // first argument just needs to be non-null 
-        else
-            return insert_equal(v);
-    }
-}
-
-#ifdef __STL_MEMBER_TEMPLATES  
-
-template <class K, class V, class KoV, class Cmp, class Al> template<class II>
-void rb_tree<K, V, KoV, Cmp, Al>::insert_equal(II first, II last) {
-  for ( ; first != last; ++first)
-    insert_equal(*first);
-}
-
-template <class K, class V, class KoV, class Cmp, class Al> template<class II>
-void rb_tree<K, V, KoV, Cmp, Al>::insert_unique(II first, II last) {
-  for ( ; first != last; ++first)
-    insert_unique(*first);
-}
-
-#else /* __STL_MEMBER_TEMPLATES */
-
-template <class K, class V, class KoV, class Cmp, class Al>
-void
-rb_tree<K, V, KoV, Cmp, Al>::insert_equal(const V* first, const V* last) {
-  for ( ; first != last; ++first)
-    insert_equal(*first);
-}
-
-template <class K, class V, class KoV, class Cmp, class Al>
-void
-rb_tree<K, V, KoV, Cmp, Al>::insert_equal(const_iterator first,
-                                          const_iterator last) {
-  for ( ; first != last; ++first)
-    insert_equal(*first);
-}
-
-template <class K, class V, class KoV, class Cmp, class A>
-void 
-rb_tree<K, V, KoV, Cmp, A>::insert_unique(const V* first, const V* last) {
-  for ( ; first != last; ++first)
-    insert_unique(*first);
-}
-
-template <class K, class V, class KoV, class Cmp, class A>
-void 
-rb_tree<K, V, KoV, Cmp, A>::insert_unique(const_iterator first,
-                                          const_iterator last) {
-  for ( ; first != last; ++first)
-    insert_unique(*first);
-}
-
-#endif /* __STL_MEMBER_TEMPLATES */
-         
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-inline void
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(iterator position) {
-  link_type y = (link_type) __rb_tree_rebalance_for_erase(position.node,
-                                                          header->parent,
-                                                          header->left,
-                                                          header->right);
-  destroy_node(y);
-  --node_count;
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::size_type 
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(const Key& x) {
-    pair<iterator,iterator> p = equal_range(x);
-    size_type n = 0;
-    distance(p.first, p.second, n);
-    erase(p.first, p.second);
-    return n;
-}
-
-template <class K, class V, class KeyOfValue, class Compare, class Alloc>
-rb_tree<K, V, KeyOfValue, Compare, Alloc>::link_type 
-rb_tree<K, V, KeyOfValue, Compare, Alloc>::__copy(link_type x, link_type p) {
-                                // structural copy.  x and p must be non-null.
-  link_type top = clone_node(x);
-  top->parent = p;
-#     ifdef __STL_USE_EXCEPTIONS
-  try {
-#     endif /* __STL_USE_EXCEPTIONS */
-    if (x->right)
-      top->right = __copy(right(x), top);
-    p = top;
-    x = left(x);
-
-    while (x != 0) {
-      link_type y = clone_node(x);
-      p->left = y;
-      y->parent = p;
-      if (x->right)
-        y->right = __copy(right(x), y);
-      p = y;
-      x = left(x);
-    }
-#     ifdef __STL_USE_EXCEPTIONS
-  }
-  catch(...) {
-    __erase(top);
-    throw;
-  }
-#     endif /* __STL_USE_EXCEPTIONS */
-
-  return top;
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::__erase(link_type x) {
-                                // erase without rebalancing
-  while (x != 0) {
-    __erase(right(x));
-    link_type y = left(x);
-    destroy_node(x);
-    x = y;
-  }
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(iterator first, 
-                                                            iterator last) {
-    if (first == begin() && last == end())
-        clear();
-    else
-        while (first != last) erase(first++);
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-void rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::erase(const Key* first, 
-                                                            const Key* last) {
-    while (first != last) erase(*first++);
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator 
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::find(const Key& k) {
-   link_type y = header;        // Last node which is not less than k. 
-   link_type x = root();        // Current node. 
-
-   while (x != 0) 
-     if (!key_compare(key(x), k))
-       y = x, x = left(x);
-     else
-       x = right(x);
-
-   iterator j = iterator(y);   
-   return (j == end() || key_compare(k, key(j.node))) ? end() : j;
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator 
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::find(const Key& k) const {
-   link_type y = header; /* Last node which is not less than k. */
-   link_type x = root(); /* Current node. */
-
-   while (x != 0) {
-     if (!key_compare(key(x), k))
-       y = x, x = left(x);
-     else
-       x = right(x);
-   }
-   const_iterator j = const_iterator(y);   
-   return (j == end() || key_compare(k, key(j.node))) ? end() : j;
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::size_type 
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::count(const Key& k) const {
-    pair<const_iterator, const_iterator> p = equal_range(k);
-    size_type n = 0;
-    distance(p.first, p.second, n);
-    return n;
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator 
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::lower_bound(const Key& k) {
-   link_type y = header; /* Last node which is not less than k. */
-   link_type x = root(); /* Current node. */
-
-   while (x != 0) 
-     if (!key_compare(key(x), k))
-       y = x, x = left(x);
-     else
-       x = right(x);
-
-   return iterator(y);
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator 
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::lower_bound(const Key& k) const {
-   link_type y = header; /* Last node which is not less than k. */
-   link_type x = root(); /* Current node. */
-
-   while (x != 0) 
-     if (!key_compare(key(x), k))
-       y = x, x = left(x);
-     else
-       x = right(x);
-
-   return const_iterator(y);
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator 
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::upper_bound(const Key& k) {
-  link_type y = header; /* Last node which is greater than k. */
-  link_type x = root(); /* Current node. */
-
-   while (x != 0) 
-     if (key_compare(k, key(x)))
-       y = x, x = left(x);
-     else
-       x = right(x);
-
-   return iterator(y);
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator 
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::upper_bound(const Key& k) const {
-  link_type y = header; /* Last node which is greater than k. */
-  link_type x = root(); /* Current node. */
-
-   while (x != 0) 
-     if (key_compare(k, key(x)))
-       y = x, x = left(x);
-     else
-       x = right(x);
-
-   return const_iterator(y);
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-inline pair<rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator,
-            rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::iterator>
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::equal_range(const Key& k) {
-    return pair<iterator, iterator>(lower_bound(k), upper_bound(k));
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-inline pair<rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator,
-            rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::const_iterator>
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::equal_range(const Key& k) const {
-    return pair<const_iterator,const_iterator>(lower_bound(k), upper_bound(k));
-}
-
-inline int __black_count(__rb_tree_node_base* node, __rb_tree_node_base* root)
-{
-  if (node == 0)
-    return 0;
-  else {
-    int bc = node->color == __rb_tree_black ? 1 : 0;
-    if (node == root)
-      return bc;
-    else
-      return bc + __black_count(node->parent, root);
-  }
-}
-
-template <class Key, class Value, class KeyOfValue, class Compare, class Alloc>
-bool 
-rb_tree<Key, Value, KeyOfValue, Compare, Alloc>::__rb_verify() const
-{
-  if (node_count == 0 || begin() == end())
-    return node_count == 0 && begin() == end() &&
-      header->left == header && header->right == header;
-  
-  int len = __black_count(leftmost(), root());
-  for (const_iterator it = begin(); it != end(); ++it) {
-    link_type x = (link_type) it.node;
-    link_type L = left(x);
-    link_type R = right(x);
-
-    if (x->color == __rb_tree_red)
-      if ((L && L->color == __rb_tree_red) ||
-          (R && R->color == __rb_tree_red))
-        return false;
-
-    if (L && key_compare(key(x), key(L)))
-      return false;
-    if (R && key_compare(key(R), key(x)))
-      return false;
-
-    if (!L && !R && __black_count(x, root()) != len)
-      return false;
-  }
-
-  if (leftmost() != __rb_tree_node_base::minimum(root()))
-    return false;
-  if (rightmost() != __rb_tree_node_base::maximum(root()))
-    return false;
-
-  return true;
-}
+#ifdef __STL_USE_NAMESPACES
+using __STD::rb_tree;
+#endif /* __STL_USE_NAMESPACES */
 
 #endif /* __SGI_STL_TREE_H */
+
+// Local Variables:
+// mode:C++
+// End:
index 6ca0137..a7b977c 100644 (file)
@@ -15,7 +15,9 @@
 #ifndef __TYPE_TRAITS_H
 #define __TYPE_TRAITS_H
 
+#ifndef __STL_CONFIG_H
 #include <stl_config.h>
+#endif
 
 /*
 This header file provides a framework for allowing compile time dispatch
@@ -88,7 +90,7 @@ struct __type_traits {
 //  have built-in __types_traits support, and essential for compilers
 //  that don't.
 
-struct __type_traits<char> {
+__STL_TEMPLATE_NULL struct __type_traits<char> {
    typedef __true_type    has_trivial_default_constructor;
    typedef __true_type    has_trivial_copy_constructor;
    typedef __true_type    has_trivial_assignment_operator;
@@ -96,7 +98,7 @@ struct __type_traits<char> {
    typedef __true_type    is_POD_type;
 };
 
-struct __type_traits<signed char> {
+__STL_TEMPLATE_NULL struct __type_traits<signed char> {
    typedef __true_type    has_trivial_default_constructor;
    typedef __true_type    has_trivial_copy_constructor;
    typedef __true_type    has_trivial_assignment_operator;
@@ -104,7 +106,7 @@ struct __type_traits<signed char> {
    typedef __true_type    is_POD_type;
 };
 
-struct __type_traits<unsigned char> {
+__STL_TEMPLATE_NULL struct __type_traits<unsigned char> {
    typedef __true_type    has_trivial_default_constructor;
    typedef __true_type    has_trivial_copy_constructor;
    typedef __true_type    has_trivial_assignment_operator;
@@ -112,7 +114,7 @@ struct __type_traits<unsigned char> {
    typedef __true_type    is_POD_type;
 };
 
-struct __type_traits<short> {
+__STL_TEMPLATE_NULL struct __type_traits<short> {
    typedef __true_type    has_trivial_default_constructor;
    typedef __true_type    has_trivial_copy_constructor;
    typedef __true_type    has_trivial_assignment_operator;
@@ -120,7 +122,7 @@ struct __type_traits<short> {
    typedef __true_type    is_POD_type;
 };
 
-struct __type_traits<unsigned short> {
+__STL_TEMPLATE_NULL struct __type_traits<unsigned short> {
    typedef __true_type    has_trivial_default_constructor;
    typedef __true_type    has_trivial_copy_constructor;
    typedef __true_type    has_trivial_assignment_operator;
@@ -128,7 +130,7 @@ struct __type_traits<unsigned short> {
    typedef __true_type    is_POD_type;
 };
 
-struct __type_traits<int> {
+__STL_TEMPLATE_NULL struct __type_traits<int> {
    typedef __true_type    has_trivial_default_constructor;
    typedef __true_type    has_trivial_copy_constructor;
    typedef __true_type    has_trivial_assignment_operator;
@@ -136,7 +138,7 @@ struct __type_traits<int> {
    typedef __true_type    is_POD_type;
 };
 
-struct __type_traits<unsigned int> {
+__STL_TEMPLATE_NULL struct __type_traits<unsigned int> {
    typedef __true_type    has_trivial_default_constructor;
    typedef __true_type    has_trivial_copy_constructor;
    typedef __true_type    has_trivial_assignment_operator;
@@ -144,7 +146,7 @@ struct __type_traits<unsigned int> {
    typedef __true_type    is_POD_type;
 };
 
-struct __type_traits<long> {
+__STL_TEMPLATE_NULL struct __type_traits<long> {
    typedef __true_type    has_trivial_default_constructor;
    typedef __true_type    has_trivial_copy_constructor;
    typedef __true_type    has_trivial_assignment_operator;
@@ -152,7 +154,7 @@ struct __type_traits<long> {
    typedef __true_type    is_POD_type;
 };
 
-struct __type_traits<unsigned long> {
+__STL_TEMPLATE_NULL struct __type_traits<unsigned long> {
    typedef __true_type    has_trivial_default_constructor;
    typedef __true_type    has_trivial_copy_constructor;
    typedef __true_type    has_trivial_assignment_operator;
@@ -160,7 +162,7 @@ struct __type_traits<unsigned long> {
    typedef __true_type    is_POD_type;
 };
 
-struct __type_traits<float> {
+__STL_TEMPLATE_NULL struct __type_traits<float> {
    typedef __true_type    has_trivial_default_constructor;
    typedef __true_type    has_trivial_copy_constructor;
    typedef __true_type    has_trivial_assignment_operator;
@@ -168,7 +170,7 @@ struct __type_traits<float> {
    typedef __true_type    is_POD_type;
 };
 
-struct __type_traits<double> {
+__STL_TEMPLATE_NULL struct __type_traits<double> {
    typedef __true_type    has_trivial_default_constructor;
    typedef __true_type    has_trivial_copy_constructor;
    typedef __true_type    has_trivial_assignment_operator;
@@ -176,7 +178,7 @@ struct __type_traits<double> {
    typedef __true_type    is_POD_type;
 };
 
-struct __type_traits<long double> {
+__STL_TEMPLATE_NULL struct __type_traits<long double> {
    typedef __true_type    has_trivial_default_constructor;
    typedef __true_type    has_trivial_copy_constructor;
    typedef __true_type    has_trivial_assignment_operator;
@@ -225,3 +227,7 @@ struct __type_traits<unsigned char*> {
 
 
 #endif /* __TYPE_TRAITS_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/utility b/libstdc++/stl/utility
new file mode 100644 (file)
index 0000000..df8c224
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __SGI_STL_UTILITY
+#define __SGI_STL_UTILITY
+
+#include <stl_config.h>
+#include <stl_relops.h>
+#include <stl_pair.h>
+
+#endif /* __SGI_STL_UTILITY */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/stl/vector b/libstdc++/stl/vector
new file mode 100644 (file)
index 0000000..4bcdebc
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef __SGI_STL_VECTOR
+#define __SGI_STL_VECTOR
+
+#include <stl_algobase.h>
+#include <stl_alloc.h>
+#include <stl_construct.h>
+#include <stl_uninitialized.h>
+#include <stl_vector.h>
+#include <stl_bvector.h>
+
+#endif /* __SGI_STL_VECTOR */
+
+// Local Variables:
+// mode:C++
+// End:
index 1c7867e..231a227 100644 (file)
 #ifndef __SGI_STL_VECTOR_H
 #define __SGI_STL_VECTOR_H
 
-#include <stddef.h>
 #include <algobase.h>
 #include <alloc.h>
+#include <stl_vector.h>
 
-template <class T, class Alloc = alloc>
-class vector {
-public:
-    typedef T value_type;
-    typedef value_type* pointer;
-    typedef value_type* iterator;
-    typedef const value_type* const_iterator;
-    typedef value_type& reference;
-    typedef const value_type& const_reference;
-    typedef size_t size_type;
-    typedef ptrdiff_t difference_type;
-
-#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
-    typedef reverse_iterator<const_iterator> const_reverse_iterator;
-    typedef reverse_iterator<iterator> reverse_iterator;
-#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-    typedef reverse_iterator<const_iterator, value_type, const_reference, 
-                             difference_type>  const_reverse_iterator;
-    typedef reverse_iterator<iterator, value_type, reference, difference_type>
-        reverse_iterator;
-#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
-protected:
-    typedef simple_alloc<value_type, Alloc> data_allocator;
-    iterator start;
-    iterator finish;
-    iterator end_of_storage;
-    void insert_aux(iterator position, const T& x);
-    void deallocate() {
-      if (start) data_allocator::deallocate(start, end_of_storage - start);
-    }
-
-    void fill_initialize(size_type n, const T& value) {
-      start = allocate_and_fill(n, value);
-      finish = start + n;
-      end_of_storage = finish;
-    }
-public:
-    iterator begin() { return start; }
-    const_iterator begin() const { return start; }
-    iterator end() { return finish; }
-    const_iterator end() const { return finish; }
-    reverse_iterator rbegin() { return reverse_iterator(end()); }
-    const_reverse_iterator rbegin() const { 
-        return const_reverse_iterator(end()); 
-    }
-    reverse_iterator rend() { return reverse_iterator(begin()); }
-    const_reverse_iterator rend() const { 
-        return const_reverse_iterator(begin()); 
-    }
-    size_type size() const { return size_type(end() - begin()); }
-    size_type max_size() const { return size_type(-1) / sizeof(T); }
-    size_type capacity() const { return size_type(end_of_storage - begin()); }
-    bool empty() const { return begin() == end(); }
-    reference operator[](size_type n) { return *(begin() + n); }
-    const_reference operator[](size_type n) const { return *(begin() + n); }
-
-    vector() : start(0), finish(0), end_of_storage(0) {}
-    vector(size_type n, const T& value) { fill_initialize(n, value); }
-    vector(int n, const T& value) { fill_initialize(n, value); }
-    vector(long n, const T& value) { fill_initialize(n, value); }
-    explicit vector(size_type n) { fill_initialize(n, T()); }
-
-    vector(const vector<T, Alloc>& x) {
-      start = allocate_and_copy(x.end() - x.begin(), x.begin(), x.end());
-      finish = start + (x.end() - x.begin());
-      end_of_storage = finish;
-    }
-#ifdef __STL_MEMBER_TEMPLATES
-    template <class InputIterator>
-    vector(InputIterator first, InputIterator last) :
-      start(0), finish(0), end_of_storage(0) {
-        range_initialize(first, last, iterator_category(first));
-    }
-#else /* __STL_MEMBER_TEMPLATES */
-    vector(const_iterator first, const_iterator last) {
-      size_type n = 0;
-      distance(first, last, n);
-      start = allocate_and_copy(n, first, last);
-      finish = start + n;
-      end_of_storage = finish;
-    }
-#endif /* __STL_MEMBER_TEMPLATES */
-    ~vector() { 
-       destroy(start, finish);
-       deallocate();
-    }
-    vector<T, Alloc>& operator=(const vector<T, Alloc>& x);
-    void reserve(size_type n) {
-      if (capacity() < n) {
-        const size_type old_size = size();
-        iterator tmp = allocate_and_copy(n, start, finish);
-        destroy(start, finish);
-        deallocate();
-        start = tmp;
-        finish = tmp + old_size;
-        end_of_storage = start + n;
-      }
-    }
-    reference front() { return *begin(); }
-    const_reference front() const { return *begin(); }
-    reference back() { return *(end() - 1); }
-    const_reference back() const { return *(end() - 1); }
-    void push_back(const T& x) {
-       if (finish != end_of_storage) {
-           construct(finish, x);
-           ++finish;
-       } else
-           insert_aux(end(), x);
-    }
-    void swap(vector<T, Alloc>& x) {
-       ::swap(start, x.start);
-       ::swap(finish, x.finish);
-       ::swap(end_of_storage, x.end_of_storage);
-    }
-    iterator insert(iterator position, const T& x) {
-       size_type n = position - begin();
-       if (finish != end_of_storage && position == end()) {
-           construct(finish, x);
-           ++finish;
-       } else
-           insert_aux(position, x);
-       return begin() + n;
-    }
-    iterator insert(iterator position) { return insert(position, T()); }
-#ifdef __STL_MEMBER_TEMPLATES
-    template <class InputIterator>
-    void insert(iterator position, InputIterator first, InputIterator last) {
-      range_insert(position, first, last, iterator_category(first));
-    }
-#else /* __STL_MEMBER_TEMPLATES */
-    void insert(iterator position,
-                const_iterator first, const_iterator last);
-#endif /* __STL_MEMBER_TEMPLATES */
-
-    void insert (iterator pos, size_type n, const T& x);
-    void insert (iterator pos, int n, const T& x) {
-      insert(pos, (size_type) n, x);
-    }
-    void insert (iterator pos, long n, const T& x) {
-      insert(pos, (size_type) n, x);
-    }
-
-    void pop_back() {
-        --finish;
-        destroy(finish);
-    }
-    void erase(iterator position) {
-       if (position + 1 != end())
-           copy(position + 1, finish, position);
-       --finish;
-       destroy(finish);
-    }
-    void erase(iterator first, iterator last) {
-        iterator i = copy(last, finish, first);
-       destroy(i, finish);
-       finish = finish - (last - first); 
-    }
-    void resize(size_type new_size, const T& x) {
-      if (new_size < size()) 
-        erase(begin() + new_size, end());
-      else
-        insert(end(), new_size - size(), x);
-    }
-    void resize(size_type new_size) { resize(new_size, T()); }
-    void clear() { erase(begin(), end()); }
-
-protected:
-    iterator allocate_and_fill(size_type n, const T& x) {
-      iterator result = data_allocator::allocate(n);
-#         ifdef __STL_USE_EXCEPTIONS
-      try {
-#         endif /* __STL_USE_EXCEPTIONS */
-        uninitialized_fill_n(result, n, x);
-        return result;
-#         ifdef __STL_USE_EXCEPTIONS
-      }
-      catch(...) {
-        data_allocator::deallocate(result, n);
-        throw;
-      }
-#         endif /* __STL_USE_EXCEPTIONS */
-    }
-
-#ifdef __STL_MEMBER_TEMPLATES
-    template <class ForwardIterator>
-    iterator allocate_and_copy(size_type n,
-                               ForwardIterator first, ForwardIterator last) {
-      iterator result = data_allocator::allocate(n);
-#         ifdef __STL_USE_EXCEPTIONS
-      try {
-#         endif /* __STL_USE_EXCEPTIONS */
-        uninitialized_copy(first, last, result);
-        return result;
-#         ifdef __STL_USE_EXCEPTIONS
-      }
-      catch(...) {
-        data_allocator::deallocate(result, n);
-        throw;
-      }
-#         endif /* __STL_USE_EXCEPTIONS */
-    }
-#else /* __STL_MEMBER_TEMPLATES */
-    iterator allocate_and_copy(size_type n,
-                               const_iterator first, const_iterator last) {
-      iterator result = data_allocator::allocate(n);
-#         ifdef __STL_USE_EXCEPTIONS
-      try {
-#         endif /* __STL_USE_EXCEPTIONS */
-        uninitialized_copy(first, last, result);
-        return result;
-#         ifdef __STL_USE_EXCEPTIONS
-      }
-      catch(...) {
-        data_allocator::deallocate(result, n);
-        throw;
-      }
-#         endif /* __STL_USE_EXCEPTIONS */
-    }
-#endif /* __STL_MEMBER_TEMPLATES */
-
-
-#ifdef __STL_MEMBER_TEMPLATES
-    template <class InputIterator>
-    void range_initialize(InputIterator first, InputIterator last,
-                          input_iterator_tag) {
-      for ( ; first != last; ++first)
-        push_back(*first);
-    }
-
-    // This function is only called by the constructor.  We have to worry
-    //  about resource leaks, but not about maintaining invariants.
-    template <class ForwardIterator>
-    void range_initialize(ForwardIterator first, ForwardIterator last,
-                          forward_iterator_tag) {
-      size_type n = 0;
-      distance(first, last, n);
-      start = allocate_and_copy(n, first, last);
-      finish = start + n;
-      end_of_storage = finish;
-    }
-
-    template <class InputIterator>
-    void range_insert(iterator pos,
-                      InputIterator first, InputIterator last,
-                      input_iterator_tag);
-
-    template <class ForwardIterator>
-    void range_insert(iterator pos,
-                      ForwardIterator first, ForwardIterator last,
-                      forward_iterator_tag);
-
-#endif /* __STL_MEMBER_TEMPLATES */
-};
-
-template <class T, class Alloc>
-inline bool operator==(const vector<T, Alloc>& x, const vector<T, Alloc>& y) {
-    return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
-}
-
-template <class T, class Alloc>
-inline bool operator<(const vector<T, Alloc>& x, const vector<T, Alloc>& y) {
-    return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
-}
-
-
-
-template <class T, class Alloc>
-vector<T, Alloc>& vector<T, Alloc>::operator=(const vector<T, Alloc>& x) {
-  if (&x != this) {
-    if (x.size() > capacity()) {
-      iterator tmp = allocate_and_copy(x.end() - x.begin(),
-                                             x.begin(), x.end());
-      destroy(start, finish);
-      deallocate();
-      start = tmp;
-      end_of_storage = start + (x.end() - x.begin());
-    }
-    else if (size() >= x.size()) {
-      iterator i = copy(x.begin(), x.end(), begin());
-      destroy(i, finish);
-    }
-    else {
-      copy(x.begin(), x.begin() + size(), start);
-      uninitialized_copy(x.begin() + size(), x.end(), finish);
-    }
-    finish = start + x.size();
-  }
-  return *this;
-}
-
-template <class T, class Alloc>
-void vector<T, Alloc>::insert_aux(iterator position, const T& x) {
-  if (finish != end_of_storage) {
-    construct(finish, *(finish - 1));
-    ++finish;
-    T x_copy = x;
-    copy_backward(position, finish - 2, 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 = data_allocator::allocate(len);
-    iterator new_finish = new_start;
-#       ifdef __STL_USE_EXCEPTIONS
-    try {
-#       endif /* __STL_USE_EXCEPTIONS */
-      new_finish = uninitialized_copy(start, position, new_start);
-      construct(new_finish, x);
-      ++new_finish;
-      new_finish = uninitialized_copy(position, finish, new_finish);
-#       ifdef __STL_USE_EXCEPTIONS
-    }
-    catch(...) {
-      destroy(new_start, new_finish);
-      data_allocator::deallocate(new_start, len);
-      throw;
-    }
-#       endif /* __STL_USE_EXCEPTIONS */
-    destroy(begin(), end());
-    deallocate();
-    start = new_start;
-    finish = new_finish;
-    end_of_storage = new_start + len;
-  }
-}
-
-template <class T, class Alloc>
-void vector<T, Alloc>::insert(iterator position, size_type n, const T& x) {
-  if (n != 0) {
-    if (size_type(end_of_storage - finish) >= n) {
-      T x_copy = x;
-      const size_type elems_after = finish - position;
-      iterator old_finish = finish;
-      if (elems_after > n) {
-        uninitialized_copy(finish - n, finish, finish);
-        finish += n;
-        copy_backward(position, old_finish - n, old_finish);
-        fill(position, position + n, x_copy);
-      }
-      else {
-        uninitialized_fill_n(finish, n - elems_after, x_copy);
-        finish += n - elems_after;
-        uninitialized_copy(position, old_finish, finish);
-        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 = data_allocator::allocate(len);
-      iterator new_finish = new_start;
-#         ifdef __STL_USE_EXCEPTIONS
-      try {
-#         endif /* __STL_USE_EXCEPTIONS */
-        new_finish = uninitialized_copy(start, position, new_start);
-        new_finish = uninitialized_fill_n(new_finish, n, x);
-        new_finish = uninitialized_copy(position, finish, new_finish);
-#         ifdef __STL_USE_EXCEPTIONS
-      }
-      catch(...) {
-        destroy(new_start, new_finish);
-        data_allocator::deallocate(new_start, len);
-        throw;
-      }
-#         endif /* __STL_USE_EXCEPTIONS */
-      destroy(start, finish);
-      deallocate();
-      start = new_start;
-      finish = new_finish;
-      end_of_storage = new_start + len;
-    }
-  }
-}
-
-#ifdef __STL_MEMBER_TEMPLATES
-
-template <class T, class Alloc> template <class InputIterator>
-void vector<T, Alloc>::range_insert(iterator pos,
-                                    InputIterator first, InputIterator last,
-                                    input_iterator_tag) {
-  for ( ; first != last; ++first) {
-    pos = insert(pos, *first);
-    ++pos;
-  }
-}
-
-template <class T, class Alloc> template <class ForwardIterator>
-void vector<T, Alloc>::range_insert(iterator position,
-                                    ForwardIterator first,
-                                    ForwardIterator last,
-                                    forward_iterator_tag) {
-  if (first != last) {
-    size_type n = 0;
-    distance(first, last, n);
-    if (size_type(end_of_storage - finish) >= n) {
-      const size_type elems_after = finish - position;
-      iterator old_finish = finish;
-      if (elems_after > n) {
-        uninitialized_copy(finish - n, finish, finish);
-        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, finish);
-        finish += n - elems_after;
-        uninitialized_copy(position, old_finish, finish);
-        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 = data_allocator::allocate(len);
-      iterator new_finish = new_start;
-#         ifdef __STL_USE_EXCEPTIONS
-      try {
-#         endif /* __STL_USE_EXCEPTIONS */
-        new_finish = uninitialized_copy(start, position, new_start);
-        new_finish = uninitialized_copy(first, last, new_finish);
-        new_finish = uninitialized_copy(position, finish, new_finish);
-#         ifdef __STL_USE_EXCEPTIONS
-      }
-      catch(...) {
-        destroy(new_start, new_finish);
-        data_allocator::deallocate(new_start, len);
-        throw;
-      }
-#         endif /* __STL_USE_EXCEPTIONS */
-      destroy(start, finish);
-      deallocate();
-      start = new_start;
-      finish = new_finish;
-      end_of_storage = new_start + len;
-    }
-  }
-}
-
-#else /* __STL_MEMBER_TEMPLATES */
-
-template <class T, class Alloc>
-void vector<T, Alloc>::insert(iterator position, 
-                              const_iterator first, 
-                              const_iterator last) {
-  if (first != last) {
-    size_type n = 0;
-    distance(first, last, n);
-    if (size_type(end_of_storage - finish) >= n) {
-      const size_type elems_after = finish - position;
-      iterator old_finish = finish;
-      if (elems_after > n) {
-        uninitialized_copy(finish - n, finish, finish);
-        finish += n;
-        copy_backward(position, old_finish - n, old_finish);
-        copy(first, last, position);
-      }
-      else {
-        uninitialized_copy(first + elems_after, last, finish);
-        finish += n - elems_after;
-        uninitialized_copy(position, old_finish, finish);
-        finish += elems_after;
-        copy(first, first + elems_after, position);
-      }
-    }
-    else {
-      const size_type old_size = size();
-      const size_type len = old_size + max(old_size, n);
-      iterator new_start = data_allocator::allocate(len);
-      iterator new_finish = new_start;
-#         ifdef __STL_USE_EXCEPTIONS
-      try {
-#         endif /* __STL_USE_EXCEPTIONS */
-        new_finish = uninitialized_copy(start, position, new_start);
-        new_finish = uninitialized_copy(first, last, new_finish);
-        new_finish = uninitialized_copy(position, finish, new_finish);
-#         ifdef __STL_USE_EXCEPTIONS
-      }
-      catch(...) {
-        destroy(new_start, new_finish);
-        data_allocator::deallocate(new_start, len);
-        throw;
-      }
-#         endif /* __STL_USE_EXCEPTIONS */
-      destroy(start, finish);
-      deallocate();
-      start = new_start;
-      finish = new_finish;
-      end_of_storage = new_start + len;
-    }
-  }
-}
-
-#endif /* __STL_MEMBER_TEMPLATES */
+#ifdef __STL_USE_NAMESPACES
+using __STD::vector;
+#endif /* __STL_USE_NAMESPACES */
 
 #endif /* __SGI_STL_VECTOR_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/libstdc++/utility b/libstdc++/utility
deleted file mode 100644 (file)
index fb79aa7..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// -*- C++ -*- forwarding header.
-// This file is part of the GNU ANSI C++ Library.
-
-#ifndef __UTILITY__
-#define __UTILITY__
-#include <function.h>
-#include <pair.h>
-#endif
diff --git a/libstdc++/vector b/libstdc++/vector
deleted file mode 100644 (file)
index 79f7359..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// -*- C++ -*- forwarding header.
-// This file is part of the GNU ANSI C++ Library.
-
-#ifndef __VECTOR__
-#define __VECTOR__
-#include <vector.h>
-#endif