From: Jason Merrill Date: Tue, 4 Nov 1997 20:14:50 +0000 (+0000) Subject: update to 10/27 STL snapshot X-Git-Tag: releases/egcs-1.0.0~166 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ff5b5c164a4e9f9232b75279653f991110c00a42;p=thirdparty%2Fgcc.git update to 10/27 STL snapshot From-SVN: r16311 --- diff --git a/libstdc++/ChangeLog b/libstdc++/ChangeLog index a0a4184c219f..a8b91e92ecfe 100644 --- a/libstdc++/ChangeLog +++ b/libstdc++/ChangeLog @@ -3,10 +3,16 @@ Sun Nov 2 23:34:09 1997 Manfred Hollstein * configure.in: Use delta.mt for m68k-motorola-sysv. * config/delta.mt: New makefile fragment. +Sun Nov 2 12:14:37 1997 Jason Merrill + + * Makefile.in (install): Some of HEADERS come from the stl dir now. + * algorithm, deque, functional, iterator, list, map, memory, numeric, + queue, set, stack, utility, vector: Now in stl dir. + Fri Oct 10 00:40:00 1997 Jason Merrill * std/bastring.h: Use ibegin internally. Return passed iterator - instead of recalculating it were appropriate. + instead of recalculating it where appropriate. * std/bastring.cc: Adjust for erase. From Yotam Medini: diff --git a/libstdc++/Makefile.in b/libstdc++/Makefile.in index c8f7b145210a..1cd2a6fc3160 100644 --- a/libstdc++/Makefile.in +++ b/libstdc++/Makefile.in @@ -248,7 +248,16 @@ install: rootme=`pwd`/ ; export rootme ; \ if [ -z "$(MULTISUBDIR)" ]; then \ cd $(srcdir); \ - for FILE in $(HEADERS) *.h std/*.*; do \ + for FILE in $(HEADERS); do \ + rm -f $(gxx_includedir)/$$FILE ; \ + if [ -f stl/$$FILE ]; then \ + $(INSTALL_DATA) stl/$$FILE $(gxx_includedir)/$$FILE ; \ + else \ + $(INSTALL_DATA) $$FILE $(gxx_includedir)/$$FILE ; \ + fi ; \ + chmod a-x $(gxx_includedir)/$$FILE ; \ + done ; \ + for FILE in *.h std/*.*; do \ rm -f $(gxx_includedir)/$$FILE ; \ $(INSTALL_DATA) $$FILE $(gxx_includedir)/$$FILE ; \ chmod a-x $(gxx_includedir)/$$FILE ; \ diff --git a/libstdc++/algorithm b/libstdc++/algorithm deleted file mode 100644 index 472d24166401..000000000000 --- a/libstdc++/algorithm +++ /dev/null @@ -1,7 +0,0 @@ -// -*- C++ -*- forwarding header. -// This file is part of the GNU ANSI C++ Library. - -#ifndef __ALGORITHM__ -#define __ALGORITHM__ -#include -#endif diff --git a/libstdc++/deque b/libstdc++/deque deleted file mode 100644 index bdc14299a045..000000000000 --- a/libstdc++/deque +++ /dev/null @@ -1,7 +0,0 @@ -// -*- C++ -*- forwarding header. -// This file is part of the GNU ANSI C++ Library. - -#ifndef __DEQUE__ -#define __DEQUE__ -#include -#endif diff --git a/libstdc++/functional b/libstdc++/functional deleted file mode 100644 index ee8b7f20202e..000000000000 --- a/libstdc++/functional +++ /dev/null @@ -1,7 +0,0 @@ -// -*- C++ -*- forwarding header. -// This file is part of the GNU ANSI C++ Library. - -#ifndef __FUNCTIONAL__ -#define __FUNCTIONAL__ -#include -#endif diff --git a/libstdc++/iterator b/libstdc++/iterator deleted file mode 100644 index a0fa054c5ec6..000000000000 --- a/libstdc++/iterator +++ /dev/null @@ -1,7 +0,0 @@ -// -*- C++ -*- forwarding header. -// This file is part of the GNU ANSI C++ Library. - -#ifndef __ITERATOR__ -#define __ITERATOR__ -#include -#endif diff --git a/libstdc++/list b/libstdc++/list deleted file mode 100644 index 475d8443d167..000000000000 --- a/libstdc++/list +++ /dev/null @@ -1,7 +0,0 @@ -// -*- C++ -*- forwarding header. -// This file is part of the GNU ANSI C++ Library. - -#ifndef __LIST__ -#define __LIST__ -#include -#endif diff --git a/libstdc++/map b/libstdc++/map deleted file mode 100644 index 0127b9db250f..000000000000 --- a/libstdc++/map +++ /dev/null @@ -1,7 +0,0 @@ -// -*- C++ -*- forwarding header. -// This file is part of the GNU ANSI C++ Library. - -#ifndef __MAP__ -#define __MAP__ -#include -#endif diff --git a/libstdc++/memory b/libstdc++/memory deleted file mode 100644 index 8328720db6d5..000000000000 --- a/libstdc++/memory +++ /dev/null @@ -1,7 +0,0 @@ -// -*- C++ -*- forwarding header. -// This file is part of the GNU ANSI C++ Library. - -#ifndef __MEMORY__ -#define __MEMORY__ -#include -#endif diff --git a/libstdc++/numeric b/libstdc++/numeric deleted file mode 100644 index dcb88737f171..000000000000 --- a/libstdc++/numeric +++ /dev/null @@ -1,7 +0,0 @@ -// -*- C++ -*- forwarding header. -// This file is part of the GNU ANSI C++ Library. - -#ifndef __NUMERIC__ -#define __NUMERIC__ -#include -#endif diff --git a/libstdc++/queue b/libstdc++/queue deleted file mode 100644 index e71ce343067c..000000000000 --- a/libstdc++/queue +++ /dev/null @@ -1,7 +0,0 @@ -// -*- C++ -*- forwarding header. -// This file is part of the GNU ANSI C++ Library. - -#ifndef __QUEUE__ -#define __QUEUE__ -#include -#endif diff --git a/libstdc++/set b/libstdc++/set deleted file mode 100644 index 0353285fe502..000000000000 --- a/libstdc++/set +++ /dev/null @@ -1,7 +0,0 @@ -// -*- C++ -*- forwarding header. -// This file is part of the GNU ANSI C++ Library. - -#ifndef __SET__ -#define __SET__ -#include -#endif diff --git a/libstdc++/stack b/libstdc++/stack deleted file mode 100644 index dfe0c51e1813..000000000000 --- a/libstdc++/stack +++ /dev/null @@ -1,7 +0,0 @@ -// -*- C++ -*- forwarding header. -// This file is part of the GNU ANSI C++ Library. - -#ifndef __STACK__ -#define __STACK__ -#include -#endif diff --git a/libstdc++/stl/ChangeLog b/libstdc++/stl/ChangeLog index ca1c01a626f3..7d0c62ab462e 100644 --- a/libstdc++/stl/ChangeLog +++ b/libstdc++/stl/ChangeLog @@ -1,3 +1,21 @@ +Sun Nov 2 12:14:56 1997 Jason Merrill + + * 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 * tree.h, vector.h: Fix accidental divergence from SGI release. diff --git a/libstdc++/stl/algo.h b/libstdc++/stl/algo.h index 2f142898d8b9..1707868c7c43 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 -#include #include -#include #include - -#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) -#pragma set woff 1209 -#endif - -template -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 -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 -Function for_each(InputIterator first, InputIterator last, Function f) { - for ( ; first != last; ++first) - f(*first); - return f; -} - -template -InputIterator find(InputIterator first, InputIterator last, const T& value) { - while (first != last && *first != value) ++first; - return first; -} - -template -InputIterator find_if(InputIterator first, InputIterator last, - Predicate pred) { - while (first != last && !pred(*first)) ++first; - return first; -} - -template -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 -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 -void count(InputIterator first, InputIterator last, const T& value, - Size& n) { - for ( ; first != last; ++first) - if (*first == value) - ++n; -} - -template -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 -iterator_traits::difference_type -count(InputIterator first, InputIterator last, const T& value) { - iterator_traits::difference_type n = 0; - for ( ; first != last; ++first) - if (*first == value) - ++n; - return n; -} - -template -iterator_traits::difference_type -count_if(InputIterator first, InputIterator last, Predicate pred) { - iterator_traits::difference_type n = 0; - for ( ; first != last; ++first) - if (pred(*first)) - ++n; - return n; -} - - -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - -template -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 -inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2) -{ - return __search(first1, last1, first2, last2, distance_type(first1), - distance_type(first2)); -} - -template -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 -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 -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 -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 -ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2) { - for ( ; first1 != last1; ++first1, ++first2) - iter_swap(first1, first2); - return first2; -} - -template -OutputIterator transform(InputIterator first, InputIterator last, - OutputIterator result, UnaryOperation op) { - for ( ; first != last; ++first, ++result) - *result = op(*first); - return result; -} - -template -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 -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 -void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, - const T& new_value) { - for ( ; first != last; ++first) - if (pred(*first)) *first = new_value; -} - -template -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 -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 -void generate(ForwardIterator first, ForwardIterator last, Generator gen) { - for ( ; first != last; ++first) - *first = gen(); -} - -template -OutputIterator generate_n(OutputIterator first, Size n, Generator gen) { - for ( ; n > 0; --n, ++first) - *first = gen(); - return first; -} - -template -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 -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 -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 -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 -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 -inline BidirectionalIterator __unique_copy(InputIterator first, - InputIterator last, - BidirectionalIterator result, - bidirectional_iterator_tag) { - return __unique_copy(first, last, result, forward_iterator_tag()); -} - -template -inline RandomAccessIterator __unique_copy(InputIterator first, - InputIterator last, - RandomAccessIterator result, - random_access_iterator_tag) { - return __unique_copy(first, last, result, forward_iterator_tag()); -} - -template -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 -inline OutputIterator __unique_copy(InputIterator first, InputIterator last, - OutputIterator result, - output_iterator_tag) { - return __unique_copy(first, last, result, value_type(first)); -} - -template -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 -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 -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 -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 -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 -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 -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 -ForwardIterator unique(ForwardIterator first, ForwardIterator last) { - first = adjacent_find(first, last); - return unique_copy(first, last, first); -} - -template -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 -void __reverse(BidirectionalIterator first, BidirectionalIterator last, - bidirectional_iterator_tag) { - while (true) - if (first == last || first == --last) - return; - else - iter_swap(first++, last); -} - -template -void __reverse(RandomAccessIterator first, RandomAccessIterator last, - random_access_iterator_tag) { - while (first < last) iter_swap(first++, --last); -} - -template -inline void reverse(BidirectionalIterator first, BidirectionalIterator last) { - __reverse(first, last, iterator_category(first)); -} - -template -OutputIterator reverse_copy(BidirectionalIterator first, - BidirectionalIterator last, - OutputIterator result) { - while (first != last) { - --last; - *result = *last; - ++result; - } - return result; -} - -template -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 -void __rotate(BidirectionalIterator first, BidirectionalIterator middle, - BidirectionalIterator last, Distance*, - bidirectional_iterator_tag) { - reverse(first, middle); - reverse(middle, last); - reverse(first, last); -} - -template -EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n) -{ - while (n != 0) { - EuclideanRingElement t = m % n; - m = n; - n = t; - } - return m; -} - -template -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 -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 -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 -OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle, - ForwardIterator last, OutputIterator result) { - return copy(first, middle, copy(middle, last, result)); -} - -template -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 -inline void random_shuffle(RandomAccessIterator first, - RandomAccessIterator last) { - __random_shuffle(first, last, distance_type(first)); -} - -template -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -inline ForwardIterator __stable_partition_aux(ForwardIterator first, - ForwardIterator last, - Predicate pred, T*, Distance*) { - temporary_buffer 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 -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 -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 -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 -void __unguarded_linear_insert(RandomAccessIterator last, T value) { - RandomAccessIterator next = last; - --next; - while (value < *next) { - *last = *next; - last = next; - --next; - } - *last = value; -} - -template -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 -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 -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 -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 -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 -void __unguarded_insertion_sort_aux(RandomAccessIterator first, - RandomAccessIterator last, T*) { - for (RandomAccessIterator i = first; i != last; ++i) - __unguarded_linear_insert(i, T(*i)); -} - -template -inline void __unguarded_insertion_sort(RandomAccessIterator first, - RandomAccessIterator last) { - __unguarded_insertion_sort_aux(first, last, value_type(first)); -} - -template -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 -inline void __unguarded_insertion_sort(RandomAccessIterator first, - RandomAccessIterator last, - Compare comp) { - __unguarded_insertion_sort_aux(first, last, value_type(first), comp); -} - -template -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 -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 -Size __lg(Size n) { - Size k; - for (k = 0; n != 1; n = n / 2) ++k; - return k; -} - -template -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -inline void __stable_sort_aux(RandomAccessIterator first, - RandomAccessIterator last, T*, Distance*) { - temporary_buffer buf(first, last); - if (buf.begin() == 0) - __inplace_stable_sort(first, last); - else - __stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size())); -} - -template -inline void __stable_sort_aux(RandomAccessIterator first, - RandomAccessIterator last, T*, Distance*, - Compare comp) { - temporary_buffer 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 -inline void stable_sort(RandomAccessIterator first, - RandomAccessIterator last) { - __stable_sort_aux(first, last, value_type(first), distance_type(first)); -} - -template -inline void stable_sort(RandomAccessIterator first, - RandomAccessIterator last, Compare comp) { - __stable_sort_aux(first, last, value_type(first), distance_type(first), - comp); -} - -template -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 -inline void partial_sort(RandomAccessIterator first, - RandomAccessIterator middle, - RandomAccessIterator last) { - __partial_sort(first, middle, last, value_type(first)); -} - -template -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 -inline void partial_sort(RandomAccessIterator first, - RandomAccessIterator middle, - RandomAccessIterator last, Compare comp) { - __partial_sort(first, middle, last, value_type(first), comp); -} - -template -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 -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 -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 -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 -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 -inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last) { - __nth_element(first, nth, last, value_type(first)); -} - -template -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 -inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last, Compare comp) { - __nth_element(first, nth, last, value_type(first), comp); -} - -template -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 -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 -inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, - const T& value) { - return __lower_bound(first, last, value, distance_type(first), - iterator_category(first)); -} - -template -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 -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 -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 -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 -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 -inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, - const T& value) { - return __upper_bound(first, last, value, distance_type(first), - iterator_category(first)); -} - -template -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 -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 -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 -pair -__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(left, right); - } - } - return pair(first, first); -} - -template -pair -__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(left, - right); - } - } - return pair(first, first); -} - -template -inline pair -equal_range(ForwardIterator first, ForwardIterator last, const T& value) { - return __equal_range(first, last, value, distance_type(first), - iterator_category(first)); -} - -template -pair -__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(left, right); - } - } - return pair(first, first); -} - -template -pair -__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(left, - right); - } - } - return pair(first, first); -} - -template -inline pair -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 -bool binary_search(ForwardIterator first, ForwardIterator last, - const T& value) { - ForwardIterator i = lower_bound(first, last, value); - return i != last && !(value < *i); -} - -template -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 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 -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 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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -T accumulate(InputIterator first, InputIterator last, T init) { - for ( ; first != last; ++first) - init = init + *first; - return init; -} - -template -T accumulate(InputIterator first, InputIterator last, T init, - BinaryOperation binary_op) { - for ( ; first != last; ++first) - init = binary_op(init, *first); - return init; -} - -template -T inner_product(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, T init) { - for ( ; first1 != last1; ++first1, ++first2) - init = init + (*first1 * *first2); - return init; -} - -template -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 -OutputIterator __partial_sum(InputIterator first, InputIterator last, - OutputIterator result, T*) { - T value = *first; - while (++first != last) { - value = value + *first; - *++result = value; - } - return ++result; -} - -template -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -BidirectionalIterator1 -__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1, - BidirectionalIterator2 first2, BidirectionalIterator2 last2, - bidirectional_iterator_tag, bidirectional_iterator_tag) -{ - typedef reverse_iterator reviter1; - typedef reverse_iterator 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 -BidirectionalIterator1 -__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1, - BidirectionalIterator2 first2, BidirectionalIterator2 last2, - bidirectional_iterator_tag, bidirectional_iterator_tag, - BinaryPredicate comp) -{ - typedef reverse_iterator reviter1; - typedef reverse_iterator 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 -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 -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 -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 -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 -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::iterator_category(), - iterator_traits::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 -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::iterator_category(), - iterator_traits::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 -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 -inline T power(T x, Integer n) { - return power(x, n, multiplies()); -} - - -template -void iota(ForwardIterator first, ForwardIterator last, T value) { - while (first != last) *first++ = value++; -} - -template -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 -inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last) -{ - return __is_heap(first, last, distance_type(first)); -} - - -template -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 -inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last, - StrictWeakOrdering comp) -{ - return __is_heap(first, last, comp, distance_type(first)); -} - - -template -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 -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 +#include + +#ifdef __STL_USE_NAMESPACES + +// Names from +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 +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 eccf465d52c4..f35e7af4a976 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 -#include -#include +#ifndef __SGI_STL_PAIR_H #include +#endif +#ifndef __SGI_STL_ITERATOR_H #include -#include -#include - -template -inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, T*) { - T tmp = *a; - *a = *b; - *b = tmp; -} - -template -inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) { - __iter_swap(a, b, value_type(a)); -} - -template -inline void swap(T& a, T& b) { - T tmp = a; - a = b; - b = tmp; -} - -#ifdef __BORLANDC__ -#include -#else - -template -inline const T& min(const T& a, const T& b) { - return b < a ? b : a; -} - -template -inline const T& max(const T& a, const T& b) { - return a < b ? b : a; -} - #endif - -template -inline const T& min(const T& a, const T& b, Compare comp) { - return comp(b, a) ? b : a; -} - -template -inline const T& max(const T& a, const T& b, Compare comp) { - return comp(a, b) ? b : a; -} - -template -inline void __distance(InputIterator first, InputIterator last, Distance& n, - input_iterator_tag) { - while (first != last) { ++first; ++n; } -} - -template -inline void __distance(RandomAccessIterator first, RandomAccessIterator last, - Distance& n, random_access_iterator_tag) { - n += last - first; -} - -template -inline void distance(InputIterator first, InputIterator last, Distance& n) { - __distance(first, last, n, iterator_category(first)); -} - -#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION - -template -inline iterator_traits::difference_type -__distance(InputIterator first, InputIterator last, input_iterator_tag) { - iterator_traits::difference_type n = 0; - while (first != last) { - ++first; ++n; - } - return n; -} - -template -inline iterator_traits::difference_type -__distance(RandomAccessIterator first, RandomAccessIterator last, - random_access_iterator_tag) { - return last - first; -} - -template -inline iterator_traits::difference_type -distance(InputIterator first, InputIterator last) { - return __distance(first, last, - iterator_traits::iterator_category()); -} - -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - -template -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 #endif - -template -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 #endif -template -inline void __advance(RandomAccessIterator& i, Distance n, - random_access_iterator_tag) { - i += n; -} - -template -inline void advance(InputIterator& i, Distance n) { - __advance(i, n, iterator_category(i)); -} - -template -inline OutputIterator __copy(InputIterator first, InputIterator last, - OutputIterator result, input_iterator_tag) -{ - for ( ; first != last; ++result, ++first) - *result = *first; - return result; -} - -template -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 -inline OutputIterator -__copy(RandomAccessIterator first, RandomAccessIterator last, - OutputIterator result, random_access_iterator_tag) -{ - return __copy_d(first, last, result, distance_type(first)); -} - -template -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 -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 -inline T* __copy_t(const T* first, const T* last, T* result, __false_type) { - return __copy_d(first, last, result, (ptrdiff_t*) 0); -} - -template -struct __copy_dispatch -{ - T* operator()(T* first, T* last, T* result) { - return __copy_t(first, last, result, - __type_traits::has_trivial_assignment_operator()); - } -}; - -template -struct __copy_dispatch -{ - T* operator()(const T* first, const T* last, T* result) { - return __copy_t(first, last, result, - __type_traits::has_trivial_assignment_operator()); - } -}; - -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - -template -inline OutputIterator copy(InputIterator first, InputIterator last, - OutputIterator result) -{ - return __copy_dispatch()(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 -inline BidirectionalIterator2 __copy_backward(BidirectionalIterator1 first, - BidirectionalIterator1 last, - BidirectionalIterator2 result) { - while (first != last) *--result = *--last; - return result; -} - - -template -struct __copy_backward_dispatch -{ - BidirectionalIterator2 operator()(BidirectionalIterator1 first, - BidirectionalIterator1 last, - BidirectionalIterator2 result) { - return __copy_backward(first, last, result); - } -}; - -#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION - -template -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 -inline T* __copy_backward_t(const T* first, const T* last, T* result, - __false_type) { - return __copy_backward(first, last, result); -} - -template -struct __copy_backward_dispatch -{ - T* operator()(T* first, T* last, T* result) { - return - __copy_backward_t(first, last, result, - __type_traits::has_trivial_assignment_operator()); - } -}; - -template -struct __copy_backward_dispatch -{ - T* operator()(const T* first, const T* last, T* result) { - return - __copy_backward_t(first, last, result, - __type_traits::has_trivial_assignment_operator()); - } -}; - -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - -template -inline BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, - BidirectionalIterator1 last, - BidirectionalIterator2 result) { - return __copy_backward_dispatch()(first, last, - result); -} - -template -OutputIterator __copy_n(InputIterator first, Size count, - OutputIterator result, - input_iterator_tag) { - for ( ; count > 0; --count, ++first, ++result) - *result = *first; - return result; -} - -template -inline OutputIterator __copy_n(RandomAccessIterator first, Size count, - OutputIterator result, - random_access_iterator_tag) { - return copy(first, first + count, result); -} - -template -inline OutputIterator copy_n(InputIterator first, Size count, - OutputIterator result) { - return __copy_n(first, count, result, iterator_category(first)); -} - -template -void fill(ForwardIterator first, ForwardIterator last, const T& value) { - for ( ; first != last; ++first) - *first = value; -} - -template -OutputIterator fill_n(OutputIterator first, Size n, const T& value) { - for ( ; n > 0; --n, ++first) - *first = value; - return first; -} - -template -pair mismatch(InputIterator1 first1, - InputIterator1 last1, - InputIterator2 first2) { - while (first1 != last1 && *first1 == *first2) { - ++first1; - ++first2; - } - return pair(first1, first2); -} - -template -pair mismatch(InputIterator1 first1, - InputIterator1 last1, - InputIterator2 first2, - BinaryPredicate binary_pred) { - while (first1 != last1 && binary_pred(*first1, *first2)) { - ++first1; - ++first2; - } - return pair(first1, first2); -} - -template -inline bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2) { - for ( ; first1 != last1; ++first1, ++first2) - if (*first1 != *first2) - return false; - return true; -} - -template -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 -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 -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 -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 -inline void destroy(T* pointer) { - pointer->~T(); -} - -template -inline void construct(T1* p, const T2& value) { - new (p) T1(value); -} - -template -inline void -__destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) { - for ( ; first < last; ++first) - destroy(&*first); -} - -template -inline void __destroy_aux(ForwardIterator, ForwardIterator, __true_type) { -} - -template -inline void __destroy(ForwardIterator first, ForwardIterator last, T*) { - __destroy_aux(first, last, __type_traits::has_trivial_destructor()); -} - -template -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 -inline ForwardIterator -__uninitialized_copy_aux(InputIterator first, InputIterator last, - ForwardIterator result, - __true_type) { - return copy(first, last, result); -} - -template -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 -inline ForwardIterator -__uninitialized_copy(InputIterator first, InputIterator last, - ForwardIterator result, T*) { - return __uninitialized_copy_aux(first, last, result, - __type_traits::is_POD_type()); -} - -template -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 -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 -inline ForwardIterator -__uninitialized_copy_n(RandomAccessIterator first, Size count, - ForwardIterator result, - random_access_iterator_tag) { - return uninitialized_copy(first, first + count, result); -} - -template -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 -inline void -__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, - const T& x, __true_type) -{ - fill(first, last, x); -} - -template -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 -inline void __uninitialized_fill(ForwardIterator first, ForwardIterator last, - const T& x, T1*) { - __uninitialized_fill_aux(first, last, x, - __type_traits::is_POD_type()); -} - -template -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 -inline ForwardIterator -__uninitialized_fill_n_aux(ForwardIterator first, Size n, - const T& x, __true_type) { - return fill_n(first, n, x); -} - -template -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 -inline ForwardIterator __uninitialized_fill_n(ForwardIterator first, Size n, - const T& x, T1*) { - return __uninitialized_fill_n_aux(first, n, x, - __type_traits::is_POD_type()); -} - -template -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 -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 -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 -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/alloc.h b/libstdc++/stl/alloc.h index 8831976c6149..7cc961006057 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 - -#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 -# define __THROW_BAD_ALLOC throw bad_alloc -#elif !defined(__THROW_BAD_ALLOC) -# include -# define __THROW_BAD_ALLOC cerr << "out of memory" << endl; exit(1) -#endif - -#ifndef __ALLOC -# define __ALLOC alloc -#endif -#ifdef __STL_WIN32THREADS -# include -#endif - -#include -#include -#include -#include -#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 #endif -# ifdef _PTHREADS - // POSIX Threads - // This is dubious, since this is likely to be a high contention - // lock. Performance may not be adequate. -# include -# 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 - // 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 -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 -void (* __malloc_alloc_template::__malloc_alloc_oom_handler)() = 0; -#endif - -template -void * __malloc_alloc_template::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 -void * __malloc_alloc_template::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 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 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 -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 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 -char* -__default_alloc_template::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 -void* __default_alloc_template::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 -void* -__default_alloc_template::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 - pthread_mutex_t - __default_alloc_template::__node_allocator_lock - = PTHREAD_MUTEX_INITIALIZER; -#endif - -#ifdef __STL_WIN32THREADS - template CRITICAL_SECTION - __default_alloc_template::__node_allocator_lock; - - template bool - __default_alloc_template::__node_allocator_lock_initialized - = false; -#endif - -#ifdef __STL_SGI_THREADS -#include -#include -// 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 -volatile unsigned long -__default_alloc_template::__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 -void -__default_alloc_template::__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 -inline void -__default_alloc_template::__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 -char *__default_alloc_template::start_free = 0; - -template -char *__default_alloc_template::end_free = 0; - -template -size_t __default_alloc_template::heap_size = 0; - -template -__default_alloc_template::obj * __VOLATILE -__default_alloc_template ::free_list[ -# ifdef __SUNPRO_CC - __NFREELISTS -# else - __default_alloc_template::__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 71b49173c400..03a3fb1c7f23 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 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 +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION +#include +#else #include #include +#endif +#include -#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 { - 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 - { - 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_reverse_iterator; - typedef reverse_iterator reverse_iterator; -#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - typedef reverse_iterator const_reverse_iterator; - typedef reverse_iterator - reverse_iterator; -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - -protected: - typedef simple_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 - 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 - 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 - 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 - 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 - 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 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 e7d24d38c84c..49690f8d6e07 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.h b/libstdc++/stl/deque.h index e202a1173985..ede38b1ceba8 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 #include #include +#include -// 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 -struct __deque_iterator { - typedef __deque_iterator iterator; - typedef __deque_iterator const_iterator; - static size_t buffer_size() {return __deque_buf_size(BufSiz, sizeof(T)); } -#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ -template -struct __deque_iterator { - typedef __deque_iterator iterator; - typedef __deque_iterator 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 -inline random_access_iterator_tag -iterator_category(const __deque_iterator&) { - return random_access_iterator_tag(); -} - -template -inline T* value_type(const __deque_iterator&) { - return 0; -} - -template -inline ptrdiff_t* distance_type(const __deque_iterator&) { - return 0; -} - -#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ - -template -inline random_access_iterator_tag -iterator_category(const __deque_iterator&) { - return random_access_iterator_tag(); -} - -template -inline T* value_type(const __deque_iterator&) { return 0; } - -template -inline ptrdiff_t* distance_type(const __deque_iterator&) { - 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 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 iterator; - typedef __deque_iterator const_iterator; -#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ - typedef __deque_iterator iterator; - typedef __deque_iterator const_iterator; -#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ - -#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION - typedef reverse_iterator const_reverse_iterator; - typedef reverse_iterator reverse_iterator; -#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - typedef reverse_iterator - const_reverse_iterator; - typedef reverse_iterator - reverse_iterator; -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - -protected: // Internal typedefs - typedef pointer* map_pointer; - typedef simple_alloc data_allocator; - typedef simple_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 - 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 - 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 - void range_initialize(InputIterator first, InputIterator last, - input_iterator_tag); - - template - 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 - void insert(iterator pos, InputIterator first, InputIterator last, - input_iterator_tag); - - template - 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 - 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& x) const { - return size() == x.size() && equal(begin(), end(), x.begin()); - } - bool operator!=(const deque& x) const { - return size() != x.size() || !equal(begin(), end(), x.begin()); - } - bool operator<(const deque& x) const { - return lexicographical_compare(begin(), end(), x.begin(), x.end()); - } -#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ -}; - -// Non-inline member functions - -template -void deque::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 -void deque::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 -void deque::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 -void deque::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 -void deque::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 -void deque::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 -void deque::destroy_map_and_nodes() { - for (map_pointer cur = start.node; cur <= finish.node; ++cur) - deallocate_node(*cur); - map_allocator::deallocate(map, map_size); -} - - -template -void deque::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 -template -void deque::range_initialize(InputIterator first, - InputIterator last, - input_iterator_tag) { - create_map_and_nodes(0); - for ( ; first != last; ++first) - push_back(*first); -} - -template -template -void deque::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 -void deque::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 -void deque::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 -void deque:: 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 -void deque::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 -template -void deque::insert(iterator pos, - InputIterator first, InputIterator last, - input_iterator_tag) { - copy(first, last, inserter(*this, pos)); -} - -template -template -void deque::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 -deque::iterator -deque::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 -void deque::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 -template -void deque::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 -void deque::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 -void deque::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 -void deque::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 -void deque::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 -void deque::destroy_nodes_at_front(iterator before_start) { - for (map_pointer n = before_start.node; n < start.node; ++n) - deallocate_node(*n); -} - -template -void deque::destroy_nodes_at_back(iterator after_finish) { - for (map_pointer n = after_finish.node; n > finish.node; --n) - deallocate_node(*n); -} - -template -void deque::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 -bool operator==(const deque& x, - const deque& y) { - return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); -} - -template -bool operator<(const deque& x, - const deque& 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 e4f4713235b9..6474dd99fa2e 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 +#ifndef __STL_CONFIG_H #include - -template -inline bool operator!=(const T& x, const T& y) { - return !(x == y); -} - -template -inline bool operator>(const T& x, const T& y) { - return y < x; -} - -template -inline bool operator<=(const T& x, const T& y) { - return !(y < x); -} - -template -inline bool operator>=(const T& x, const T& y) { - return !(x < y); -} - -template -struct unary_function { - typedef Arg argument_type; - typedef Result result_type; -}; - -template -struct binary_function { - typedef Arg1 first_argument_type; - typedef Arg2 second_argument_type; - typedef Result result_type; -}; - -template -struct plus : public binary_function { - T operator()(const T& x, const T& y) const { return x + y; } -}; - -template -struct minus : public binary_function { - T operator()(const T& x, const T& y) const { return x - y; } -}; - -template -struct multiplies : public binary_function { - T operator()(const T& x, const T& y) const { return x * y; } -}; - -template -struct divides : public binary_function { - T operator()(const T& x, const T& y) const { return x / y; } -}; - -template inline T identity_element(plus) { return T(0); } - -template inline T identity_element(multiplies) { return T(1); } - -template -struct modulus : public binary_function { - T operator()(const T& x, const T& y) const { return x % y; } -}; - -template -struct negate : public unary_function { - T operator()(const T& x) const { return -x; } -}; - -template -struct equal_to : public binary_function { - bool operator()(const T& x, const T& y) const { return x == y; } -}; - -template -struct not_equal_to : public binary_function { - bool operator()(const T& x, const T& y) const { return x != y; } -}; - -template -struct greater : public binary_function { - bool operator()(const T& x, const T& y) const { return x > y; } -}; - -template -struct less : public binary_function { - bool operator()(const T& x, const T& y) const { return x < y; } -}; - -template -struct greater_equal : public binary_function { - bool operator()(const T& x, const T& y) const { return x >= y; } -}; - -template -struct less_equal : public binary_function { - bool operator()(const T& x, const T& y) const { return x <= y; } -}; - -template -struct logical_and : public binary_function { - bool operator()(const T& x, const T& y) const { return x && y; } -}; - -template -struct logical_or : public binary_function { - bool operator()(const T& x, const T& y) const { return x || y; } -}; - -template -struct logical_not : public unary_function { - bool operator()(const T& x) const { return !x; } -}; - -template -class unary_negate - : public unary_function { -protected: - Predicate pred; -public: - explicit unary_negate(const Predicate& x) : pred(x) {} - bool operator()(const argument_type& x) const { return !pred(x); } -}; - -template -inline unary_negate not1(const Predicate& pred) { - return unary_negate(pred); -} - -template -class binary_negate - : public binary_function { -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 -inline binary_negate not2(const Predicate& pred) { - return binary_negate(pred); -} - -template -class binder1st - : public unary_function { -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 -inline binder1st bind1st(const Operation& op, const T& x) { - typedef typename Operation::first_argument_type arg1_type; - return binder1st(op, arg1_type(x)); -} - -template -class binder2nd - : public unary_function { -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 -inline binder2nd bind2nd(const Operation& op, const T& x) { - typedef typename Operation::second_argument_type arg2_type; - return binder2nd(op, arg2_type(x)); -} - -template -class unary_compose : public unary_function { -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 -inline unary_compose compose1(const Operation1& op1, - const Operation2& op2) { - return unary_compose(op1, op2); -} - -template -class binary_compose - : public unary_function { -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 -inline binary_compose -compose2(const Operation1& op1, const Operation2& op2, const Operation3& op3) { - return binary_compose(op1, op2, op3); -} - -template -class pointer_to_unary_function : public unary_function { -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 -inline pointer_to_unary_function ptr_fun(Result (*x)(Arg)) { - return pointer_to_unary_function(x); -} - -template -class pointer_to_binary_function : public binary_function { -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 -inline pointer_to_binary_function -ptr_fun(Result (*x)(Arg1, Arg2)) { - return pointer_to_binary_function(x); -} - -template -struct identity : public unary_function { - const T& operator()(const T& x) const { return x; } -}; - -template -struct select1st : public unary_function { - const typename Pair::first_type& operator()(const Pair& x) const - { - return x.first; - } -}; - -template -struct select2nd : public unary_function { - const typename Pair::second_type& operator()(const Pair& x) const - { - return x.second; - } -}; - -template -struct project1st : public binary_function { - Arg1 operator()(const Arg1& x, const Arg2&) const { return x; } -}; - -template -struct project2nd : public binary_function { - Arg2 operator()(const Arg1&, const Arg2& y) const { return y; } -}; - -template -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 -#else -template #endif -struct constant_unary_fun : public unary_function { - 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 -#else -template +#ifndef __SGI_STL_INTERNAL_RELOPS +#include +#endif +#include +#ifndef __SGI_STL_INTERNAL_FUNCTION_H +#include #endif -struct constant_binary_fun : public binary_function { - 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 -inline constant_void_fun constant0(const Result& val) -{ - return constant_void_fun(val); -} - -template -inline constant_unary_fun constant1(const Result& val) -{ - return constant_unary_fun(val); -} - -template -inline constant_binary_fun constant2(const Result& val) -{ - return constant_binary_fun(val); -} - -// Note: this code assumes that int is 32 bits. -class subtractive_rng : public unary_function { -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 mem_fun_t : public unary_function { -public: - explicit mem_fun_t(S (T::*pf)()) : f(pf) {} - S operator()(T* p) const { return (p->*f)(); } -private: - S (T::*f)(); -}; - -template -class const_mem_fun_t : public unary_function { -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 mem_fun_ref_t : public unary_function { -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 const_mem_fun_ref_t : public unary_function { -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 mem_fun1_t : public binary_function { -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 const_mem_fun1_t : public binary_function { -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 mem_fun1_ref_t : public binary_function { -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 const_mem_fun1_ref_t : public binary_function { -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 mem_fun_t : public unary_function { -public: - explicit mem_fun_t(void (T::*pf)()) : f(pf) {} - void operator()(T* p) const { (p->*f)(); } -private: - void (T::*f)(); -}; - -template -class const_mem_fun_t : public unary_function { -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 mem_fun_ref_t : public unary_function { -public: - explicit mem_fun_ref_t(void (T::*pf)()) : f(pf) {} - void operator()(T& r) const { (r.*f)(); } -private: - void (T::*f)(); -}; - -template -class const_mem_fun_ref_t : public unary_function { -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 mem_fun1_t : public binary_function { -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 const_mem_fun1_t : public binary_function { -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 mem_fun1_ref_t : public binary_function { -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 const_mem_fun1_ref_t : public binary_function { -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 -inline mem_fun_t mem_fun(S (T::*f)()) { - return mem_fun_t(f); -} - -template -inline const_mem_fun_t mem_fun(S (T::*f)() const) { - return const_mem_fun_t(f); -} - -template -inline mem_fun_ref_t mem_fun_ref(S (T::*f)()) { - return mem_fun_ref_t(f); -} - -template -inline const_mem_fun_ref_t mem_fun_ref(S (T::*f)() const) { - return const_mem_fun_ref_t(f); -} - -template -inline mem_fun1_t mem_fun1(S (T::*f)(A)) { - return mem_fun1_t(f); -} - -template -inline const_mem_fun1_t mem_fun1(S (T::*f)(A) const) { - return const_mem_fun1_t(f); -} - -template -inline mem_fun1_ref_t mem_fun1_ref(S (T::*f)(A)) { - return mem_fun1_ref_t(f); -} -template -inline const_mem_fun1_ref_t mem_fun1_ref(S (T::*f)(A) const) { - return const_mem_fun1_ref_t(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/hash_map.h b/libstdc++/stl/hash_map.h index c52b9936e7b2..81cb5784f474 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 -#endif /* __SGI_STL_HASHTABLE_H */ +#ifndef __SGI_STL_INTERNAL_HASHTABLE_H +#include +#endif +#include -#ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , - class EqualKey = equal_to, - class Alloc = alloc> -#else -template -#endif -class hash_map -{ -private: - typedef hashtable, Key, HashFcn, - select1st >, 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 - hash_map(InputIterator f, InputIterator l) - : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } - template - hash_map(InputIterator f, InputIterator l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } - template - hash_map(InputIterator f, InputIterator l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } - template - 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&, - 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 insert(const value_type& obj) - { return rep.insert_unique(obj); } -#ifdef __STL_MEMBER_TEMPLATES - template - 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 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 equal_range(const key_type& key) - { return rep.equal_range(key); } - pair 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 -inline bool operator==(const hash_map& hm1, - const hash_map& hm2) -{ - return hm1.rep == hm2.rep; -} - -#ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , - class EqualKey = equal_to, - class Alloc = alloc> -#else -template -#endif -class hash_multimap -{ -private: - typedef hashtable, Key, HashFcn, - select1st >, 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 - hash_multimap(InputIterator f, InputIterator l) - : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } - template - hash_multimap(InputIterator f, InputIterator l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } - template - hash_multimap(InputIterator f, InputIterator l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } - template - 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&, - 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 - 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 equal_range(const key_type& key) - { return rep.equal_range(key); } - pair 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 -inline bool operator==(const hash_multimap& hm1, - const hash_multimap& hm2) -{ - return hm1.rep == hm2.rep; -} #endif /* __SGI_STL_HASH_MAP_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++/stl/hash_set.h b/libstdc++/stl/hash_set.h index 2c7125eb7e51..c938ccc467ab 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 -#endif /* __SGI_STL_HASHTABLE_H */ - -#ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , - class EqualKey = equal_to, - class Alloc = alloc> -#else -template -#endif -class hash_set -{ -private: - typedef hashtable, - 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 - hash_set(InputIterator f, InputIterator l) - : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } - template - hash_set(InputIterator f, InputIterator l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } - template - hash_set(InputIterator f, InputIterator l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } - template - 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&, - const hash_set&); - - iterator begin() const { return rep.begin(); } - iterator end() const { return rep.end(); } - -public: - pair insert(const value_type& obj) - { - pair p = rep.insert_unique(obj); - return pair(p.first, p.second); - } -#ifdef __STL_MEMBER_TEMPLATES - template - 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 insert_noresize(const value_type& obj) - { - pair p = rep.insert_unique_noresize(obj); - return pair(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 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 -inline bool operator==(const hash_set& hs1, - const hash_set& hs2) -{ - return hs1.rep == hs2.rep; -} - -#ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , - class EqualKey = equal_to, - class Alloc = alloc> -#else -template -#endif -class hash_multiset -{ -private: - typedef hashtable, - 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 - hash_multiset(InputIterator f, InputIterator l) - : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } - template - hash_multiset(InputIterator f, InputIterator l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } - template - hash_multiset(InputIterator f, InputIterator l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } - template - 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&, - 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 - 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 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 -inline bool operator==(const hash_multiset& hs1, - const hash_multiset& hs2) -{ - return hs1.rep == hs2.rep; -} - +#ifndef __SGI_STL_INTERNAL_HASHTABLE_H +#include +#endif + +#include + +#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 fb4abc2b3440..15dbfc916441 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 -#include +#include #include +#include #include - -template 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 -{ - size_t operator()(const char* s) const { return __stl_hash_string(s); } -}; - -struct hash -{ - size_t operator()(const char* s) const { return __stl_hash_string(s); } -}; - -struct hash { - size_t operator()(char x) const { return x; } -}; -struct hash { - size_t operator()(unsigned char x) const { return x; } -}; -struct hash { - size_t operator()(unsigned char x) const { return x; } -}; -struct hash { - size_t operator()(short x) const { return x; } -}; -struct hash { - size_t operator()(unsigned short x) const { return x; } -}; -struct hash { - size_t operator()(int x) const { return x; } -}; -struct hash { - size_t operator()(unsigned int x) const { return x; } -}; -struct hash { - size_t operator()(long x) const { return x; } -}; -struct hash { - size_t operator()(unsigned long x) const { return x; } -}; - -template -struct __hashtable_node -{ - __hashtable_node* next; - Value val; -}; - -template -class hashtable; - -template -struct __hashtable_iterator; - -template -struct __hashtable_const_iterator; - -template -struct __hashtable_iterator { - typedef hashtable - hashtable; - typedef __hashtable_iterator - iterator; - typedef __hashtable_const_iterator - const_iterator; - typedef __hashtable_node 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 -struct __hashtable_const_iterator { - typedef hashtable - hashtable; - typedef __hashtable_iterator - iterator; - typedef __hashtable_const_iterator - const_iterator; - typedef __hashtable_node 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 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 node; - typedef simple_alloc node_allocator; - - vector buckets; - size_type num_elements; - -public: - typedef __hashtable_iterator - iterator; - - typedef __hashtable_const_iterator - const_iterator; - - friend struct - __hashtable_iterator; - friend struct - __hashtable_const_iterator; - -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&, - 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 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 insert_unique_noresize(const value_type& obj); - iterator insert_equal_noresize(const value_type& obj); - -#ifdef __STL_MEMBER_TEMPLATES - template - void insert_unique(InputIterator f, InputIterator l) - { - insert_unique(f, l, iterator_category(f)); - } - - template - void insert_equal(InputIterator f, InputIterator l) - { - insert_equal(f, l, iterator_category(f)); - } - - template - void insert_unique(InputIterator f, InputIterator l, - input_iterator_tag) - { - for ( ; f != l; ++f) - insert_unique(*f); - } - - template - void insert_equal(InputIterator f, InputIterator l, - input_iterator_tag) - { - for ( ; f != l; ++f) - insert_equal(*f); - } - - template - 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 - 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 equal_range(const key_type& key); - pair 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 -__hashtable_iterator& -__hashtable_iterator::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 -inline __hashtable_iterator -__hashtable_iterator::operator++(int) -{ - iterator tmp = *this; - ++*this; - return tmp; -} - -template -__hashtable_const_iterator& -__hashtable_const_iterator::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 -inline __hashtable_const_iterator -__hashtable_const_iterator::operator++(int) -{ - const_iterator tmp = *this; - ++*this; - return tmp; -} - -#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION - -template -inline forward_iterator_tag -iterator_category(const __hashtable_iterator&) -{ - return forward_iterator_tag(); -} - -template -inline V* value_type(const __hashtable_iterator&) -{ - return (V*) 0; -} - -template -inline hashtable::difference_type* -distance_type(const __hashtable_iterator&) -{ - return (hashtable::difference_type*) 0; -} - -template -inline forward_iterator_tag -iterator_category(const __hashtable_const_iterator&) -{ - return forward_iterator_tag(); -} - -template -inline V* -value_type(const __hashtable_const_iterator&) -{ - return (V*) 0; -} - -template -inline hashtable::difference_type* -distance_type(const __hashtable_const_iterator&) -{ - return (hashtable::difference_type*) 0; -} - -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - -template -bool operator==(const hashtable& ht1, - const hashtable& ht2) -{ - typedef hashtable::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 -pair::iterator, bool> -hashtable::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(cur, this), false); - - node* tmp = new_node(obj); - tmp->next = first; - buckets[n] = tmp; - ++num_elements; - return pair(iterator(tmp, this), true); -} - -template -hashtable::iterator -hashtable::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 -hashtable::reference -hashtable::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 -pair::iterator, - hashtable::iterator> -hashtable::equal_range(const key_type& key) -{ - typedef pair 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 -pair::const_iterator, - hashtable::const_iterator> -hashtable::equal_range(const key_type& key) const -{ - typedef pair 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 -hashtable::size_type -hashtable::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 -void hashtable::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 -void hashtable::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 -inline void -hashtable::erase(const_iterator first, - const_iterator last) -{ - erase(iterator(const_cast(first.cur), - const_cast(first.ht)), - iterator(const_cast(last.cur), - const_cast(last.ht))); -} - -template -inline void -hashtable::erase(const const_iterator& it) -{ - erase(iterator(const_cast(it.cur), - const_cast(it.ht))); -} - -template -void hashtable::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 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 -void hashtable::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 -void -hashtable::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 -void hashtable::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 -void hashtable::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 b24afafadd6d..2ec93c07b765 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 -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 -inline void __push_heap_aux(RandomAccessIterator first, - RandomAccessIterator last, Distance*, T*) { - __push_heap(first, Distance((last - first) - 1), Distance(0), - T(*(last - 1))); -} - -template -inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) { - __push_heap_aux(first, last, distance_type(first), value_type(first)); -} - -template -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 -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 -inline void push_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp) { - __push_heap_aux(first, last, comp, distance_type(first), value_type(first)); -} +#include +#include -template -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 -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 -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 -inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last) { - __pop_heap_aux(first, last, value_type(first)); -} - -template -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 -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 -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 -inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp) { - __pop_heap_aux(first, last, value_type(first), comp); -} - -template -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 -inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) { - __make_heap(first, last, value_type(first), distance_type(first)); -} - -template -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 -inline void make_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp) { - __make_heap(first, last, comp, value_type(first), distance_type(first)); -} - -template -void sort_heap(RandomAccessIterator first, RandomAccessIterator last) { - while (last - first > 1) pop_heap(first, last--); -} - -template -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.h b/libstdc++/stl/iterator.h index f8a19d0aa345..f8a023774228 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 +#endif #include #include -#include - -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 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 struct forward_iterator { - typedef forward_iterator_tag iterator_category; - typedef T value_type; - typedef Distance difference_type; - typedef T* pointer; - typedef T& reference; -}; - - -template struct bidirectional_iterator { - typedef bidirectional_iterator_tag iterator_category; - typedef T value_type; - typedef Distance difference_type; - typedef T* pointer; - typedef T& reference; -}; - -template 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 -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 #endif - -#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION - -template -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 -struct iterator_traits { - typedef random_access_iterator_tag iterator_category; - typedef T value_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef T& reference; -}; - -template -struct iterator_traits { - 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 -inline iterator_traits::iterator_category -iterator_category(const Iterator&) { - return iterator_traits::iterator_category(); -} - -template -inline iterator_traits::difference_type* -distance_type(const Iterator&) { - return static_cast::difference_type*>(0); -} - -template -inline iterator_traits::value_type* -value_type(const Iterator&) { - return static_cast::value_type*>(0); -} - -#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - -template -inline input_iterator_tag -iterator_category(const input_iterator&) { - return input_iterator_tag(); -} - -inline output_iterator_tag iterator_category(const output_iterator&) { - return output_iterator_tag(); -} - -template -inline forward_iterator_tag -iterator_category(const forward_iterator&) { - return forward_iterator_tag(); -} - -template -inline bidirectional_iterator_tag -iterator_category(const bidirectional_iterator&) { - return bidirectional_iterator_tag(); -} - -template -inline random_access_iterator_tag -iterator_category(const random_access_iterator&) { - return random_access_iterator_tag(); -} - -template -inline random_access_iterator_tag iterator_category(const T*) { - return random_access_iterator_tag(); -} - -template -inline T* value_type(const input_iterator&) { - return (T*)(0); -} - -template -inline T* value_type(const forward_iterator&) { - return (T*)(0); -} - -template -inline T* value_type(const bidirectional_iterator&) { - return (T*)(0); -} - -template -inline T* value_type(const random_access_iterator&) { - return (T*)(0); -} - -template -inline T* value_type(const T*) { return (T*)(0); } - -template -inline Distance* distance_type(const input_iterator&) { - return (Distance*)(0); -} - -template -inline Distance* distance_type(const forward_iterator&) { - return (Distance*)(0); -} - -template -inline Distance* -distance_type(const bidirectional_iterator&) { - return (Distance*)(0); -} - -template -inline Distance* -distance_type(const random_access_iterator&) { - return (Distance*)(0); -} - -template -inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); } - -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - -template -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& - operator=(const typename Container::value_type& value) { - container->push_back(value); - return *this; - } - back_insert_iterator& operator*() { return *this; } - back_insert_iterator& operator++() { return *this; } - back_insert_iterator& operator++(int) { return *this; } -}; - -#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION - -template -inline output_iterator_tag -iterator_category(const back_insert_iterator&) -{ - return output_iterator_tag(); -} - -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - -template -inline back_insert_iterator back_inserter(Container& x) { - return back_insert_iterator(x); -} - -template -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& - operator=(const typename Container::value_type& value) { - container->push_front(value); - return *this; - } - front_insert_iterator& operator*() { return *this; } - front_insert_iterator& operator++() { return *this; } - front_insert_iterator& operator++(int) { return *this; } -}; - -#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION - -template -inline output_iterator_tag -iterator_category(const front_insert_iterator&) -{ - return output_iterator_tag(); -} - -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - -template -inline front_insert_iterator front_inserter(Container& x) { - return front_insert_iterator(x); -} - -template -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& - operator=(const typename Container::value_type& value) { - iter = container->insert(iter, value); - ++iter; - return *this; - } - insert_iterator& operator*() { return *this; } - insert_iterator& operator++() { return *this; } - insert_iterator& operator++(int) { return *this; } -}; - -#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION - -template -inline output_iterator_tag -iterator_category(const insert_iterator&) -{ - return output_iterator_tag(); -} - -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - -template -inline insert_iterator inserter(Container& x, Iterator i) { - typedef typename Container::iterator iter; - return insert_iterator(x, iter(i)); -} - -#ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template -#else -template +#ifndef __TYPE_TRAITS_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H +#include #endif -class reverse_bidirectional_iterator { - typedef reverse_bidirectional_iterator 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 -inline bidirectional_iterator_tag -iterator_category(const reverse_bidirectional_iterator&) { - return bidirectional_iterator_tag(); -} -template -inline T* -value_type(const reverse_bidirectional_iterator&) { - return (T*) 0; -} +#ifdef __STL_USE_NAMESPACES -template -inline Distance* -distance_type(const reverse_bidirectional_iterator&) { - 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 -inline bool operator==( - const reverse_bidirectional_iterator& x, - const reverse_bidirectional_iterator& 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 reverse_iterator : public iterator_traits -{ -protected: - Iterator current; -public: - typedef Iterator iterator_type; - typedef reverse_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 - reverse_iterator(const reverse_iterator& 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 -inline bool operator==(const reverse_iterator& x, - const reverse_iterator& y) { - return x.base() == y.base(); -} - -template -inline bool operator<(const reverse_iterator& x, - const reverse_iterator& y) { - return y.base() < x.base(); -} - -template -inline reverse_iterator::difference_type -operator-(const reverse_iterator& x, - const reverse_iterator& y) { - return y.base() - x.base(); -} - -template -inline reverse_iterator -operator+(reverse_iterator::difference_type n, - const reverse_iterator& x) { - return reverse_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 -#else -template +using __STD::iterator_traits; #endif -class reverse_iterator { - typedef reverse_iterator - 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 -inline random_access_iterator_tag -iterator_category(const reverse_iterator&) { - return random_access_iterator_tag(); -} - -template -inline T* value_type(const reverse_iterator&) { - return (T*) 0; -} - -template -inline Distance* distance_type(const reverse_iterator&) { - return (Distance*) 0; -} - - -template -inline bool operator==(const reverse_iterator& x, - const reverse_iterator& y) { - return x.current == y.current; -} - -template -inline bool operator<(const reverse_iterator& x, - const reverse_iterator& y) { - return y.current < x.current; -} - -template -inline Distance operator-(const reverse_iterator& x, - const reverse_iterator& y) { - return y.current - x.current; -} - -template -inline reverse_iterator -operator+(Distance n, - const reverse_iterator& x) { - return reverse_iterator - (x.current - n); -} -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ +using __STD::iterator_category; +using __STD::distance_type; +using __STD::value_type; -template -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& operator*() { return *this; } - raw_storage_iterator& operator=(const T& element) { - construct(&*iter, element); - return *this; - } - raw_storage_iterator& operator++() { - ++iter; - return *this; - } - raw_storage_iterator operator++(int) { - raw_storage_iterator 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 -inline output_iterator_tag -iterator_category(const raw_storage_iterator&) -{ - 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 istream_iterator { -friend bool operator==(const istream_iterator& x, - const istream_iterator& 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& operator++() { - read(); - return *this; - } - istream_iterator operator++(int) { - istream_iterator tmp = *this; - read(); - return tmp; - } -}; - -#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION - -template -inline input_iterator_tag -iterator_category(const istream_iterator&) { - return input_iterator_tag(); -} - -template -inline T* value_type(const istream_iterator&) { return (T*) 0; } - -template -inline Distance* distance_type(const istream_iterator&) { - return (Distance*) 0; -} - -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - -template -bool operator==(const istream_iterator& x, - const istream_iterator& y) { - return x.stream == y.stream && x.end_marker == y.end_marker || - x.end_marker == false && y.end_marker == false; -} - -template -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& operator=(const T& value) { - *stream << value; - if (string) *stream << string; - return *this; - } - ostream_iterator& operator*() { return *this; } - ostream_iterator& operator++() { return *this; } - ostream_iterator& operator++(int) { return *this; } -}; - -#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION - -template -inline output_iterator_tag -iterator_category(const ostream_iterator&) { - 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.h b/libstdc++/stl/list.h index 6d9492865e8f..4e6ee0b4113b 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 #include -#include #include +#include -template -struct __list_node { - typedef void* void_pointer; - void_pointer next; - void_pointer prev; - T data; -}; - -template -struct __list_iterator { - typedef __list_iterator iterator; - typedef __list_iterator const_iterator; - typedef __list_iterator self; - - typedef bidirectional_iterator_tag iterator_category; - typedef T value_type; - typedef Ptr pointer; - typedef Ref reference; - typedef __list_node* 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 -inline bidirectional_iterator_tag -iterator_category(const __list_iterator&) { - return bidirectional_iterator_tag(); -} - -template -inline T* -value_type(const __list_iterator&) { - return 0; -} - -template -inline ptrdiff_t* -distance_type(const __list_iterator&) { - return 0; -} - -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - -template -class list { -protected: - typedef void* void_pointer; - typedef __list_node list_node; - typedef simple_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 iterator; - typedef __list_iterator const_iterator; - -#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION - typedef reverse_iterator const_reverse_iterator; - typedef reverse_iterator reverse_iterator; -#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - typedef reverse_bidirectional_iterator - const_reverse_iterator; - typedef reverse_bidirectional_iterator - 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 - 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& 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 - 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 - 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& x) { - range_initialize(x.begin(), x.end()); - } - ~list() { - clear(); - put_node(node); - } - list& operator=(const list& 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 void remove_if(Predicate); - template void unique(BinaryPredicate); - template void merge(list&, StrictWeakOrdering); - template void sort(StrictWeakOrdering); -#endif /* __STL_MEMBER_TEMPLATES */ - - friend bool operator== (const list& x, const list& y); -}; - -template -inline bool operator==(const list& x, const list& y) { - typedef list::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 -inline bool operator<(const list& x, const list& y) { - return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); -} - -#ifdef __STL_MEMBER_TEMPLATES - -template template -void list::insert(iterator position, - InputIterator first, InputIterator last) { - for ( ; first != last; ++first) - insert(position, *first); -} - -#else /* __STL_MEMBER_TEMPLATES */ - -template -void list::insert(iterator position, const T* first, const T* last) { - for ( ; first != last; ++first) - insert(position, *first); -} - -template -void list::insert(iterator position, - const_iterator first, const_iterator last) { - for ( ; first != last; ++first) - insert(position, *first); -} - -#endif /* __STL_MEMBER_TEMPLATES */ - -template -void list::insert(iterator position, size_type n, const T& x) { - for ( ; n > 0; --n) - insert(position, x); -} - -template -void list::erase(iterator first, iterator last) { - while (first != last) erase(first++); -} - -template -void list::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 -void list::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 -list& list::operator=(const list& 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 -void list::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 -void list::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 -void list::merge(list& x) { - iterator first1 = begin(); - iterator last1 = end(); - iterator first2 = x.begin(); - iterator last2 = x.end(); - while (first1 != last1 && first2 != last2) - if (*first2 < *first1) { - iterator next = first2; - transfer(first1, first2, ++next); - first2 = next; - } - else - ++first1; - if (first2 != last2) transfer(last1, first2, last2); -} - -template -void list::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 -void list::sort() { - if (node->next == node || link_type(node->next)->next == node) return; - list carry; - list counter[64]; - int fill = 0; - while (!empty()) { - carry.splice(carry.begin(), *this, begin()); - int i = 0; - while(i < fill && !counter[i].empty()) { - counter[i].merge(carry); - 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 template -void list::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 template -void list::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 template -void list::merge(list& x, StrictWeakOrdering comp) { - iterator first1 = begin(); - iterator last1 = end(); - iterator first2 = x.begin(); - iterator last2 = x.end(); - while (first1 != last1 && first2 != last2) - if (comp(*first2, *first1)) { - iterator next = first2; - transfer(first1, first2, ++next); - first2 = next; - } - else - ++first1; - if (first2 != last2) transfer(last1, first2, last2); -} - -template template -void list::sort(StrictWeakOrdering comp) { - if (node->next == node || link_type(node->next)->next == node) return; - list carry; - list counter[64]; - int fill = 0; - while (!empty()) { - carry.splice(carry.begin(), *this, begin()); - int i = 0; - while(i < fill && !counter[i].empty()) { - counter[i].merge(carry, comp); - carry.swap(counter[i++]); - } - carry.swap(counter[i]); - if (i == fill) ++fill; - } - - for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1], comp); - swap(counter[fill-1]); -} - -#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.h b/libstdc++/stl/map.h index 5c9d6b1bf3bb..a89bd31e81cd 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 +#include -#ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , class Alloc = alloc> -#else -template -#endif -class map { -public: - -// typedefs: - - typedef Key key_type; - typedef T data_type; - typedef pair value_type; - typedef Compare key_compare; - - class value_compare - : public binary_function { - friend class map; - 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_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 - map(InputIterator first, InputIterator last) - : t(Compare()) { t.insert_unique(first, last); } - - template - 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& x) : t(x.t) {} - map& operator=(const map& 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& x) { t.swap(x.t); } - - // insert/erase - - pair 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 - 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 equal_range(const key_type& x) { - return t.equal_range(x); - } - pair 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 -inline bool operator==(const map& x, - const map& y) { - return x.t == y.t; -} - -template -inline bool operator<(const map& x, - const map& 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/multimap.h b/libstdc++/stl/multimap.h index f15880af39d9..1a8ec4af4f94 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 +#include -#ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , class Alloc = alloc> -#else -template -#endif -class multimap { -public: - -// typedefs: - - typedef Key key_type; - typedef T data_type; - typedef pair value_type; - typedef Compare key_compare; - - class value_compare : public binary_function { - friend class multimap; - 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_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 - multimap(InputIterator first, InputIterator last) - : t(Compare()) { t.insert_equal(first, last); } - - template - 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& x) : t(x.t) { } - multimap& - operator=(const multimap& 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& 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 - 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 equal_range(const key_type& x) { - return t.equal_range(x); - } - pair 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 -inline bool operator==(const multimap& x, - const multimap& y) { - return x.t == y.t; -} - -template -inline bool operator<(const multimap& x, - const multimap& 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 3df4557b18f1..3024fd74c03d 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 +#include -#ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , class Alloc = alloc> -#else -template -#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_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 - multiset(InputIterator first, InputIterator last) - : t(Compare()) { t.insert_equal(first, last); } - template - 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& x) : t(x.t) {} - multiset& - operator=(const multiset& 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& 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 - 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 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 -inline bool operator==(const multiset& x, - const multiset& y) { - return x.t == y.t; -} - -template -inline bool operator<(const multiset& x, - const multiset& 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/pair.h b/libstdc++/stl/pair.h index ca20d8baf8af..00f5caddb614 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 - -template -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 - pair(const pair& p) : first(p.first), second(p.second) {} #endif -}; +#ifndef __SGI_STL_INTERNAL_RELOPS +#include +#endif +#ifndef __SGI_STL_INTERNAL_PAIR_H +#include +#endif -template -inline bool operator==(const pair& x, const pair& y) { - return x.first == y.first && x.second == y.second; -} +#ifdef __STL_USE_NAMESPACES -template -inline bool operator<(const pair& x, const pair& y) { - return x.first < y.first || (!(y.first < x.first) && x.second < y.second); -} +using __STD::pair; +using __STD::make_pair; -template -inline pair make_pair(const T1& x, const T2& y) { - return pair(x, y); -} +#endif /* __STL_USE_NAMESPACES */ -#endif +#endif /* __SGI_STL_PAIR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++/stl/pthread_alloc.h b/libstdc++/stl/pthread_alloc.h index a2aeaa1290e9..0a2debb74bd5 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 +#ifdef __STL_USE_NAMESPACES -#include -#include -#include -#include -#include -#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 -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* 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* 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 *new_allocator(); - // Return a recycled or new allocator instance. - static __pthread_alloc_template *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* a; - - if (n > MAX_BYTES) { - return(malloc(n)); - } - if (!key_initialized || - !(a = (__pthread_alloc_template*) - 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* a; - - if (n > MAX_BYTES) { - free(p); - return; - } - if (!key_initialized || - !(a = (__pthread_alloc_template*) - 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 pthread_alloc; - - -template -void __pthread_alloc_template::destructor(void * instance) -{ - __pthread_alloc_template* a = - (__pthread_alloc_template*)instance; - a -> next = free_allocators; - free_allocators = a; -} - -template -__pthread_alloc_template* -__pthread_alloc_template::new_allocator() -{ - if (0 != free_allocators) { - __pthread_alloc_template* result = free_allocators; - free_allocators = free_allocators -> next; - return result; - } else { - return new __pthread_alloc_template; - } -} - -template -__pthread_alloc_template* -__pthread_alloc_template::get_allocator_instance() -{ - __pthread_alloc_template* 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 -char *__pthread_alloc_template -::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* a = - (__pthread_alloc_template*)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 -void *__pthread_alloc_template -::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 -void *__pthread_alloc_template -::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 -__pthread_alloc_template * -__pthread_alloc_template::free_allocators = 0; - -template -pthread_key_t __pthread_alloc_template::key; - -template -bool __pthread_alloc_template::key_initialized = false; - -template -pthread_mutex_t __pthread_alloc_template::chunk_allocator_lock -= PTHREAD_MUTEX_INITIALIZER; - -template -char *__pthread_alloc_template -::start_free = 0; - -template -char *__pthread_alloc_template -::end_free = 0; - -template -size_t __pthread_alloc_template -::heap_size = 0; - - -#endif /* __NODE_ALLOC_H */ +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++/stl/rope.h b/libstdc++/stl/rope.h index 399352f477ee..d767fa32e7a2 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 -# include -# include -# include -# include -# include -# include -# ifdef __GC -# define __GC_CONST const -# else -# define __GC_CONST // constant except for deallocation -# endif -# ifdef __STL_SGI_THREADS -# include -# endif +#include +#include -// The end-of-C-string character. -// This is what the draft standard says it should be. -template -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 -inline bool __is_basic_char_type(charT *) { return false; } -template -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 -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 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 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 -// 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 and a -// little like containers. - -template -// 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 __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 rope; -template struct __rope_RopeConcatenation; -template struct __rope_RopeLeaf; -template struct __rope_RopeFunction; -template struct __rope_RopeSubstring; -template class __rope_iterator; -template class __rope_const_iterator; -template class __rope_charT_ref_proxy; -template 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 -struct __rope_RopeBase { - typedef rope my_rope; - typedef simple_alloc DataAlloc; - typedef simple_alloc<__rope_RopeConcatenation, Alloc> CAlloc; - typedef simple_alloc<__rope_RopeLeaf, Alloc> LAlloc; - typedef simple_alloc<__rope_RopeFunction, Alloc> FAlloc; - typedef simple_alloc<__rope_RopeSubstring, 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 -struct __rope_RopeLeaf : public __rope_RopeBase { - 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 -struct __rope_RopeConcatenation : public __rope_RopeBase { - public: - __rope_RopeBase* left; - __rope_RopeBase* right; -}; - -template -struct __rope_RopeFunction : public __rope_RopeBase { - public: - char_producer* 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 -struct __rope_RopeSubstring: public __rope_RopeFunction, - public char_producer { - public: - __rope_RopeBase * 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 *fn = - ((__rope_RopeFunction *)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 *)base) -> data; - uninitialized_copy_n(s + start_pos + start, req_len, - buffer); - } - break; - default: - __stl_assert(false); - } - } - __rope_RopeSubstring(__rope_RopeBase * 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 - struct __rope_self_destruct_ptr { - __rope_RopeBase * ptr; - ~__rope_self_destruct_ptr() { __rope_RopeBase::unref(ptr); } -# ifdef __STL_USE_EXCEPTIONS - __rope_self_destruct_ptr() : ptr(0) {}; -# else - __rope_self_destruct_ptr() {}; -# endif - __rope_self_destruct_ptr(__rope_RopeBase * p) : ptr(p) {} - __rope_RopeBase & operator*() { return *ptr; } - __rope_RopeBase * operator->() { return ptr; } - operator __rope_RopeBase *() { return ptr; } - __rope_self_destruct_ptr & operator= (__rope_RopeBase * 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 __rope_charT_ref_proxy { - friend class rope; - friend class __rope_iterator; - friend class __rope_charT_ptr_proxy; -# ifdef __GC - typedef __rope_RopeBase * self_destruct_ptr; -# else - typedef __rope_self_destruct_ptr self_destruct_ptr; -# endif - typedef __rope_RopeBase RopeBase; - typedef rope 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 operator& () const; - __rope_charT_ref_proxy& operator= (const __rope_charT_ref_proxy& c) { - return operator=((charT)c); - } -}; - -template -class __rope_charT_ptr_proxy { - friend class __rope_charT_ref_proxy; - size_t pos; - charT current; - bool current_valid; - rope * root; // The whole rope. - public: - __rope_charT_ptr_proxy(const __rope_charT_ref_proxy & 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 & x, - const __rope_charT_ptr_proxy & y); - __rope_charT_ref_proxy operator *() const { - if (current_valid) { - return __rope_charT_ref_proxy(root, pos, current); - } else { - return __rope_charT_ref_proxy(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 __rope_iterator_base: - public random_access_iterator { - friend class rope; - public: - typedef __rope_RopeBase 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 __rope_iterator; - -template -class __rope_const_iterator : public __rope_iterator_base { - friend class rope; - protected: - __rope_const_iterator(const RopeBase * root, size_t pos): - __rope_iterator_base( - const_cast(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(x) { } - __rope_const_iterator(const __rope_iterator & x); - __rope_const_iterator(const rope &r, size_t pos) : - __rope_iterator_base(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(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(root, old_pos); - } - friend __rope_const_iterator operator- - (const __rope_const_iterator & x, - ptrdiff_t n); - friend __rope_const_iterator operator+ - (const __rope_const_iterator & x, - ptrdiff_t n); - friend __rope_const_iterator operator+ - (ptrdiff_t n, - const __rope_const_iterator & x); - reference operator[](size_t n) { - return rope::fetch(root, current_pos + n); - } - friend bool operator== - (const __rope_const_iterator & x, - const __rope_const_iterator & y); - friend bool operator< - (const __rope_const_iterator & x, - const __rope_const_iterator & y); - friend ptrdiff_t operator- - (const __rope_const_iterator & x, - const __rope_const_iterator & y); -}; - -template -class __rope_iterator : public __rope_iterator_base { - friend class rope; - protected: - rope * 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 * r, size_t pos): - __rope_iterator_base(r -> tree_ptr, pos), - root_rope(r) { - RopeBase::ref(root); - } - void check(); - public: - typedef __rope_charT_ref_proxy reference; - typedef __rope_charT_ref_proxy* pointer; - - public: - rope& container() { return *root_rope; } - __rope_iterator() { - root = 0; // Needed for reference counting. - }; - __rope_iterator(const __rope_iterator & x) : - __rope_iterator_base(x) { - root_rope = x.root_rope; - RopeBase::ref(root); - } - __rope_iterator(rope& 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(root_rope, current_pos); - } else { - return __rope_charT_ref_proxy(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(root_rope, old_pos); - } - __rope_iterator operator--(int) { - size_t old_pos = current_pos; - decr(1); - return __rope_iterator(root_rope, old_pos); - } - reference operator[](ptrdiff_t n) { - return __rope_charT_ref_proxy(root_rope, current_pos + n); - } - friend bool operator== - (const __rope_iterator & x, - const __rope_iterator & y); - friend bool operator< - (const __rope_iterator & x, - const __rope_iterator & y); - friend ptrdiff_t operator- - (const __rope_iterator & x, - const __rope_iterator & y); - friend __rope_iterator operator- - (const __rope_iterator & x, - ptrdiff_t n); - friend __rope_iterator operator+ - (const __rope_iterator & x, - ptrdiff_t n); - friend __rope_iterator operator+ - (ptrdiff_t n, - const __rope_iterator & x); - -}; - -template -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 iterator; - typedef __rope_const_iterator const_iterator; - typedef __rope_charT_ref_proxy reference; - typedef __rope_charT_ptr_proxy pointer; - - friend class __rope_iterator; - friend class __rope_const_iterator; - friend struct __rope_RopeBase; - friend class __rope_iterator_base; - friend class __rope_charT_ptr_proxy; - friend class __rope_charT_ref_proxy; - friend struct __rope_RopeSubstring; - - 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 DataAlloc; - typedef simple_alloc<__rope_RopeConcatenation, Alloc> CAlloc; - typedef simple_alloc<__rope_RopeLeaf, Alloc> LAlloc; - typedef simple_alloc<__rope_RopeFunction, Alloc> FAlloc; - typedef simple_alloc<__rope_RopeSubstring, 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 RopeBase; - typedef __rope_RopeConcatenation RopeConcatenation; - typedef __rope_RopeLeaf RopeLeaf; - typedef __rope_RopeFunction RopeFunction; - typedef __rope_RopeSubstring 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& 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 * self_destruct_ptr; -# else - typedef __rope_self_destruct_ptr 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& 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 *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::concat_fn; - - struct concat_fn - : binary_function, rope, - rope > { - rope operator() (const rope& x, const rope& y) { - return x + y; - } - }; - - friend rope identity_element(concat_fn) { return rope(); } - - 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 *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_reverse_iterator; -# else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - typedef reverse_iterator 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 operator+ (const rope &left, - const rope &right); - - friend rope operator+ (const rope &left, - const charT* right); - - friend rope operator+ (const rope &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 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 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( - substring(tree_ptr, start, start + len)); - } - - rope substr(iterator start, iterator end) const { - return rope( - substring(tree_ptr, start.index(), end.index())); - } - - rope substr(iterator start) const { - size_t pos = start.index(); - return rope( - 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 - (substring(tree_ptr, start.index(), end.index())); - } - - rope substr(const_iterator start) { - size_t pos = start.index(); - return rope(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 reverse_iterator; -# else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - typedef reverse_iterator 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 -inline bool operator== (const __rope_const_iterator & x, - const __rope_const_iterator & y) { - return (x.current_pos == y.current_pos && x.root == y.root); -} - -template -inline bool operator< (const __rope_const_iterator & x, - const __rope_const_iterator & y) { - return (x.current_pos < y.current_pos); -} - -template -inline ptrdiff_t operator-(const __rope_const_iterator & x, - const __rope_const_iterator & y) { - return x.current_pos - y.current_pos; -} - -template -inline __rope_const_iterator -operator-(const __rope_const_iterator & x, - ptrdiff_t n) { - return __rope_const_iterator(x.root, x.current_pos - n); -} - -template -inline __rope_const_iterator -operator+(const __rope_const_iterator & x, - ptrdiff_t n) { - return __rope_const_iterator(x.root, x.current_pos + n); -} - -template -inline __rope_const_iterator -operator+(ptrdiff_t n, - const __rope_const_iterator & x) { - return __rope_const_iterator(x.root, x.current_pos + n); -} - -template -inline bool operator== (const __rope_iterator & x, - const __rope_iterator & y) { - return (x.current_pos == y.current_pos && x.root_rope == y.root_rope); -} - -template -inline bool operator< (const __rope_iterator & x, - const __rope_iterator & y) { - return (x.current_pos < y.current_pos); -} - -template -inline ptrdiff_t operator-(const __rope_iterator & x, - const __rope_iterator & y) { - return x.current_pos - y.current_pos; -} - -template -inline __rope_iterator -operator-(const __rope_iterator & x, - ptrdiff_t n) { - return __rope_iterator(x.root_rope, x.current_pos - n); -} - -template -inline __rope_iterator -operator+(const __rope_iterator & x, - ptrdiff_t n) { - return __rope_iterator(x.root_rope, x.current_pos + n); -} - -template -inline __rope_iterator -operator+(ptrdiff_t n, - const __rope_iterator & x) { - return __rope_iterator(x.root_rope, x.current_pos + n); -} - -template -inline -rope -operator+ (const rope &left, - const rope &right) -{ - return rope - (rope::concat(left.tree_ptr, right.tree_ptr)); - // Inlining this should make it possible to keep left and - // right in registers. -} - -template -inline -rope& -operator+= (rope &left, - const rope &right) -{ - left.append(right); - return left; -} - -template -inline -rope -operator+ (const rope &left, - const charT* right) { - size_t rlen = rope::char_ptr_len(right); - return rope - (rope::concat_char_iter(left.tree_ptr, right, rlen)); -} - -template -inline -rope& -operator+= (rope &left, - const charT* right) { - left.append(right); - return left; -} - -template -inline -rope -operator+ (const rope &left, charT right) { - return rope - (rope::concat_char_iter(left.tree_ptr, &right, 1)); -} - -template -inline -rope& -operator+= (rope &left, charT right) { - left.append(right); - return left; -} - -template -bool -operator< (const rope &left, const rope &right) { - return left.compare(right) < 0; -} - -template -bool -operator== (const rope &left, const rope &right) { - return left.compare(right) == 0; -} - -template -inline bool operator== (const __rope_charT_ptr_proxy & x, - const __rope_charT_ptr_proxy & y) { - return (x.pos == y.pos && x.root == y.root); -} - -template -ostream& operator<< (ostream& o, const rope& r); - -typedef rope crope; -typedef rope 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 -{ - 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 -{ - 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 -# endif /* _ROPE_H */ +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++/stl/ropeimpl.h b/libstdc++/stl/ropeimpl.h index d1c1ed4e6893..dcd6bfd51176 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 # include +__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::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::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::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::RopeBase * rope::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::RopeBase * rope::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::RopeBase * rope } 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::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::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::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& 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& 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::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::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::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::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::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 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.h b/libstdc++/stl/set.h index 6a79a625653f..9004d2e04770 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 +#include -#ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , class Alloc = alloc> -#else -template -#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_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 - set(InputIterator first, InputIterator last) - : t(Compare()) { t.insert_unique(first, last); } - - template - 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& x) : t(x.t) {} - set& operator=(const set& 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& x) { t.swap(x.t); } - - // insert/erase - typedef pair pair_iterator_bool; - pair insert(const value_type& x) { - pair p = t.insert_unique(x); - return pair(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 - 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 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 -inline bool operator==(const set& x, - const set& y) { - return x.t == y.t; -} - -template -inline bool operator<(const set& x, - const set& 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.h b/libstdc++/stl/slist.h index 9ae6e117f0df..d2377b0cf5ae 100644 --- a/libstdc++/stl/slist.h +++ b/libstdc++/stl/slist.h @@ -17,720 +17,14 @@ #include #include +#include -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 -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 -struct __slist_iterator : public __slist_iterator_base -{ - typedef __slist_iterator iterator; - typedef __slist_iterator const_iterator; - typedef __slist_iterator self; - - typedef T value_type; - typedef Ptr pointer; - typedef Ref reference; - typedef __slist_node 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 -inline T* -value_type(const __slist_iterator&) { - 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 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 iterator; - typedef __slist_iterator const_iterator; - -private: - typedef __slist_node list_node; - typedef __slist_node_base list_node_base; - typedef __slist_iterator_base iterator_base; - typedef simple_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 - 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 - 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& L1, const slist& 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 - 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 - 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 - 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 void remove_if(Predicate pred); - template void unique(BinaryPredicate pred); - template void merge(slist&, StrictWeakOrdering); - template void sort(StrictWeakOrdering comp); -#endif /* __STL_MEMBER_TEMPLATES */ -}; - -template -slist& slist::operator=(const slist& 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 -bool operator==(const slist& L1, const slist& L2) -{ - typedef typename slist::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 -inline bool operator<(const slist& L1, const slist& L2) -{ - return lexicographical_compare(L1.begin(), L1.end(), L2.begin(), L2.end()); -} - -template -void slist::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 -void slist::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 -void slist::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 -void slist::merge(slist& 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 -void slist::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 -template void slist::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 template -void slist::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 template -void slist::merge(slist& 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 template -void slist::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.h b/libstdc++/stl/stack.h index cc025bb70e18..89beca82f128 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 -#include #include #include +#include +#include +#include -#ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template > -#else -template -#endif -class stack { - friend bool operator==(const stack& x, - const stack& y); - friend bool operator<(const stack& x, - const stack& 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 -bool operator==(const stack& x, const stack& y) { - return x.c == y.c; -} - -template -bool operator<(const stack& x, const stack& y) { - return x.c < y.c; -} - -#ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template > -#else -template -#endif -class queue { -friend bool operator==(const queue& x, const queue& y); -friend bool operator<(const queue& x, const queue& 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 -bool operator==(const queue& x, const queue& y) { - return x.c == y.c; -} - -template -bool operator<(const queue& x, const queue& y) { - return x.c < y.c; -} - -#ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , - class Compare = less > -#else -template -#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 - priority_queue(InputIterator first, InputIterator last, const Compare& x) - : c(first, last), comp(x) { make_heap(c.begin(), c.end(), comp); } - template - 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_config.h b/libstdc++/stl/stl_config.h index 31e96cf7cd30..c6546667a93f 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/tempbuf.h b/libstdc++/stl/tempbuf.h index 18d995252d8a..8799393f39f1 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 +#endif #include #include #include -#include +#ifndef __TYPE_TRAITS_H #include +#endif +#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H +#include +#endif +#ifndef __SGI_STL_INTERNAL_TEMPBUF_H +#include +#endif -template -pair 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(tmp, len); - len /= 2; - } - - return pair((T*)0, 0); -} - -template -void return_temporary_buffer(T* p) { - free(p); -} - -template ::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::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 80e0cafa352b..77c57cbbba1f 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 +#ifndef __SGI_STL_INTERNAL_TREE_H +#include +#endif #include -#include #include - -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 -struct __rb_tree_node : public __rb_tree_node_base -{ - typedef __rb_tree_node* 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 -struct __rb_tree_iterator : public __rb_tree_base_iterator -{ - typedef Value value_type; - typedef Value& reference; - typedef Value* pointer; - typedef __rb_tree_iterator iterator; - typedef __rb_tree_iterator const_iterator; - typedef __rb_tree_iterator self; - typedef __rb_tree_node* 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 -inline Value* value_type(const __rb_tree_iterator&) { - 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 rb_tree { -protected: - typedef void* void_pointer; - typedef __rb_tree_node_base* base_ptr; - typedef __rb_tree_node rb_tree_node; - typedef simple_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 iterator; - typedef __rb_tree_iterator - const_iterator; - -#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION - typedef reverse_iterator const_reverse_iterator; - typedef reverse_iterator reverse_iterator; -#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - typedef reverse_bidirectional_iterator - reverse_iterator; - typedef reverse_bidirectional_iterator - 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& 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& - operator=(const rb_tree& 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& t) { - ::swap(header, t.header); - ::swap(node_count, t.node_count); - ::swap(key_compare, t.key_compare); - } - -public: - // insert/erase - pair 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 - void insert_unique(InputIterator first, InputIterator last); - template - 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 equal_range(const key_type& x); - pair equal_range(const key_type& x) const; - -public: - // Debugging. - bool __rb_verify() const; -}; - -template -inline bool operator==(const rb_tree& x, - const rb_tree& y) { - return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); -} - -template -inline bool operator<(const rb_tree& x, - const rb_tree& y) { - return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); -} - -template -rb_tree& -rb_tree:: -operator=(const rb_tree& 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 -rb_tree::iterator -rb_tree:: -__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 -rb_tree::iterator -rb_tree::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 -pair::iterator, bool> -rb_tree::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(__insert(x, y, v), true); - else - --j; - if (key_compare(key(j.node), KeyOfValue()(v))) - return pair(__insert(x, y, v), true); - return pair(j, false); -} - - -template -rb_tree::iterator -rb_tree::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 -rb_tree::iterator -rb_tree::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 template -void rb_tree::insert_equal(II first, II last) { - for ( ; first != last; ++first) - insert_equal(*first); -} - -template template -void rb_tree::insert_unique(II first, II last) { - for ( ; first != last; ++first) - insert_unique(*first); -} - -#else /* __STL_MEMBER_TEMPLATES */ - -template -void -rb_tree::insert_equal(const V* first, const V* last) { - for ( ; first != last; ++first) - insert_equal(*first); -} - -template -void -rb_tree::insert_equal(const_iterator first, - const_iterator last) { - for ( ; first != last; ++first) - insert_equal(*first); -} - -template -void -rb_tree::insert_unique(const V* first, const V* last) { - for ( ; first != last; ++first) - insert_unique(*first); -} - -template -void -rb_tree::insert_unique(const_iterator first, - const_iterator last) { - for ( ; first != last; ++first) - insert_unique(*first); -} - -#endif /* __STL_MEMBER_TEMPLATES */ - -template -inline void -rb_tree::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 -rb_tree::size_type -rb_tree::erase(const Key& x) { - pair p = equal_range(x); - size_type n = 0; - distance(p.first, p.second, n); - erase(p.first, p.second); - return n; -} - -template -rb_tree::link_type -rb_tree::__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 -void rb_tree::__erase(link_type x) { - // erase without rebalancing - while (x != 0) { - __erase(right(x)); - link_type y = left(x); - destroy_node(x); - x = y; - } -} - -template -void rb_tree::erase(iterator first, - iterator last) { - if (first == begin() && last == end()) - clear(); - else - while (first != last) erase(first++); -} - -template -void rb_tree::erase(const Key* first, - const Key* last) { - while (first != last) erase(*first++); -} - -template -rb_tree::iterator -rb_tree::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 -rb_tree::const_iterator -rb_tree::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 -rb_tree::size_type -rb_tree::count(const Key& k) const { - pair p = equal_range(k); - size_type n = 0; - distance(p.first, p.second, n); - return n; -} - -template -rb_tree::iterator -rb_tree::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 -rb_tree::const_iterator -rb_tree::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 -rb_tree::iterator -rb_tree::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 -rb_tree::const_iterator -rb_tree::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 -inline pair::iterator, - rb_tree::iterator> -rb_tree::equal_range(const Key& k) { - return pair(lower_bound(k), upper_bound(k)); -} - -template -inline pair::const_iterator, - rb_tree::const_iterator> -rb_tree::equal_range(const Key& k) const { - return pair(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 -bool -rb_tree::__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 6ca0137709dc..a7b977cc06b9 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 +#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 { +__STL_TEMPLATE_NULL struct __type_traits { 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 { typedef __true_type is_POD_type; }; -struct __type_traits { +__STL_TEMPLATE_NULL struct __type_traits { 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 { typedef __true_type is_POD_type; }; -struct __type_traits { +__STL_TEMPLATE_NULL struct __type_traits { 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 { typedef __true_type is_POD_type; }; -struct __type_traits { +__STL_TEMPLATE_NULL struct __type_traits { 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 { typedef __true_type is_POD_type; }; -struct __type_traits { +__STL_TEMPLATE_NULL struct __type_traits { 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 { typedef __true_type is_POD_type; }; -struct __type_traits { +__STL_TEMPLATE_NULL struct __type_traits { 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 { typedef __true_type is_POD_type; }; -struct __type_traits { +__STL_TEMPLATE_NULL struct __type_traits { 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 { typedef __true_type is_POD_type; }; -struct __type_traits { +__STL_TEMPLATE_NULL struct __type_traits { 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 { typedef __true_type is_POD_type; }; -struct __type_traits { +__STL_TEMPLATE_NULL struct __type_traits { 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 { typedef __true_type is_POD_type; }; -struct __type_traits { +__STL_TEMPLATE_NULL struct __type_traits { 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 { typedef __true_type is_POD_type; }; -struct __type_traits { +__STL_TEMPLATE_NULL struct __type_traits { 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 { typedef __true_type is_POD_type; }; -struct __type_traits { +__STL_TEMPLATE_NULL struct __type_traits { 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 { #endif /* __TYPE_TRAITS_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++/stl/vector.h b/libstdc++/stl/vector.h index 1c7867e8b030..231a227b7e3a 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 #include #include +#include -template -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_reverse_iterator; - typedef reverse_iterator reverse_iterator; -#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - typedef reverse_iterator const_reverse_iterator; - typedef reverse_iterator - reverse_iterator; -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -protected: - typedef simple_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& 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 - 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& operator=(const vector& 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& 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 - 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 - 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 - 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 - 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 - void range_insert(iterator pos, - InputIterator first, InputIterator last, - input_iterator_tag); - - template - void range_insert(iterator pos, - ForwardIterator first, ForwardIterator last, - forward_iterator_tag); - -#endif /* __STL_MEMBER_TEMPLATES */ -}; - -template -inline bool operator==(const vector& x, const vector& y) { - return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); -} - -template -inline bool operator<(const vector& x, const vector& y) { - return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); -} - - - -template -vector& vector::operator=(const vector& 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 -void vector::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 -void vector::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 template -void vector::range_insert(iterator pos, - InputIterator first, InputIterator last, - input_iterator_tag) { - for ( ; first != last; ++first) { - pos = insert(pos, *first); - ++pos; - } -} - -template template -void vector::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 -void vector::insert(iterator position, - const_iterator first, - const_iterator last) { - if (first != last) { - size_type n = 0; - distance(first, last, n); - if (size_type(end_of_storage - finish) >= n) { - const size_type elems_after = finish - position; - iterator old_finish = finish; - if (elems_after > n) { - uninitialized_copy(finish - n, finish, finish); - finish += n; - copy_backward(position, old_finish - n, old_finish); - copy(first, last, position); - } - else { - uninitialized_copy(first + elems_after, last, finish); - finish += n - elems_after; - uninitialized_copy(position, old_finish, finish); - finish += elems_after; - copy(first, first + elems_after, position); - } - } - else { - const size_type old_size = size(); - const size_type len = old_size + max(old_size, n); - iterator new_start = data_allocator::allocate(len); - iterator new_finish = new_start; -# ifdef __STL_USE_EXCEPTIONS - try { -# endif /* __STL_USE_EXCEPTIONS */ - new_finish = uninitialized_copy(start, position, new_start); - new_finish = uninitialized_copy(first, last, new_finish); - new_finish = uninitialized_copy(position, finish, new_finish); -# ifdef __STL_USE_EXCEPTIONS - } - catch(...) { - destroy(new_start, new_finish); - data_allocator::deallocate(new_start, len); - throw; - } -# endif /* __STL_USE_EXCEPTIONS */ - destroy(start, finish); - deallocate(); - start = new_start; - finish = new_finish; - end_of_storage = new_start + len; - } - } -} - -#endif /* __STL_MEMBER_TEMPLATES */ +#ifdef __STL_USE_NAMESPACES +using __STD::vector; +#endif /* __STL_USE_NAMESPACES */ #endif /* __SGI_STL_VECTOR_H */ + +// Local Variables: +// mode:C++ +// End: diff --git a/libstdc++/utility b/libstdc++/utility deleted file mode 100644 index fb79aa782746..000000000000 --- a/libstdc++/utility +++ /dev/null @@ -1,8 +0,0 @@ -// -*- C++ -*- forwarding header. -// This file is part of the GNU ANSI C++ Library. - -#ifndef __UTILITY__ -#define __UTILITY__ -#include -#include -#endif diff --git a/libstdc++/vector b/libstdc++/vector deleted file mode 100644 index 79f735937517..000000000000 --- a/libstdc++/vector +++ /dev/null @@ -1,7 +0,0 @@ -// -*- C++ -*- forwarding header. -// This file is part of the GNU ANSI C++ Library. - -#ifndef __VECTOR__ -#define __VECTOR__ -#include -#endif