summaryrefslogtreecommitdiffstats
path: root/libstdc++/stl
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++/stl')
-rw-r--r--libstdc++/stl/ChangeLog18
-rw-r--r--libstdc++/stl/algo.h2927
-rw-r--r--libstdc++/stl/algobase.h775
-rw-r--r--libstdc++/stl/algorithm39
-rw-r--r--libstdc++/stl/alloc.h680
-rw-r--r--libstdc++/stl/bvector.h537
-rw-r--r--libstdc++/stl/defalloc.h19
-rw-r--r--libstdc++/stl/deque40
-rw-r--r--libstdc++/stl/deque.h1411
-rw-r--r--libstdc++/stl/function.h684
-rw-r--r--libstdc++/stl/functional26
-rw-r--r--libstdc++/stl/hash_map40
-rw-r--r--libstdc++/stl/hash_map.h299
-rw-r--r--libstdc++/stl/hash_set40
-rw-r--r--libstdc++/stl/hash_set.h287
-rw-r--r--libstdc++/stl/hashtable.h974
-rw-r--r--libstdc++/stl/heap.h202
-rw-r--r--libstdc++/stl/iterator40
-rw-r--r--libstdc++/stl/iterator.h795
-rw-r--r--libstdc++/stl/list40
-rw-r--r--libstdc++/stl/list.h610
-rw-r--r--libstdc++/stl/map40
-rw-r--r--libstdc++/stl/map.h163
-rw-r--r--libstdc++/stl/memory89
-rw-r--r--libstdc++/stl/multimap.h159
-rw-r--r--libstdc++/stl/multiset.h144
-rw-r--r--libstdc++/stl/numeric42
-rw-r--r--libstdc++/stl/pair.h50
-rw-r--r--libstdc++/stl/pthread_alloc347
-rw-r--r--libstdc++/stl/pthread_alloc.h337
-rw-r--r--libstdc++/stl/queue45
-rw-r--r--libstdc++/stl/rope32
-rw-r--r--libstdc++/stl/rope.h2072
-rw-r--r--libstdc++/stl/ropeimpl.h72
-rw-r--r--libstdc++/stl/set40
-rw-r--r--libstdc++/stl/set.h144
-rw-r--r--libstdc++/stl/slist28
-rw-r--r--libstdc++/stl/slist.h722
-rw-r--r--libstdc++/stl/stack41
-rw-r--r--libstdc++/stl/stack.h155
-rw-r--r--libstdc++/stl/stl_algo.h2674
-rw-r--r--libstdc++/stl/stl_algobase.h439
-rw-r--r--libstdc++/stl/stl_alloc.h698
-rw-r--r--libstdc++/stl/stl_bvector.h614
-rw-r--r--libstdc++/stl/stl_config.h119
-rw-r--r--libstdc++/stl/stl_construct.h78
-rw-r--r--libstdc++/stl/stl_deque.h1335
-rw-r--r--libstdc++/stl/stl_function.h628
-rw-r--r--libstdc++/stl/stl_hash_fun.h93
-rw-r--r--libstdc++/stl/stl_hash_map.h358
-rw-r--r--libstdc++/stl/stl_hash_set.h342
-rw-r--r--libstdc++/stl/stl_hashtable.h948
-rw-r--r--libstdc++/stl/stl_heap.h226
-rw-r--r--libstdc++/stl/stl_iterator.h843
-rw-r--r--libstdc++/stl/stl_list.h617
-rw-r--r--libstdc++/stl/stl_map.h217
-rw-r--r--libstdc++/stl/stl_multimap.h214
-rw-r--r--libstdc++/stl/stl_multiset.h200
-rw-r--r--libstdc++/stl/stl_numeric.h196
-rw-r--r--libstdc++/stl/stl_pair.h73
-rw-r--r--libstdc++/stl/stl_queue.h134
-rw-r--r--libstdc++/stl/stl_raw_storage_iter.h81
-rw-r--r--libstdc++/stl/stl_relops.h62
-rw-r--r--libstdc++/stl/stl_rope.h2112
-rw-r--r--libstdc++/stl/stl_set.h198
-rw-r--r--libstdc++/stl/stl_slist.h740
-rw-r--r--libstdc++/stl/stl_stack.h76
-rw-r--r--libstdc++/stl/stl_tempbuf.h123
-rw-r--r--libstdc++/stl/stl_tree.h1099
-rw-r--r--libstdc++/stl/stl_uninitialized.h242
-rw-r--r--libstdc++/stl/stl_vector.h534
-rw-r--r--libstdc++/stl/tempbuf.h103
-rw-r--r--libstdc++/stl/tree.h1073
-rw-r--r--libstdc++/stl/type_traits.h30
-rw-r--r--libstdc++/stl/utility38
-rw-r--r--libstdc++/stl/vector41
-rw-r--r--libstdc++/stl/vector.h507
77 files changed, 17947 insertions, 15363 deletions
diff --git a/libstdc++/stl/ChangeLog b/libstdc++/stl/ChangeLog
index ca1c01a626f..7d0c62ab462 100644
--- a/libstdc++/stl/ChangeLog
+++ b/libstdc++/stl/ChangeLog
@@ -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.
diff --git a/libstdc++/stl/algo.h b/libstdc++/stl/algo.h
index 2f142898d8b..1707868c7c4 100644
--- a/libstdc++/stl/algo.h
+++ b/libstdc++/stl/algo.h
@@ -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
@@ -27,2851 +27,88 @@
#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:
diff --git a/libstdc++/stl/algobase.h b/libstdc++/stl/algobase.h
index eccf465d52c..f35e7af4a97 100644
--- a/libstdc++/stl/algobase.h
+++ b/libstdc++/stl/algobase.h
@@ -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
@@ -24,743 +23,49 @@
* 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
index 00000000000..515e9bd25da
--- /dev/null
+++ b/libstdc++/stl/algorithm
@@ -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:
diff --git a/libstdc++/stl/alloc.h b/libstdc++/stl/alloc.h
index 8831976c614..7cc96100605 100644
--- a/libstdc++/stl/alloc.h
+++ b/libstdc++/stl/alloc.h
@@ -11,674 +11,34 @@
* 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:
diff --git a/libstdc++/stl/bvector.h b/libstdc++/stl/bvector.h
index 71b49173c40..03a3fb1c7f2 100644
--- a/libstdc++/stl/bvector.h
+++ b/libstdc++/stl/bvector.h
@@ -24,541 +24,28 @@
* 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 */
diff --git a/libstdc++/stl/defalloc.h b/libstdc++/stl/defalloc.h
index e7d24d38c84..49690f8d6e0 100644
--- a/libstdc++/stl/defalloc.h
+++ b/libstdc++/stl/defalloc.h
@@ -12,16 +12,15 @@
* 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
index 00000000000..61654acad5b
--- /dev/null
+++ b/libstdc++/stl/deque
@@ -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:
diff --git a/libstdc++/stl/deque.h b/libstdc++/stl/deque.h
index e202a117398..ede38b1ceba 100644
--- a/libstdc++/stl/deque.h
+++ b/libstdc++/stl/deque.h
@@ -27,1413 +27,16 @@
#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:
diff --git a/libstdc++/stl/function.h b/libstdc++/stl/function.h
index e4f4713235b..6474dd99fa2 100644
--- a/libstdc++/stl/function.h
+++ b/libstdc++/stl/function.h
@@ -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
@@ -27,608 +27,92 @@
#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
index 00000000000..d046dbb036d
--- /dev/null
+++ b/libstdc++/stl/functional
@@ -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
index 00000000000..f7421e026fa
--- /dev/null
+++ b/libstdc++/stl/hash_map
@@ -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:
diff --git a/libstdc++/stl/hash_map.h b/libstdc++/stl/hash_map.h
index c52b9936e7b..81cb5784f47 100644
--- a/libstdc++/stl/hash_map.h
+++ b/libstdc++/stl/hash_map.h
@@ -27,293 +27,22 @@
#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
index 00000000000..2244f47cfa0
--- /dev/null
+++ b/libstdc++/stl/hash_set
@@ -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:
diff --git a/libstdc++/stl/hash_set.h b/libstdc++/stl/hash_set.h
index 2c7125eb7e5..c938ccc467a 100644
--- a/libstdc++/stl/hash_set.h
+++ b/libstdc++/stl/hash_set.h
@@ -27,280 +27,17 @@
#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 */
diff --git a/libstdc++/stl/hashtable.h b/libstdc++/stl/hashtable.h
index fb4abc2b344..15dbfc91644 100644
--- a/libstdc++/stl/hashtable.h
+++ b/libstdc++/stl/hashtable.h
@@ -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
@@ -24,969 +24,25 @@
*
*/
+/* 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:
diff --git a/libstdc++/stl/heap.h b/libstdc++/stl/heap.h
index b24afafadd6..2ec93c07b76 100644
--- a/libstdc++/stl/heap.h
+++ b/libstdc++/stl/heap.h
@@ -11,194 +11,36 @@
* 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
index 00000000000..90e6c9c8b68
--- /dev/null
+++ b/libstdc++/stl/iterator
@@ -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:
diff --git a/libstdc++/stl/iterator.h b/libstdc++/stl/iterator.h
index f8a19d0aa34..f8a02377422 100644
--- a/libstdc++/stl/iterator.h
+++ b/libstdc++/stl/iterator.h
@@ -27,765 +27,78 @@
#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
index 00000000000..5294f39fea6
--- /dev/null
+++ b/libstdc++/stl/list
@@ -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:
diff --git a/libstdc++/stl/list.h b/libstdc++/stl/list.h
index 6d9492865e8..4e6ee0b4113 100644
--- a/libstdc++/stl/list.h
+++ b/libstdc++/stl/list.h
@@ -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
@@ -27,608 +27,16 @@
#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
index 00000000000..4cfb7652c54
--- /dev/null
+++ b/libstdc++/stl/map
@@ -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:
diff --git a/libstdc++/stl/map.h b/libstdc++/stl/map.h
index 5c9d6b1bf3b..a89bd31e81c 100644
--- a/libstdc++/stl/map.h
+++ b/libstdc++/stl/map.h
@@ -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
@@ -28,161 +28,14 @@
#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
index 00000000000..a80658875ee
--- /dev/null
+++ b/libstdc++/stl/memory
@@ -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:
diff --git a/libstdc++/stl/multimap.h b/libstdc++/stl/multimap.h
index f15880af39d..1a8ec4af4f9 100644
--- a/libstdc++/stl/multimap.h
+++ b/libstdc++/stl/multimap.h
@@ -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
@@ -28,155 +28,14 @@
#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:
diff --git a/libstdc++/stl/multiset.h b/libstdc++/stl/multiset.h
index 3df4557b18f..3024fd74c03 100644
--- a/libstdc++/stl/multiset.h
+++ b/libstdc++/stl/multiset.h
@@ -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
@@ -28,140 +28,14 @@
#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
index 00000000000..7f048e11b56
--- /dev/null
+++ b/libstdc++/stl/numeric
@@ -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:
diff --git a/libstdc++/stl/pair.h b/libstdc++/stl/pair.h
index ca20d8baf8a..00f5caddb61 100644
--- a/libstdc++/stl/pair.h
+++ b/libstdc++/stl/pair.h
@@ -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
@@ -24,40 +24,28 @@
* 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
index 00000000000..71df3d3b548
--- /dev/null
+++ b/libstdc++/stl/pthread_alloc
@@ -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:
diff --git a/libstdc++/stl/pthread_alloc.h b/libstdc++/stl/pthread_alloc.h
index a2aeaa1290e..0a2debb74bd 100644
--- a/libstdc++/stl/pthread_alloc.h
+++ b/libstdc++/stl/pthread_alloc.h
@@ -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
@@ -11,334 +11,21 @@
* 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
index 00000000000..f9417fb1fbb
--- /dev/null
+++ b/libstdc++/stl/queue
@@ -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
index 00000000000..9ef738241d7
--- /dev/null
+++ b/libstdc++/stl/rope
@@ -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:
diff --git a/libstdc++/stl/rope.h b/libstdc++/stl/rope.h
index 399352f477e..d767fa32e7a 100644
--- a/libstdc++/stl/rope.h
+++ b/libstdc++/stl/rope.h
@@ -11,2066 +11,24 @@
* 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:
diff --git a/libstdc++/stl/ropeimpl.h b/libstdc++/stl/ropeimpl.h
index d1c1ed4e689..dcd6bfd5117 100644
--- a/libstdc++/stl/ropeimpl.h
+++ b/libstdc++/stl/ropeimpl.h
@@ -11,9 +11,19 @@
* 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
index 00000000000..c836c4596d2
--- /dev/null
+++ b/libstdc++/stl/set
@@ -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:
diff --git a/libstdc++/stl/set.h b/libstdc++/stl/set.h
index 6a79a625653..9004d2e0477 100644
--- a/libstdc++/stl/set.h
+++ b/libstdc++/stl/set.h
@@ -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
@@ -28,140 +28,14 @@
#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
index 00000000000..c3ec74204c5
--- /dev/null
+++ b/libstdc++/stl/slist
@@ -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:
diff --git a/libstdc++/stl/slist.h b/libstdc++/stl/slist.h
index 9ae6e117f0d..d2377b0cf5a 100644
--- a/libstdc++/stl/slist.h
+++ b/libstdc++/stl/slist.h
@@ -17,720 +17,14 @@
#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
index 00000000000..36461d95b8c
--- /dev/null
+++ b/libstdc++/stl/stack
@@ -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:
diff --git a/libstdc++/stl/stack.h b/libstdc++/stl/stack.h
index cc025bb70e1..89beca82f12 100644
--- a/libstdc++/stl/stack.h
+++ b/libstdc++/stl/stack.h
@@ -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
@@ -24,148 +24,23 @@
* 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
index 00000000000..6703c2aa7a8
--- /dev/null
+++ b/libstdc++/stl/stl_algo.h
@@ -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
index 00000000000..668baad8d6b
--- /dev/null
+++ b/libstdc++/stl/stl_algobase.h
@@ -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
index 00000000000..a6d41437bd4
--- /dev/null
+++ b/libstdc++/stl/stl_alloc.h
@@ -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
index 00000000000..db02251facd
--- /dev/null
+++ b/libstdc++/stl/stl_bvector.h
@@ -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:
diff --git a/libstdc++/stl/stl_config.h b/libstdc++/stl/stl_config.h
index 31e96cf7cd3..c6546667a93 100644
--- a/libstdc++/stl/stl_config.h
+++ b/libstdc++/stl/stl_config.h
@@ -28,35 +28,47 @@
# 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
@@ -90,6 +105,8 @@
# 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
@@ -108,6 +125,7 @@
# define __STL_MEMBER_TEMPLATES
# define __STL_CLASS_PARTIAL_SPECIALIZATION
# define __STL_USE_EXCEPTIONS
+# define __STL_USE_NAMESPACES
# endif
# if defined(_MSC_VER)
@@ -150,17 +168,60 @@
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
@@ -173,3 +234,7 @@
#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
index 00000000000..46876353da6
--- /dev/null
+++ b/libstdc++/stl/stl_construct.h
@@ -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
index 00000000000..79d40082f76
--- /dev/null
+++ b/libstdc++/stl/stl_deque.h
@@ -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
index 00000000000..c0d785d6a60
--- /dev/null
+++ b/libstdc++/stl/stl_function.h
@@ -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
index 00000000000..3afa9dc554d
--- /dev/null
+++ b/libstdc++/stl/stl_hash_fun.h
@@ -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
index 00000000000..9999e9a401b
--- /dev/null
+++ b/libstdc++/stl/stl_hash_map.h
@@ -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
index 00000000000..80159dab59f
--- /dev/null
+++ b/libstdc++/stl/stl_hash_set.h
@@ -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
index 00000000000..2452f625d3d
--- /dev/null
+++ b/libstdc++/stl/stl_hashtable.h
@@ -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
index 00000000000..3fe24f833fc
--- /dev/null
+++ b/libstdc++/stl/stl_heap.h
@@ -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
index 00000000000..892db3e3dbb
--- /dev/null
+++ b/libstdc++/stl/stl_iterator.h
@@ -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
index 00000000000..ac836b6fcf9
--- /dev/null
+++ b/libstdc++/stl/stl_list.h
@@ -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
index 00000000000..2a830cc65f2
--- /dev/null
+++ b/libstdc++/stl/stl_map.h
@@ -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
index 00000000000..b82159b648e
--- /dev/null
+++ b/libstdc++/stl/stl_multimap.h
@@ -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
index 00000000000..ff5947e1490
--- /dev/null
+++ b/libstdc++/stl/stl_multiset.h
@@ -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
index 00000000000..57fee2b1b5c
--- /dev/null
+++ b/libstdc++/stl/stl_numeric.h
@@ -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
index 00000000000..10a9cb08e3b
--- /dev/null
+++ b/libstdc++/stl/stl_pair.h
@@ -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
index 00000000000..ff6eedeb701
--- /dev/null
+++ b/libstdc++/stl/stl_queue.h
@@ -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
index 00000000000..5d3d0747b5e
--- /dev/null
+++ b/libstdc++/stl/stl_raw_storage_iter.h
@@ -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
index 00000000000..01a0c7cdfcb
--- /dev/null
+++ b/libstdc++/stl/stl_relops.h
@@ -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
index 00000000000..620db6ffbc5
--- /dev/null
+++ b/libstdc++/stl/stl_rope.h
@@ -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
index 00000000000..9ffeaa799a7
--- /dev/null
+++ b/libstdc++/stl/stl_set.h
@@ -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
index 00000000000..f31ea9e15e5
--- /dev/null
+++ b/libstdc++/stl/stl_slist.h
@@ -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
index 00000000000..d380e81dd1f
--- /dev/null
+++ b/libstdc++/stl/stl_stack.h
@@ -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
index 00000000000..5c971e6208a
--- /dev/null
+++ b/libstdc++/stl/stl_tempbuf.h
@@ -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
index 00000000000..55a6c0e53b2
--- /dev/null
+++ b/libstdc++/stl/stl_tree.h
@@ -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
index 00000000000..661bbe998e4
--- /dev/null
+++ b/libstdc++/stl/stl_uninitialized.h
@@ -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
index 00000000000..cfa7fdb62d3
--- /dev/null
+++ b/libstdc++/stl/stl_vector.h
@@ -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:
diff --git a/libstdc++/stl/tempbuf.h b/libstdc++/stl/tempbuf.h
index 18d995252d8..8799393f39f 100644
--- a/libstdc++/stl/tempbuf.h
+++ b/libstdc++/stl/tempbuf.h
@@ -27,95 +27,32 @@
#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:
diff --git a/libstdc++/stl/tree.h b/libstdc++/stl/tree.h
index 80e0cafa352..77c57cbbba1 100644
--- a/libstdc++/stl/tree.h
+++ b/libstdc++/stl/tree.h
@@ -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
@@ -29,1069 +29,18 @@
#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:
diff --git a/libstdc++/stl/type_traits.h b/libstdc++/stl/type_traits.h
index 6ca0137709d..a7b977cc06b 100644
--- a/libstdc++/stl/type_traits.h
+++ b/libstdc++/stl/type_traits.h
@@ -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
index 00000000000..df8c224388d
--- /dev/null
+++ b/libstdc++/stl/utility
@@ -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
index 00000000000..4bcdebcc186
--- /dev/null
+++ b/libstdc++/stl/vector
@@ -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:
diff --git a/libstdc++/stl/vector.h b/libstdc++/stl/vector.h
index 1c7867e8b03..231a227b7e3 100644
--- a/libstdc++/stl/vector.h
+++ b/libstdc++/stl/vector.h
@@ -27,507 +27,16 @@
#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:
OpenPOWER on IntegriCloud