update to 10/27 STL snapshot

From-SVN: r16311
This commit is contained in:
Jason Merrill
1997-11-04 20:14:50 +00:00
committed by Jason Merrill
parent 9c82d0d1fd
commit ff5b5c164a
44 changed files with 727 additions and 15462 deletions

View File

@@ -3,10 +3,16 @@ Sun Nov 2 23:34:09 1997 Manfred Hollstein <manfred@s-direktnet.de>
* configure.in: Use delta.mt for m68k-motorola-sysv.
* config/delta.mt: New makefile fragment.
Sun Nov 2 12:14:37 1997 Jason Merrill <jason@yorick.cygnus.com>
* Makefile.in (install): Some of HEADERS come from the stl dir now.
* algorithm, deque, functional, iterator, list, map, memory, numeric,
queue, set, stack, utility, vector: Now in stl dir.
Fri Oct 10 00:40:00 1997 Jason Merrill <jason@yorick.cygnus.com>
* std/bastring.h: Use ibegin internally. Return passed iterator
instead of recalculating it were appropriate.
instead of recalculating it where appropriate.
* std/bastring.cc: Adjust for erase.
From Yotam Medini:

View File

@@ -248,7 +248,16 @@ install:
rootme=`pwd`/ ; export rootme ; \
if [ -z "$(MULTISUBDIR)" ]; then \
cd $(srcdir); \
for FILE in $(HEADERS) *.h std/*.*; do \
for FILE in $(HEADERS); do \
rm -f $(gxx_includedir)/$$FILE ; \
if [ -f stl/$$FILE ]; then \
$(INSTALL_DATA) stl/$$FILE $(gxx_includedir)/$$FILE ; \
else \
$(INSTALL_DATA) $$FILE $(gxx_includedir)/$$FILE ; \
fi ; \
chmod a-x $(gxx_includedir)/$$FILE ; \
done ; \
for FILE in *.h std/*.*; do \
rm -f $(gxx_includedir)/$$FILE ; \
$(INSTALL_DATA) $$FILE $(gxx_includedir)/$$FILE ; \
chmod a-x $(gxx_includedir)/$$FILE ; \

View File

@@ -1,7 +0,0 @@
// -*- C++ -*- forwarding header.
// This file is part of the GNU ANSI C++ Library.
#ifndef __ALGORITHM__
#define __ALGORITHM__
#include <algo.h>
#endif

View File

@@ -1,7 +0,0 @@
// -*- C++ -*- forwarding header.
// This file is part of the GNU ANSI C++ Library.
#ifndef __DEQUE__
#define __DEQUE__
#include <deque.h>
#endif

View File

@@ -1,7 +0,0 @@
// -*- C++ -*- forwarding header.
// This file is part of the GNU ANSI C++ Library.
#ifndef __FUNCTIONAL__
#define __FUNCTIONAL__
#include <function.h>
#endif

View File

@@ -1,7 +0,0 @@
// -*- C++ -*- forwarding header.
// This file is part of the GNU ANSI C++ Library.
#ifndef __ITERATOR__
#define __ITERATOR__
#include <iterator.h>
#endif

View File

@@ -1,7 +0,0 @@
// -*- C++ -*- forwarding header.
// This file is part of the GNU ANSI C++ Library.
#ifndef __LIST__
#define __LIST__
#include <list.h>
#endif

View File

@@ -1,7 +0,0 @@
// -*- C++ -*- forwarding header.
// This file is part of the GNU ANSI C++ Library.
#ifndef __MAP__
#define __MAP__
#include <map.h>
#endif

View File

@@ -1,7 +0,0 @@
// -*- C++ -*- forwarding header.
// This file is part of the GNU ANSI C++ Library.
#ifndef __MEMORY__
#define __MEMORY__
#include <defalloc.h>
#endif

View File

@@ -1,7 +0,0 @@
// -*- C++ -*- forwarding header.
// This file is part of the GNU ANSI C++ Library.
#ifndef __NUMERIC__
#define __NUMERIC__
#include <algo.h>
#endif

View File

@@ -1,7 +0,0 @@
// -*- C++ -*- forwarding header.
// This file is part of the GNU ANSI C++ Library.
#ifndef __QUEUE__
#define __QUEUE__
#include <stack.h>
#endif

View File

@@ -1,7 +0,0 @@
// -*- C++ -*- forwarding header.
// This file is part of the GNU ANSI C++ Library.
#ifndef __SET__
#define __SET__
#include <set.h>
#endif

View File

@@ -1,7 +0,0 @@
// -*- C++ -*- forwarding header.
// This file is part of the GNU ANSI C++ Library.
#ifndef __STACK__
#define __STACK__
#include <stack.h>
#endif

View File

@@ -1,3 +1,21 @@
Sun Nov 2 12:14:56 1997 Jason Merrill <jason@yorick.cygnus.com>
* algo.h, algobase.h, alloc.h, bvector.h, defalloc.h, deque.h,
function.h, hash_map.h, hash_set.h, hashtable.h, heap.h, iterator.h,
list.h, map.h, multimap.h, multiset.h, pair.h, pthread_alloc.h,
rope.h, ropeimpl.h, set.h, slist.h, stack.h, stl_config.h, tempbuf.h,
tree.h, type_traits.h, vector.h: Update to October 27 SGI snapshot.
* algorithm, deque, functional, hash_map, hash_set, iterator, list,
map, memory, numeric, pthread_alloc, queue, rope, set, slist, stack,
stl_algo.h, stl_algobase.h, stl_alloc.h, stl_bvector.h,
stl_construct.h, stl_deque.h, stl_function.h, stl_hash_fun.h,
stl_hash_map.h, stl_hash_set.h, stl_hashtable.h, stl_heap.h,
stl_iterator.h, stl_list.h, stl_map.h, stl_multimap.h, stl_multiset.h,
stl_numeric.h, stl_pair.h, stl_queue.h, stl_raw_storage_iter.h,
stl_relops.h, stl_rope.h, stl_set.h, stl_slist.h, stl_stack.h,
stl_tempbuf.h, stl_tree.h, stl_uninitialized.h, stl_vector.h,
utility, vector: New files in October 27 SGI snapshot.
Fri Oct 17 19:07:42 1997 Jason Merrill <jason@yorick.cygnus.com>
* tree.h, vector.h: Fix accidental divergence from SGI release.

File diff suppressed because it is too large Load Diff

View File

@@ -11,8 +11,7 @@
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
@@ -24,743 +23,49 @@
* purpose. It is provided "as is" without express or implied warranty.
*/
#ifndef _SGI_STL_ALGOBASE_H
#define _SGI_STL_ALGOBASE_H
#ifndef __SGI_STL_ALGOBASE_H
#define __SGI_STL_ALGOBASE_H
#include <string.h>
#include <limits.h>
#include <function.h>
#ifndef __SGI_STL_PAIR_H
#include <pair.h>
#endif
#ifndef __SGI_STL_ITERATOR_H
#include <iterator.h>
#include <new.h>
#include <type_traits.h>
template <class ForwardIterator1, class ForwardIterator2, class T>
inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, T*) {
T tmp = *a;
*a = *b;
*b = tmp;
}
template <class ForwardIterator1, class ForwardIterator2>
inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) {
__iter_swap(a, b, value_type(a));
}
template <class T>
inline void swap(T& a, T& b) {
T tmp = a;
a = b;
b = tmp;
}
#ifdef __BORLANDC__
#include <stdlib.h>
#else
template <class T>
inline const T& min(const T& a, const T& b) {
return b < a ? b : a;
}
template <class T>
inline const T& max(const T& a, const T& b) {
return a < b ? b : a;
}
#endif
#ifndef __SGI_STL_INTERNAL_ALGOBASE_H
#include <stl_algobase.h>
#endif
#ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H
#include <stl_uninitialized.h>
#endif
template <class T, class Compare>
inline const T& min(const T& a, const T& b, Compare comp) {
return comp(b, a) ? b : a;
}
template <class T, class Compare>
inline const T& max(const T& a, const T& b, Compare comp) {
return comp(a, b) ? b : a;
}
template <class InputIterator, class Distance>
inline void __distance(InputIterator first, InputIterator last, Distance& n,
input_iterator_tag) {
while (first != last) { ++first; ++n; }
}
template <class RandomAccessIterator, class Distance>
inline void __distance(RandomAccessIterator first, RandomAccessIterator last,
Distance& n, random_access_iterator_tag) {
n += last - first;
}
template <class InputIterator, class Distance>
inline void distance(InputIterator first, InputIterator last, Distance& n) {
__distance(first, last, n, iterator_category(first));
}
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
template <class InputIterator>
inline iterator_traits<InputIterator>::difference_type
__distance(InputIterator first, InputIterator last, input_iterator_tag) {
iterator_traits<InputIterator>::difference_type n = 0;
while (first != last) {
++first; ++n;
}
return n;
}
template <class RandomAccessIterator>
inline iterator_traits<RandomAccessIterator>::difference_type
__distance(RandomAccessIterator first, RandomAccessIterator last,
random_access_iterator_tag) {
return last - first;
}
template <class InputIterator>
inline iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last) {
return __distance(first, last,
iterator_traits<InputIterator>::iterator_category());
}
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
template <class InputIterator, class Distance>
inline void __advance(InputIterator& i, Distance n, input_iterator_tag) {
while (n--) ++i;
}
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma set woff 1183
#endif
template <class BidirectionalIterator, class Distance>
inline void __advance(BidirectionalIterator& i, Distance n,
bidirectional_iterator_tag) {
if (n >= 0)
while (n--) ++i;
else
while (n++) --i;
}
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma reset woff 1183
#endif
template <class RandomAccessIterator, class Distance>
inline void __advance(RandomAccessIterator& i, Distance n,
random_access_iterator_tag) {
i += n;
}
template <class InputIterator, class Distance>
inline void advance(InputIterator& i, Distance n) {
__advance(i, n, iterator_category(i));
}
template <class InputIterator, class OutputIterator>
inline OutputIterator __copy(InputIterator first, InputIterator last,
OutputIterator result, input_iterator_tag)
{
for ( ; first != last; ++result, ++first)
*result = *first;
return result;
}
template <class RandomAccessIterator, class OutputIterator, class Distance>
inline OutputIterator
__copy_d(RandomAccessIterator first, RandomAccessIterator last,
OutputIterator result, Distance*)
{
for (Distance n = last - first; n > 0; --n, ++result, ++first)
*result = *first;
return result;
}
template <class RandomAccessIterator, class OutputIterator>
inline OutputIterator
__copy(RandomAccessIterator first, RandomAccessIterator last,
OutputIterator result, random_access_iterator_tag)
{
return __copy_d(first, last, result, distance_type(first));
}
template <class InputIterator, class OutputIterator>
struct __copy_dispatch
{
OutputIterator operator()(InputIterator first, InputIterator last,
OutputIterator result) {
return __copy(first, last, result, iterator_category(first));
}
};
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
template <class T>
inline T* __copy_t(const T* first, const T* last, T* result, __true_type) {
memmove(result, first, sizeof(T) * (last - first));
return result + (last - first);
}
template <class T>
inline T* __copy_t(const T* first, const T* last, T* result, __false_type) {
return __copy_d(first, last, result, (ptrdiff_t*) 0);
}
template <class T>
struct __copy_dispatch<T*, T*>
{
T* operator()(T* first, T* last, T* result) {
return __copy_t(first, last, result,
__type_traits<T>::has_trivial_assignment_operator());
}
};
template <class T>
struct __copy_dispatch<const T*, T*>
{
T* operator()(const T* first, const T* last, T* result) {
return __copy_t(first, last, result,
__type_traits<T>::has_trivial_assignment_operator());
}
};
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
template <class InputIterator, class OutputIterator>
inline OutputIterator copy(InputIterator first, InputIterator last,
OutputIterator result)
{
return __copy_dispatch<InputIterator,OutputIterator>()(first, last, result);
}
inline char* copy(const char* first, const char* last, char* result) {
memmove(result, first, last - first);
return result + (last - first);
}
inline wchar_t* copy(const wchar_t* first, const wchar_t* last,
wchar_t* result) {
memmove(result, first, sizeof(wchar_t) * (last - first));
return result + (last - first);
}
template <class BidirectionalIterator1, class BidirectionalIterator2>
inline BidirectionalIterator2 __copy_backward(BidirectionalIterator1 first,
BidirectionalIterator1 last,
BidirectionalIterator2 result) {
while (first != last) *--result = *--last;
return result;
}
template <class BidirectionalIterator1, class BidirectionalIterator2>
struct __copy_backward_dispatch
{
BidirectionalIterator2 operator()(BidirectionalIterator1 first,
BidirectionalIterator1 last,
BidirectionalIterator2 result) {
return __copy_backward(first, last, result);
}
};
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
template <class T>
inline T* __copy_backward_t(const T* first, const T* last, T* result,
__true_type) {
const ptrdiff_t N = last - first;
memmove(result - N, first, sizeof(T) * N);
return result - N;
}
template <class T>
inline T* __copy_backward_t(const T* first, const T* last, T* result,
__false_type) {
return __copy_backward(first, last, result);
}
template <class T>
struct __copy_backward_dispatch<T*, T*>
{
T* operator()(T* first, T* last, T* result) {
return
__copy_backward_t(first, last, result,
__type_traits<T>::has_trivial_assignment_operator());
}
};
template <class T>
struct __copy_backward_dispatch<const T*, T*>
{
T* operator()(const T* first, const T* last, T* result) {
return
__copy_backward_t(first, last, result,
__type_traits<T>::has_trivial_assignment_operator());
}
};
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
template <class BidirectionalIterator1, class BidirectionalIterator2>
inline BidirectionalIterator2 copy_backward(BidirectionalIterator1 first,
BidirectionalIterator1 last,
BidirectionalIterator2 result) {
return __copy_backward_dispatch<BidirectionalIterator1,
BidirectionalIterator2>()(first, last,
result);
}
template <class InputIterator, class Size, class OutputIterator>
OutputIterator __copy_n(InputIterator first, Size count,
OutputIterator result,
input_iterator_tag) {
for ( ; count > 0; --count, ++first, ++result)
*result = *first;
return result;
}
template <class RandomAccessIterator, class Size, class OutputIterator>
inline OutputIterator __copy_n(RandomAccessIterator first, Size count,
OutputIterator result,
random_access_iterator_tag) {
return copy(first, first + count, result);
}
template <class InputIterator, class Size, class OutputIterator>
inline OutputIterator copy_n(InputIterator first, Size count,
OutputIterator result) {
return __copy_n(first, count, result, iterator_category(first));
}
template <class ForwardIterator, class T>
void fill(ForwardIterator first, ForwardIterator last, const T& value) {
for ( ; first != last; ++first)
*first = value;
}
template <class OutputIterator, class Size, class T>
OutputIterator fill_n(OutputIterator first, Size n, const T& value) {
for ( ; n > 0; --n, ++first)
*first = value;
return first;
}
template <class InputIterator1, class InputIterator2>
pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2) {
while (first1 != last1 && *first1 == *first2) {
++first1;
++first2;
}
return pair<InputIterator1, InputIterator2>(first1, first2);
}
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2,
BinaryPredicate binary_pred) {
while (first1 != last1 && binary_pred(*first1, *first2)) {
++first1;
++first2;
}
return pair<InputIterator1, InputIterator2>(first1, first2);
}
template <class InputIterator1, class InputIterator2>
inline bool equal(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2) {
for ( ; first1 != last1; ++first1, ++first2)
if (*first1 != *first2)
return false;
return true;
}
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
inline bool equal(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, BinaryPredicate binary_pred) {
for ( ; first1 != last1; ++first1, ++first2)
if (!binary_pred(*first1, *first2))
return false;
return true;
}
template <class InputIterator1, class InputIterator2>
bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2) {
for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) {
if (*first1 < *first2)
return true;
if (*first2 < *first1)
return false;
}
return first1 == last1 && first2 != last2;
}
template <class InputIterator1, class InputIterator2, class Compare>
bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
Compare comp) {
for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) {
if (comp(*first1, *first2))
return true;
if (comp(*first2, *first1))
return false;
}
return first1 == last1 && first2 != last2;
}
inline bool
lexicographical_compare(const unsigned char* first1,
const unsigned char* last1,
const unsigned char* first2,
const unsigned char* last2)
{
const size_t len1 = last1 - first1;
const size_t len2 = last2 - first2;
const int result = memcmp(first1, first2, min(len1, len2));
return result != 0 ? result < 0 : len1 < len2;
}
inline bool lexicographical_compare(const char* first1, const char* last1,
const char* first2, const char* last2)
{
#if CHAR_MAX == SCHAR_MAX
return lexicographical_compare((const signed char*) first1,
(const signed char*) last1,
(const signed char*) first2,
(const signed char*) last2);
#else
return lexicographical_compare((const unsigned char*) first1,
(const unsigned char*) last1,
(const unsigned char*) first2,
(const unsigned char*) last2);
#endif
}
template <class InputIterator1, class InputIterator2>
int lexicographical_compare_3way(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2)
{
while (first1 != last1 && first2 != last2) {
if (*first1 < *first2) return -1;
if (*first2 < *first1) return 1;
++first1; ++first2;
}
if (first2 == last2) {
return !(first1 == last1);
} else {
return -1;
}
}
inline int
lexicographical_compare_3way(const unsigned char* first1,
const unsigned char* last1,
const unsigned char* first2,
const unsigned char* last2)
{
const int len1 = last1 - first1;
const int len2 = last2 - first2;
const int result = memcmp(first1, first2, min(len1, len2));
return result == 0 ? len1 - len2 : result;
}
inline int lexicographical_compare_3way(const char* first1, const char* last1,
const char* first2, const char* last2)
{
#if CHAR_MAX == SCHAR_MAX
return lexicographical_compare_3way(
(const signed char*) first1,
(const signed char*) last1,
(const signed char*) first2,
(const signed char*) last2);
#else
return lexicographical_compare_3way((const unsigned char*) first1,
(const unsigned char*) last1,
(const unsigned char*) first2,
(const unsigned char*) last2);
#endif
}
template <class T>
inline void destroy(T* pointer) {
pointer->~T();
}
template <class T1, class T2>
inline void construct(T1* p, const T2& value) {
new (p) T1(value);
}
template <class ForwardIterator>
inline void
__destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) {
for ( ; first < last; ++first)
destroy(&*first);
}
template <class ForwardIterator>
inline void __destroy_aux(ForwardIterator, ForwardIterator, __true_type) {
}
template <class ForwardIterator, class T>
inline void __destroy(ForwardIterator first, ForwardIterator last, T*) {
__destroy_aux(first, last, __type_traits<T>::has_trivial_destructor());
}
template <class ForwardIterator>
inline void destroy(ForwardIterator first, ForwardIterator last) {
__destroy(first, last, value_type(first));
}
inline void destroy(char*, char*) {}
inline void destroy(wchar_t*, wchar_t*) {}
// Valid if copy construction is equivalent to assignment, and if the
// destructor is trivial.
template <class InputIterator, class ForwardIterator>
inline ForwardIterator
__uninitialized_copy_aux(InputIterator first, InputIterator last,
ForwardIterator result,
__true_type) {
return copy(first, last, result);
}
template <class InputIterator, class ForwardIterator>
ForwardIterator
__uninitialized_copy_aux(InputIterator first, InputIterator last,
ForwardIterator result,
__false_type) {
ForwardIterator cur = result;
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
for ( ; first != last; ++first, ++cur)
construct(&*cur, *first);
return cur;
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
destroy(result, cur);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
template <class InputIterator, class ForwardIterator, class T>
inline ForwardIterator
__uninitialized_copy(InputIterator first, InputIterator last,
ForwardIterator result, T*) {
return __uninitialized_copy_aux(first, last, result,
__type_traits<T>::is_POD_type());
}
template <class InputIterator, class ForwardIterator>
inline ForwardIterator
uninitialized_copy(InputIterator first, InputIterator last,
ForwardIterator result) {
return __uninitialized_copy(first, last, result, value_type(result));
}
inline char* uninitialized_copy(const char* first, const char* last,
char* result) {
memmove(result, first, last - first);
return result + (last - first);
}
inline wchar_t* uninitialized_copy(const wchar_t* first, const wchar_t* last,
wchar_t* result) {
memmove(result, first, sizeof(wchar_t) * (last - first));
return result + (last - first);
}
template <class InputIterator, class Size, class ForwardIterator>
ForwardIterator __uninitialized_copy_n(InputIterator first, Size count,
ForwardIterator result,
input_iterator_tag) {
ForwardIterator cur = result;
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
for ( ; count > 0 ; --count, ++first, ++cur)
construct(&*cur, *first);
return cur;
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
destroy(result, cur);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
template <class RandomAccessIterator, class Size, class ForwardIterator>
inline ForwardIterator
__uninitialized_copy_n(RandomAccessIterator first, Size count,
ForwardIterator result,
random_access_iterator_tag) {
return uninitialized_copy(first, first + count, result);
}
template <class InputIterator, class Size, class ForwardIterator>
inline ForwardIterator uninitialized_copy_n(InputIterator first, Size count,
ForwardIterator result) {
return __uninitialized_copy_n(first, count, result,
iterator_category(first));
}
// Valid if copy construction is equivalent to assignment, and if the
// destructor is trivial.
template <class ForwardIterator, class T>
inline void
__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,
const T& x, __true_type)
{
fill(first, last, x);
}
template <class ForwardIterator, class T>
void
__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,
const T& x, __false_type)
{
ForwardIterator cur = first;
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
for ( ; cur != last; ++cur)
construct(&*cur, x);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
destroy(first, cur);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
template <class ForwardIterator, class T, class T1>
inline void __uninitialized_fill(ForwardIterator first, ForwardIterator last,
const T& x, T1*) {
__uninitialized_fill_aux(first, last, x,
__type_traits<T1>::is_POD_type());
}
template <class ForwardIterator, class T>
inline void uninitialized_fill(ForwardIterator first, ForwardIterator last,
const T& x) {
__uninitialized_fill(first, last, x, value_type(first));
}
// Valid if copy construction is equivalent to assignment, and if the
// destructor is trivial.
template <class ForwardIterator, class Size, class T>
inline ForwardIterator
__uninitialized_fill_n_aux(ForwardIterator first, Size n,
const T& x, __true_type) {
return fill_n(first, n, x);
}
template <class ForwardIterator, class Size, class T>
ForwardIterator
__uninitialized_fill_n_aux(ForwardIterator first, Size n,
const T& x, __false_type) {
ForwardIterator cur = first;
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
for ( ; n > 0; --n, ++cur)
construct(&*cur, x);
return cur;
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
destroy(first, cur);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
template <class ForwardIterator, class Size, class T, class T1>
inline ForwardIterator __uninitialized_fill_n(ForwardIterator first, Size n,
const T& x, T1*) {
return __uninitialized_fill_n_aux(first, n, x,
__type_traits<T1>::is_POD_type());
}
template <class ForwardIterator, class Size, class T>
inline ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n,
const T& x) {
return __uninitialized_fill_n(first, n, x, value_type(first));
}
// Copies [first1, last1) into [result, result + (last1 - first1)), and
// copies [first2, last2) into
// [result, result + (last1 - first1) + (last2 - first2)).
template <class InputIterator1, class InputIterator2, class ForwardIterator>
inline ForwardIterator
__uninitialized_copy_copy(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
ForwardIterator result) {
ForwardIterator mid = uninitialized_copy(first1, last1, result);
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
return uninitialized_copy(first2, last2, mid);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
destroy(result, mid);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
// Fills [result, mid) with x, and copies [first, last) into
// [mid, mid + (last - first)).
template <class ForwardIterator, class T, class InputIterator>
inline ForwardIterator
__uninitialized_fill_copy(ForwardIterator result, ForwardIterator mid,
const T& x,
InputIterator first, InputIterator last) {
uninitialized_fill(result, mid, x);
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
return uninitialized_copy(first, last, mid);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
destroy(result, mid);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
// Copies [first1, last1) into [first2, first2 + (last1 - first1)), and
// fills [first2 + (last1 - first1), last2) with x.
template <class InputIterator, class ForwardIterator, class T>
inline void
__uninitialized_copy_fill(InputIterator first1, InputIterator last1,
ForwardIterator first2, ForwardIterator last2,
const T& x) {
ForwardIterator mid2 = uninitialized_copy(first1, last1, first2);
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
uninitialized_fill(mid2, last2, x);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
destroy(first2, mid2);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
#endif /* _SGI_STL_ALGOBASE_H */
#ifdef __STL_USE_NAMESPACES
// Names from stl_algobase.h
using __STD::iter_swap;
using __STD::swap;
using __STD::min;
using __STD::max;
using __STD::copy;
using __STD::copy_backward;
using __STD::copy_n;
using __STD::fill;
using __STD::fill_n;
using __STD::mismatch;
using __STD::equal;
using __STD::lexicographical_compare;
using __STD::lexicographical_compare_3way;
// Names from stl_uninitialized.h
using __STD::uninitialized_copy;
using __STD::uninitialized_copy_n;
using __STD::uninitialized_fill;
using __STD::uninitialized_fill_n;
#endif /* __STL_USE_NAMESPACES */
#endif /* __SGI_STL_ALGOBASE_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -11,674 +11,34 @@
* purpose. It is provided "as is" without express or implied warranty.
*/
#ifndef __ALLOC_H
#define __ALLOC_H
#ifndef __SGI_STL_ALLOC_H
#define __SGI_STL_ALLOC_H
#ifndef __STL_CONFIG_H
#include <stl_config.h>
#ifdef __SUNPRO_CC
# define __PRIVATE public
// Extra access restrictions prevent us from really making some things
// private.
#else
# define __PRIVATE private
#endif
#ifndef __SGI_STL_INTERNAL_ALLOC_H
#include <stl_alloc.h>
#endif
#ifdef __STL_USE_NAMESPACES
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
# define __USE_MALLOC
#endif
using __STD::__malloc_alloc_oom_handler;
#endif /* __STL_STATIC_TEMPLATE_MEMBER_BUG */
// 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.
#endif /* __STL_USE_NAMESPACES */
#if 0
# include <new>
# define __THROW_BAD_ALLOC throw bad_alloc
#elif !defined(__THROW_BAD_ALLOC)
# include <iostream.h>
# define __THROW_BAD_ALLOC cerr << "out of memory" << endl; exit(1)
#endif
#endif /* __SGI_STL_ALLOC_H */
#ifndef __ALLOC
# define __ALLOC alloc
#endif
#ifdef __STL_WIN32THREADS
# include <windows.h>
#endif
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#ifndef __RESTRICT
# define __RESTRICT
#endif
#if !defined(_PTHREADS) && !defined(_NOTHREADS) \
&& !defined(__STL_SGI_THREADS) && !defined(__STL_WIN32THREADS)
# define _NOTHREADS
#endif
# ifdef _PTHREADS
// POSIX Threads
// This is dubious, since this is likely to be a high contention
// lock. Performance may not be adequate.
# include <pthread.h>
# define __NODE_ALLOCATOR_LOCK \
if (threads) pthread_mutex_lock(&__node_allocator_lock)
# define __NODE_ALLOCATOR_UNLOCK \
if (threads) pthread_mutex_unlock(&__node_allocator_lock)
# define __NODE_ALLOCATOR_THREADS true
# define __VOLATILE volatile // Needed at -O3 on SGI
# endif
# ifdef __STL_WIN32THREADS
// The lock needs to be initialized by constructing an allocator
// objects of the right type. We do that here explicitly for alloc.
# define __NODE_ALLOCATOR_LOCK \
EnterCriticalSection(&__node_allocator_lock)
# define __NODE_ALLOCATOR_UNLOCK \
LeaveCriticalSection(&__node_allocator_lock)
# define __NODE_ALLOCATOR_THREADS true
# define __VOLATILE volatile // may not be needed
# endif /* WIN32THREADS */
# ifdef __STL_SGI_THREADS
// This should work without threads, with sproc threads, or with
// pthreads. It is suboptimal in all cases.
// It is unlikely to even compile on nonSGI machines.
extern int __us_rsthread_malloc;
// The above is copied from malloc.h. Including <malloc.h>
// would be cleaner but fails with certain levels of standard
// conformance.
# define __NODE_ALLOCATOR_LOCK if (threads && __us_rsthread_malloc) \
{ __lock(&__node_allocator_lock); }
# define __NODE_ALLOCATOR_UNLOCK if (threads && __us_rsthread_malloc) \
{ __unlock(&__node_allocator_lock); }
# define __NODE_ALLOCATOR_THREADS true
# define __VOLATILE volatile // Needed at -O3 on SGI
# endif
# ifdef _NOTHREADS
// Thread-unsafe
# define __NODE_ALLOCATOR_LOCK
# define __NODE_ALLOCATOR_UNLOCK
# define __NODE_ALLOCATOR_THREADS false
# define __VOLATILE
# endif
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma set woff 1174
#endif
// Malloc-based allocator. Typically slower than default alloc below.
// Typically thread-safe and more storage efficient.
#ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG
# ifdef __DECLARE_GLOBALS_HERE
void (* __malloc_alloc_oom_handler)() = 0;
// g++ 2.7.2 does not handle static template data members.
# else
extern void (* __malloc_alloc_oom_handler)();
# endif
#endif
template <int inst>
class __malloc_alloc_template {
private:
static void *oom_malloc(size_t);
static void *oom_realloc(void *, size_t);
#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG
static void (* __malloc_alloc_oom_handler)();
#endif
public:
static void * allocate(size_t n)
{
void *result = malloc(n);
if (0 == result) result = oom_malloc(n);
return result;
}
static void deallocate(void *p, size_t /* n */)
{
free(p);
}
static void * reallocate(void *p, size_t /* old_sz */, size_t new_sz)
{
void * result = realloc(p, new_sz);
if (0 == result) result = oom_realloc(p, new_sz);
return result;
}
static void (* set_malloc_handler(void (*f)()))()
{
void (* old)() = __malloc_alloc_oom_handler;
__malloc_alloc_oom_handler = f;
return(old);
}
};
// malloc_alloc out-of-memory handling
#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG
template <int inst>
void (* __malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = 0;
#endif
template <int inst>
void * __malloc_alloc_template<inst>::oom_malloc(size_t n)
{
void (* my_malloc_handler)();
void *result;
for (;;) {
my_malloc_handler = __malloc_alloc_oom_handler;
if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; }
(*my_malloc_handler)();
result = malloc(n);
if (result) return(result);
}
}
template <int inst>
void * __malloc_alloc_template<inst>::oom_realloc(void *p, size_t n)
{
void (* my_malloc_handler)();
void *result;
for (;;) {
my_malloc_handler = __malloc_alloc_oom_handler;
if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; }
(*my_malloc_handler)();
result = realloc(p, n);
if (result) return(result);
}
}
typedef __malloc_alloc_template<0> malloc_alloc;
template<class T, class Alloc>
class simple_alloc {
public:
static T *allocate(size_t n)
{ return 0 == n? 0 : (T*) Alloc::allocate(n * sizeof (T)); }
static T *allocate(void)
{ return (T*) Alloc::allocate(sizeof (T)); }
static void deallocate(T *p, size_t n)
{ if (0 != n) Alloc::deallocate(p, n * sizeof (T)); }
static void deallocate(T *p)
{ Alloc::deallocate(p, sizeof (T)); }
};
// Allocator adaptor to check size arguments for debugging.
// Reports errors using assert. Checking can be disabled with
// NDEBUG, but it's far better to just use the underlying allocator
// instead when no checking is desired.
// There is some evidence that this can confuse Purify.
template <class Alloc>
class debug_alloc {
private:
enum {extra = 8}; // Size of space used to store size. Note
// that this must be large enough to preserve
// alignment.
public:
static void * allocate(size_t n)
{
char *result = (char *)Alloc::allocate(n + extra);
*(size_t *)result = n;
return result + extra;
}
static void deallocate(void *p, size_t n)
{
char * real_p = (char *)p - extra;
assert(*(size_t *)real_p == n);
Alloc::deallocate(real_p, n + extra);
}
static void * reallocate(void *p, size_t old_sz, size_t new_sz)
{
char * real_p = (char *)p - extra;
assert(*(size_t *)real_p == old_sz);
char * result = (char *)
Alloc::reallocate(real_p, old_sz + extra, new_sz + extra);
*(size_t *)result = new_sz;
return result + extra;
}
};
# ifdef __USE_MALLOC
typedef malloc_alloc alloc;
typedef malloc_alloc single_client_alloc;
# else
// Default node allocator.
// With a reasonable compiler, this should be roughly as fast as the
// original STL class-specific allocators, but with less fragmentation.
// Default_alloc_template parameters are experimental and MAY
// DISAPPEAR in the future. Clients should just use alloc for now.
//
// Important implementation properties:
// 1. If the client request an object of size > __MAX_BYTES, the resulting
// object will be obtained directly from malloc.
// 2. In all other cases, we allocate an object of size exactly
// ROUND_UP(requested_size). Thus the client has enough size
// information that we can return the object to the proper free list
// without permanently losing part of the object.
//
// The first template parameter specifies whether more than one thread
// may use this allocator. It is safe to allocate an object from
// one instance of a default_alloc and deallocate it with another
// one. This effectively transfers its ownership to the second one.
// This may have undesirable effects on reference locality.
// The second parameter is unreferenced and serves only to allow the
// creation of multiple default_alloc instances.
// Node that containers built on different allocator instances have
// different types, limiting the utility of this approach.
#ifdef __SUNPRO_CC
// breaks if we make these template class members:
enum {__ALIGN = 8};
enum {__MAX_BYTES = 128};
enum {__NFREELISTS = __MAX_BYTES/__ALIGN};
#endif
template <bool threads, int inst>
class __default_alloc_template {
private:
// Really we should use static const int x = N
// instead of enum { x = N }, but few compilers accept the former.
# ifndef __SUNPRO_CC
enum {__ALIGN = 8};
enum {__MAX_BYTES = 128};
enum {__NFREELISTS = __MAX_BYTES/__ALIGN};
# endif
static size_t ROUND_UP(size_t bytes) {
return (((bytes) + __ALIGN-1) & ~(__ALIGN - 1));
}
__PRIVATE:
union obj {
union obj * free_list_link;
char client_data[1]; /* The client sees this. */
};
private:
# ifdef __SUNPRO_CC
static obj * __VOLATILE free_list[];
// Specifying a size results in duplicate def for 4.1
# else
static obj * __VOLATILE free_list[__NFREELISTS];
# endif
static size_t FREELIST_INDEX(size_t bytes) {
return (((bytes) + __ALIGN-1)/__ALIGN - 1);
}
// Returns an object of size n, and optionally adds to size n free list.
static void *refill(size_t n);
// Allocates a chunk for nobjs of size size. nobjs may be reduced
// if it is inconvenient to allocate the requested number.
static char *chunk_alloc(size_t size, int &nobjs);
// Chunk allocation state.
static char *start_free;
static char *end_free;
static size_t heap_size;
# ifdef __STL_SGI_THREADS
static volatile unsigned long __node_allocator_lock;
static void __lock(volatile unsigned long *);
static inline void __unlock(volatile unsigned long *);
# endif
# ifdef _PTHREADS
static pthread_mutex_t __node_allocator_lock;
# endif
# ifdef __STL_WIN32THREADS
static CRITICAL_SECTION __node_allocator_lock;
static bool __node_allocator_lock_initialized;
public:
__default_alloc_template() {
// This assumes the first constructor is called before threads
// are started.
if (!__node_allocator_lock_initialized) {
InitializeCriticalSection(&__node_allocator_lock);
__node_allocator_lock_initialized = true;
}
}
private:
# endif
class lock {
public:
lock() { __NODE_ALLOCATOR_LOCK; }
~lock() { __NODE_ALLOCATOR_UNLOCK; }
};
friend class lock;
public:
/* n must be > 0 */
static void * allocate(size_t n)
{
obj * __VOLATILE * my_free_list;
obj * __RESTRICT result;
if (n > (size_t) __MAX_BYTES) {
return(malloc_alloc::allocate(n));
}
my_free_list = free_list + FREELIST_INDEX(n);
// Acquire the lock here with a constructor call.
// This ensures that it is released in exit or during stack
// unwinding.
# ifndef _NOTHREADS
/*REFERENCED*/
lock lock_instance;
# endif
result = *my_free_list;
if (result == 0) {
void *r = refill(ROUND_UP(n));
return r;
}
*my_free_list = result -> free_list_link;
return (result);
};
/* p may not be 0 */
static void deallocate(void *p, size_t n)
{
obj *q = (obj *)p;
obj * __VOLATILE * my_free_list;
if (n > (size_t) __MAX_BYTES) {
malloc_alloc::deallocate(p, n);
return;
}
my_free_list = free_list + FREELIST_INDEX(n);
// acquire lock
# ifndef _NOTHREADS
/*REFERENCED*/
lock lock_instance;
# endif /* _NOTHREADS */
q -> free_list_link = *my_free_list;
*my_free_list = q;
// lock is released here
}
static void * reallocate(void *p, size_t old_sz, size_t new_sz);
} ;
typedef __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0> alloc;
typedef __default_alloc_template<false, 0> single_client_alloc;
/* We allocate memory in large chunks in order to avoid fragmenting */
/* the malloc heap too much. */
/* We assume that size is properly aligned. */
/* We hold the allocation lock. */
template <bool threads, int inst>
char*
__default_alloc_template<threads, inst>::chunk_alloc(size_t size, int& nobjs)
{
char * result;
size_t total_bytes = size * nobjs;
size_t bytes_left = end_free - start_free;
if (bytes_left >= total_bytes) {
result = start_free;
start_free += total_bytes;
return(result);
} else if (bytes_left >= size) {
nobjs = bytes_left/size;
total_bytes = size * nobjs;
result = start_free;
start_free += total_bytes;
return(result);
} else {
size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);
// Try to make use of the left-over piece.
if (bytes_left > 0) {
obj * __VOLATILE * my_free_list =
free_list + FREELIST_INDEX(bytes_left);
((obj *)start_free) -> free_list_link = *my_free_list;
*my_free_list = (obj *)start_free;
}
start_free = (char *)malloc(bytes_to_get);
if (0 == start_free) {
int i;
obj * __VOLATILE * my_free_list, *p;
// Try to make do with what we have. That can't
// hurt. We do not try smaller requests, since that tends
// to result in disaster on multi-process machines.
for (i = size; i <= __MAX_BYTES; i += __ALIGN) {
my_free_list = free_list + FREELIST_INDEX(i);
p = *my_free_list;
if (0 != p) {
*my_free_list = p -> free_list_link;
start_free = (char *)p;
end_free = start_free + i;
return(chunk_alloc(size, nobjs));
// Any leftover piece will eventually make it to the
// right free list.
}
}
end_free = 0; // In case of exception.
start_free = (char *)malloc_alloc::allocate(bytes_to_get);
// This should either throw an
// exception or remedy the situation. Thus we assume it
// succeeded.
}
heap_size += bytes_to_get;
end_free = start_free + bytes_to_get;
return(chunk_alloc(size, nobjs));
}
}
/* Returns an object of size n, and optionally adds to size n free list.*/
/* We assume that n is properly aligned. */
/* We hold the allocation lock. */
template <bool threads, int inst>
void* __default_alloc_template<threads, inst>::refill(size_t n)
{
int nobjs = 20;
char * chunk = chunk_alloc(n, nobjs);
obj * __VOLATILE * my_free_list;
obj * result;
obj * current_obj, * next_obj;
int i;
if (1 == nobjs) return(chunk);
my_free_list = free_list + FREELIST_INDEX(n);
/* Build free list in chunk */
result = (obj *)chunk;
*my_free_list = next_obj = (obj *)(chunk + n);
for (i = 1; ; i++) {
current_obj = next_obj;
next_obj = (obj *)((char *)next_obj + n);
if (nobjs - 1 == i) {
current_obj -> free_list_link = 0;
break;
} else {
current_obj -> free_list_link = next_obj;
}
}
return(result);
}
template <bool threads, int inst>
void*
__default_alloc_template<threads, inst>::reallocate(void *p,
size_t old_sz,
size_t new_sz)
{
void * result;
size_t copy_sz;
if (old_sz > (size_t) __MAX_BYTES && new_sz > (size_t) __MAX_BYTES) {
return(realloc(p, new_sz));
}
if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return(p);
result = allocate(new_sz);
copy_sz = new_sz > old_sz? old_sz : new_sz;
memcpy(result, p, copy_sz);
deallocate(p, old_sz);
return(result);
}
#ifdef _PTHREADS
template <bool threads, int inst>
pthread_mutex_t
__default_alloc_template<threads, inst>::__node_allocator_lock
= PTHREAD_MUTEX_INITIALIZER;
#endif
#ifdef __STL_WIN32THREADS
template <bool threads, int inst> CRITICAL_SECTION
__default_alloc_template<threads, inst>::__node_allocator_lock;
template <bool threads, int inst> bool
__default_alloc_template<threads, inst>::__node_allocator_lock_initialized
= false;
#endif
#ifdef __STL_SGI_THREADS
#include <mutex.h>
#include <time.h>
// Somewhat generic lock implementations. We need only test-and-set
// and some way to sleep. These should work with both SGI pthreads
// and sproc threads. They may be useful on other systems.
template <bool threads, int inst>
volatile unsigned long
__default_alloc_template<threads, inst>::__node_allocator_lock = 0;
#if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) || defined(__GNUC__)
# define __test_and_set(l,v) test_and_set(l,v)
#endif
template <bool threads, int inst>
void
__default_alloc_template<threads, inst>::__lock(volatile unsigned long *lock)
{
const unsigned low_spin_max = 30; // spin cycles if we suspect uniprocessor
const unsigned high_spin_max = 1000; // spin cycles for multiprocessor
static unsigned spin_max = low_spin_max;
unsigned my_spin_max;
static unsigned last_spins = 0;
unsigned my_last_spins;
static struct timespec ts = {0, 1000};
unsigned junk;
# define __ALLOC_PAUSE junk *= junk; junk *= junk; junk *= junk; junk *= junk
int i;
if (!__test_and_set((unsigned long *)lock, 1)) {
return;
}
my_spin_max = spin_max;
my_last_spins = last_spins;
for (i = 0; i < my_spin_max; i++) {
if (i < my_last_spins/2 || *lock) {
__ALLOC_PAUSE;
continue;
}
if (!__test_and_set((unsigned long *)lock, 1)) {
// got it!
// Spinning worked. Thus we're probably not being scheduled
// against the other process with which we were contending.
// Thus it makes sense to spin longer the next time.
last_spins = i;
spin_max = high_spin_max;
return;
}
}
// We are probably being scheduled against the other process. Sleep.
spin_max = low_spin_max;
for (;;) {
if (!__test_and_set((unsigned long *)lock, 1)) {
return;
}
nanosleep(&ts, 0);
}
}
template <bool threads, int inst>
inline void
__default_alloc_template<threads, inst>::__unlock(volatile unsigned long *lock)
{
# if defined(__GNUC__) && __mips >= 3
asm("sync");
*lock = 0;
# elif __mips >= 3 && (defined (_ABIN32) || defined(_ABI64))
__lock_release(lock);
# else
*lock = 0;
// This is not sufficient on many multiprocessors, since
// writes to protected variables and the lock may be reordered.
# endif
}
#endif
template <bool threads, int inst>
char *__default_alloc_template<threads, inst>::start_free = 0;
template <bool threads, int inst>
char *__default_alloc_template<threads, inst>::end_free = 0;
template <bool threads, int inst>
size_t __default_alloc_template<threads, inst>::heap_size = 0;
template <bool threads, int inst>
__default_alloc_template<threads, inst>::obj * __VOLATILE
__default_alloc_template<threads, inst> ::free_list[
# ifdef __SUNPRO_CC
__NFREELISTS
# else
__default_alloc_template<threads, inst>::__NFREELISTS
# endif
] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
// The 16 zeros are necessary to make version 4.1 of the SunPro
// compiler happy. Otherwise it appears to allocate too little
// space for the array.
# ifdef __STL_WIN32THREADS
// Create one to get critical section initialized.
// We do this onece per file, but only the first constructor
// does anything.
static alloc __node_allocator_dummy_instance;
# endif
#endif /* ! __USE_MALLOC */
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma reset woff 1174
#endif
#undef __PRIVATE
#endif /* __ALLOC_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -24,541 +24,28 @@
* purpose. It is provided "as is" without express or implied warranty.
*/
// vector<bool> is replaced by bit_vector at present because partial
// specialization is not yet implemented.
#ifndef __SGI_STL_BVECTOR_H
#define __SGI_STL_BVECTOR_H
#include <stddef.h>
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
#include <vector.h>
#else
#include <algobase.h>
#include <alloc.h>
#endif
#include <stl_bvector.h>
#define __WORD_BIT (int(CHAR_BIT*sizeof(unsigned int)))
#ifdef __STL_USE_NAMESPACES
class bit_vector {
public:
typedef bool value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
using __STD::bit_vector;
class iterator;
class const_iterator;
class reference {
friend class iterator;
friend class const_iterator;
protected:
unsigned int* p;
unsigned int mask;
reference(unsigned int* x, unsigned int y) : p(x), mask(y) {}
public:
reference() : p(0), mask(0) {}
operator bool() const { return !(!(*p & mask)); }
reference& operator=(bool x) {
if (x)
*p |= mask;
else
*p &= ~mask;
return *this;
}
reference& operator=(const reference& x) { return *this = bool(x); }
bool operator==(const reference& x) const {
return bool(*this) == bool(x);
}
bool operator<(const reference& x) const {
return bool(*this) < bool(x);
}
void flip() { *p ^= mask; }
};
typedef bool const_reference;
typedef reference bit_reference;
typedef const_reference bit_const_reference;
class iterator : public random_access_iterator<bool, difference_type> {
friend class bit_vector;
friend class const_iterator;
public:
typedef bit_reference reference;
typedef bit_reference* pointer;
protected:
unsigned int* p;
unsigned int offset;
void bump_up() {
if (offset++ == __WORD_BIT - 1) {
offset = 0;
++p;
}
}
void bump_down() {
if (offset-- == 0) {
offset = __WORD_BIT - 1;
--p;
}
}
public:
iterator() : p(0), offset(0) {}
iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {}
reference operator*() const { return reference(p, 1U << offset); }
iterator& operator++() {
bump_up();
return *this;
}
iterator operator++(int) {
iterator tmp = *this;
bump_up();
return tmp;
}
iterator& operator--() {
bump_down();
return *this;
}
iterator operator--(int) {
iterator tmp = *this;
bump_down();
return tmp;
}
iterator& operator+=(difference_type i) {
difference_type n = i + offset;
p += n / __WORD_BIT;
n = n % __WORD_BIT;
if (n < 0) {
offset = n + __WORD_BIT;
--p;
} else
offset = n;
return *this;
}
iterator& operator-=(difference_type i) {
*this += -i;
return *this;
}
iterator operator+(difference_type i) const {
iterator tmp = *this;
return tmp += i;
}
iterator operator-(difference_type i) const {
iterator tmp = *this;
return tmp -= i;
}
difference_type operator-(iterator x) const {
return __WORD_BIT * (p - x.p) + offset - x.offset;
}
reference operator[](difference_type i) { return *(*this + i); }
bool operator==(const iterator& x) const {
return p == x.p && offset == x.offset;
}
bool operator!=(const iterator& x) const {
return p != x.p || offset != x.offset;
}
bool operator<(iterator x) const {
return p < x.p || (p == x.p && offset < x.offset);
}
};
class const_iterator : public random_access_iterator<bool, difference_type>
{
friend class bit_vector;
public:
typedef bit_const_reference reference;
typedef const bool* pointer;
protected:
unsigned int* p;
unsigned int offset;
void bump_up() {
if (offset++ == __WORD_BIT - 1) {
offset = 0;
++p;
}
}
void bump_down() {
if (offset-- == 0) {
offset = __WORD_BIT - 1;
--p;
}
}
public:
const_iterator() : p(0), offset(0) {}
const_iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {}
const_iterator(const iterator& x) : p(x.p), offset(x.offset) {}
const_reference operator*() const {
return bit_vector::reference(p, 1U << offset);
}
const_iterator& operator++() {
bump_up();
return *this;
}
const_iterator operator++(int) {
const_iterator tmp = *this;
bump_up();
return tmp;
}
const_iterator& operator--() {
bump_down();
return *this;
}
const_iterator operator--(int) {
const_iterator tmp = *this;
bump_down();
return tmp;
}
const_iterator& operator+=(difference_type i) {
difference_type n = i + offset;
p += n / __WORD_BIT;
n = n % __WORD_BIT;
if (n < 0) {
offset = n + __WORD_BIT;
--p;
} else
offset = n;
return *this;
}
const_iterator& operator-=(difference_type i) {
*this += -i;
return *this;
}
const_iterator operator+(difference_type i) const {
const_iterator tmp = *this;
return tmp += i;
}
const_iterator operator-(difference_type i) const {
const_iterator tmp = *this;
return tmp -= i;
}
difference_type operator-(const_iterator x) const {
return __WORD_BIT * (p - x.p) + offset - x.offset;
}
const_reference operator[](difference_type i) {
return *(*this + i);
}
bool operator==(const const_iterator& x) const {
return p == x.p && offset == x.offset;
}
bool operator!=(const const_iterator& x) const {
return p != x.p || offset != x.offset;
}
bool operator<(const_iterator x) const {
return p < x.p || (p == x.p && offset < x.offset);
}
};
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator;
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
typedef reverse_iterator<const_iterator, value_type, const_reference,
difference_type> const_reverse_iterator;
typedef reverse_iterator<iterator, value_type, reference, difference_type>
reverse_iterator;
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
protected:
typedef simple_alloc<unsigned int, alloc> data_allocator;
iterator start;
iterator finish;
unsigned int* end_of_storage;
unsigned int* bit_alloc(size_type n) {
return data_allocator::allocate((n + __WORD_BIT - 1)/__WORD_BIT);
}
void deallocate() {
if (start.p)
data_allocator::deallocate(start.p, end_of_storage - start.p);
}
void initialize(size_type n) {
unsigned int* q = bit_alloc(n);
end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT;
start = iterator(q, 0);
finish = start + n;
}
void insert_aux(iterator position, bool x) {
if (finish.p != end_of_storage) {
copy_backward(position, finish, finish + 1);
*position = x;
++finish;
} else {
size_type len = size() ? 2 * size() : __WORD_BIT;
unsigned int* q = bit_alloc(len);
iterator i = copy(begin(), position, iterator(q, 0));
*i++ = x;
finish = copy(position, end(), i);
deallocate();
end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
start = iterator(q, 0);
}
}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void initialize_range(InputIterator first, InputIterator last,
input_iterator_tag) {
start = iterator();
finish = iterator();
end_of_storage = 0;
for ( ; first != last; ++first)
push_back(*first);
}
template <class ForwardIterator>
void initialize_range(ForwardIterator first, ForwardIterator last,
forward_iterator_tag) {
size_type n = 0;
distance(first, last, n);
initialize(n);
copy(first, last, start);
}
template <class InputIterator>
void insert_range(iterator pos,
InputIterator first, InputIterator last,
input_iterator_tag) {
for ( ; first != last; ++first) {
pos = insert(pos, *first);
++pos;
}
}
template <class ForwardIterator>
void insert_range(iterator position,
ForwardIterator first, ForwardIterator last,
forward_iterator_tag) {
if (first != last) {
size_type n = 0;
distance(first, last, n);
if (capacity() - size() >= n) {
copy_backward(position, end(), finish + 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 */
typedef bit_vector self;
public:
iterator begin() { return start; }
const_iterator begin() const { return start; }
iterator end() { return finish; }
const_iterator end() const { return finish; }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
size_type size() const { return size_type(end() - begin()); }
size_type max_size() const { return size_type(-1); }
size_type capacity() const {
return size_type(const_iterator(end_of_storage, 0) - begin());
}
bool empty() const { return begin() == end(); }
reference operator[](size_type n) { return *(begin() + n); }
const_reference operator[](size_type n) const { return *(begin() + n); }
bit_vector() : start(iterator()), finish(iterator()), end_of_storage(0) {}
bit_vector(size_type n, bool value) {
initialize(n);
fill(start.p, end_of_storage, value ? ~0 : 0);
}
bit_vector(int n, bool value) {
initialize(n);
fill(start.p, end_of_storage, value ? ~0 : 0);
}
bit_vector(long n, bool value) {
initialize(n);
fill(start.p, end_of_storage, value ? ~0 : 0);
}
explicit bit_vector(size_type n) {
initialize(n);
fill(start.p, end_of_storage, 0);
}
bit_vector(const self& x) {
initialize(x.size());
copy(x.begin(), x.end(), start);
}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
bit_vector(InputIterator first, InputIterator last) {
initialize_range(first, last, iterator_category(first));
}
#else /* __STL_MEMBER_TEMPLATES */
bit_vector(const_iterator first, const_iterator last) {
size_type n = 0;
distance(first, last, n);
initialize(n);
copy(first, last, start);
}
bit_vector(const bool* first, const bool* last) {
size_type n = 0;
distance(first, last, n);
initialize(n);
copy(first, last, start);
}
#endif /* __STL_MEMBER_TEMPLATES */
~bit_vector() { deallocate(); }
self& operator=(const self& x) {
if (&x == this) return *this;
if (x.size() > capacity()) {
deallocate();
initialize(x.size());
}
copy(x.begin(), x.end(), begin());
finish = begin() + x.size();
return *this;
}
void reserve(size_type n) {
if (capacity() < n) {
unsigned int* q = bit_alloc(n);
finish = copy(begin(), end(), iterator(q, 0));
deallocate();
start = iterator(q, 0);
end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT;
}
}
reference front() { return *begin(); }
const_reference front() const { return *begin(); }
reference back() { return *(end() - 1); }
const_reference back() const { return *(end() - 1); }
void push_back(bool x) {
if (finish.p != end_of_storage)
*finish++ = x;
else
insert_aux(end(), x);
}
void swap(bit_vector& x) {
::swap(start, x.start);
::swap(finish, x.finish);
::swap(end_of_storage, x.end_of_storage);
}
iterator insert(iterator position, bool x = bool()) {
size_type n = position - begin();
if (finish.p != end_of_storage && position == end())
*finish++ = x;
else
insert_aux(position, x);
return begin() + n;
}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator> void insert(iterator position,
InputIterator first,
InputIterator last) {
insert_range(position, first, last, iterator_category(first));
}
#else /* __STL_MEMBER_TEMPLATES */
void insert(iterator position, const_iterator first,
const_iterator last) {
if (first == last) return;
size_type n = 0;
distance(first, last, n);
if (capacity() - size() >= n) {
copy_backward(position, end(), finish + n);
copy(first, last, position);
finish += n;
} else {
size_type len = size() + max(size(), n);
unsigned int* q = bit_alloc(len);
iterator i = copy(begin(), position, iterator(q, 0));
i = copy(first, last, i);
finish = copy(position, end(), i);
deallocate();
end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
start = iterator(q, 0);
}
}
void insert(iterator position, const bool* first, const bool* last) {
if (first == last) return;
size_type n = 0;
distance(first, last, n);
if (capacity() - size() >= n) {
copy_backward(position, end(), finish + n);
copy(first, last, position);
finish += n;
} else {
size_type len = size() + max(size(), n);
unsigned int* q = bit_alloc(len);
iterator i = copy(begin(), position, iterator(q, 0));
i = copy(first, last, i);
finish = copy(position, end(), i);
deallocate();
end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
start = iterator(q, 0);
}
}
#endif /* __STL_MEMBER_TEMPLATES */
void insert(iterator position, size_type n, bool x) {
if (n == 0) return;
if (capacity() - size() >= n) {
copy_backward(position, end(), finish + n);
fill(position, position + n, x);
finish += n;
} else {
size_type len = size() + max(size(), n);
unsigned int* q = bit_alloc(len);
iterator i = copy(begin(), position, iterator(q, 0));
fill_n(i, n, x);
finish = copy(position, end(), i + n);
deallocate();
end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT;
start = iterator(q, 0);
}
}
void insert(iterator pos, int n, bool x) { insert(pos, (size_type)n, x); }
void insert(iterator pos, long n, bool x) { insert(pos, (size_type)n, x); }
void pop_back() { --finish; }
void erase(iterator position) {
if (position + 1 != end())
copy(position + 1, end(), position);
--finish;
}
void erase(iterator first, iterator last) {
finish = copy(last, end(), first);
}
void resize(size_type new_size, bool x = bool()) {
if (new_size < size())
erase(begin() + new_size, end());
else
insert(end(), new_size - size(), x);
}
void clear() { erase(begin(), end()); }
};
inline bool operator==(const bit_vector& x, const bit_vector& y) {
return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
}
inline bool operator<(const bit_vector& x, const bit_vector& y) {
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
inline void swap(bit_vector::reference x, bit_vector::reference y) {
bool tmp = x;
x = y;
y = tmp;
}
#undef __WORD_BIT
#endif /* __STL_USE_NAMESPACES */
#endif /* __SGI_STL_BVECTOR_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,7 @@
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
@@ -27,608 +27,92 @@
#ifndef __SGI_STL_FUNCTION_H
#define __SGI_STL_FUNCTION_H
#include <stddef.h>
#ifndef __STL_CONFIG_H
#include <stl_config.h>
template <class T>
inline bool operator!=(const T& x, const T& y) {
return !(x == y);
}
template <class T>
inline bool operator>(const T& x, const T& y) {
return y < x;
}
template <class T>
inline bool operator<=(const T& x, const T& y) {
return !(y < x);
}
template <class T>
inline bool operator>=(const T& x, const T& y) {
return !(x < y);
}
template <class Arg, class Result>
struct unary_function {
typedef Arg argument_type;
typedef Result result_type;
};
template <class Arg1, class Arg2, class Result>
struct binary_function {
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
template <class T>
struct plus : public binary_function<T, T, T> {
T operator()(const T& x, const T& y) const { return x + y; }
};
template <class T>
struct minus : public binary_function<T, T, T> {
T operator()(const T& x, const T& y) const { return x - y; }
};
template <class T>
struct multiplies : public binary_function<T, T, T> {
T operator()(const T& x, const T& y) const { return x * y; }
};
template <class T>
struct divides : public binary_function<T, T, T> {
T operator()(const T& x, const T& y) const { return x / y; }
};
template <class T> inline T identity_element(plus<T>) { return T(0); }
template <class T> inline T identity_element(multiplies<T>) { return T(1); }
template <class T>
struct modulus : public binary_function<T, T, T> {
T operator()(const T& x, const T& y) const { return x % y; }
};
template <class T>
struct negate : public unary_function<T, T> {
T operator()(const T& x) const { return -x; }
};
template <class T>
struct equal_to : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x == y; }
};
template <class T>
struct not_equal_to : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x != y; }
};
template <class T>
struct greater : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x > y; }
};
template <class T>
struct less : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x < y; }
};
template <class T>
struct greater_equal : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x >= y; }
};
template <class T>
struct less_equal : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x <= y; }
};
template <class T>
struct logical_and : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x && y; }
};
template <class T>
struct logical_or : public binary_function<T, T, bool> {
bool operator()(const T& x, const T& y) const { return x || y; }
};
template <class T>
struct logical_not : public unary_function<T, bool> {
bool operator()(const T& x) const { return !x; }
};
template <class Predicate>
class unary_negate
: public unary_function<typename Predicate::argument_type, bool> {
protected:
Predicate pred;
public:
explicit unary_negate(const Predicate& x) : pred(x) {}
bool operator()(const argument_type& x) const { return !pred(x); }
};
template <class Predicate>
inline unary_negate<Predicate> not1(const Predicate& pred) {
return unary_negate<Predicate>(pred);
}
template <class Predicate>
class binary_negate
: public binary_function<typename Predicate::first_argument_type,
typename Predicate::second_argument_type,
bool> {
protected:
Predicate pred;
public:
explicit binary_negate(const Predicate& x) : pred(x) {}
bool operator()(const first_argument_type& x,
const second_argument_type& y) const {
return !pred(x, y);
}
};
template <class Predicate>
inline binary_negate<Predicate> not2(const Predicate& pred) {
return binary_negate<Predicate>(pred);
}
template <class Operation>
class binder1st
: public unary_function<typename Operation::second_argument_type,
typename Operation::result_type> {
protected:
Operation op;
typename Operation::first_argument_type value;
public:
binder1st(const Operation& x,
const typename Operation::first_argument_type& y)
: op(x), value(y) {}
result_type operator()(const argument_type& x) const {
return op(value, x);
}
};
template <class Operation, class T>
inline binder1st<Operation> bind1st(const Operation& op, const T& x) {
typedef typename Operation::first_argument_type arg1_type;
return binder1st<Operation>(op, arg1_type(x));
}
template <class Operation>
class binder2nd
: public unary_function<typename Operation::first_argument_type,
typename Operation::result_type> {
protected:
Operation op;
typename Operation::second_argument_type value;
public:
binder2nd(const Operation& x,
const typename Operation::second_argument_type& y)
: op(x), value(y) {}
result_type operator()(const argument_type& x) const {
return op(x, value);
}
};
template <class Operation, class T>
inline binder2nd<Operation> bind2nd(const Operation& op, const T& x) {
typedef typename Operation::second_argument_type arg2_type;
return binder2nd<Operation>(op, arg2_type(x));
}
template <class Operation1, class Operation2>
class unary_compose : public unary_function<typename Operation2::argument_type,
typename Operation1::result_type> {
protected:
Operation1 op1;
Operation2 op2;
public:
unary_compose(const Operation1& x, const Operation2& y) : op1(x), op2(y) {}
result_type operator()(const argument_type& x) const {
return op1(op2(x));
}
};
template <class Operation1, class Operation2>
inline unary_compose<Operation1, Operation2> compose1(const Operation1& op1,
const Operation2& op2) {
return unary_compose<Operation1, Operation2>(op1, op2);
}
template <class Operation1, class Operation2, class Operation3>
class binary_compose
: public unary_function<typename Operation2::argument_type,
typename Operation1::result_type> {
protected:
Operation1 op1;
Operation2 op2;
Operation3 op3;
public:
binary_compose(const Operation1& x, const Operation2& y,
const Operation3& z) : op1(x), op2(y), op3(z) { }
result_type operator()(const argument_type& x) const {
return op1(op2(x), op3(x));
}
};
template <class Operation1, class Operation2, class Operation3>
inline binary_compose<Operation1, Operation2, Operation3>
compose2(const Operation1& op1, const Operation2& op2, const Operation3& op3) {
return binary_compose<Operation1, Operation2, Operation3>(op1, op2, op3);
}
template <class Arg, class Result>
class pointer_to_unary_function : public unary_function<Arg, Result> {
protected:
Result (*ptr)(Arg);
public:
pointer_to_unary_function() {}
explicit pointer_to_unary_function(Result (*x)(Arg)) : ptr(x) {}
Result operator()(Arg x) const { return ptr(x); }
};
template <class Arg, class Result>
inline pointer_to_unary_function<Arg, Result> ptr_fun(Result (*x)(Arg)) {
return pointer_to_unary_function<Arg, Result>(x);
}
template <class Arg1, class Arg2, class Result>
class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result> {
protected:
Result (*ptr)(Arg1, Arg2);
public:
pointer_to_binary_function() {}
explicit pointer_to_binary_function(Result (*x)(Arg1, Arg2)) : ptr(x) {}
Result operator()(Arg1 x, Arg2 y) const { return ptr(x, y); }
};
template <class Arg1, class Arg2, class Result>
inline pointer_to_binary_function<Arg1, Arg2, Result>
ptr_fun(Result (*x)(Arg1, Arg2)) {
return pointer_to_binary_function<Arg1, Arg2, Result>(x);
}
template <class T>
struct identity : public unary_function<T, T> {
const T& operator()(const T& x) const { return x; }
};
template <class Pair>
struct select1st : public unary_function<Pair, typename Pair::first_type> {
const typename Pair::first_type& operator()(const Pair& x) const
{
return x.first;
}
};
template <class Pair>
struct select2nd : public unary_function<Pair, typename Pair::second_type> {
const typename Pair::second_type& operator()(const Pair& x) const
{
return x.second;
}
};
template <class Arg1, class Arg2>
struct project1st : public binary_function<Arg1, Arg2, Arg1> {
Arg1 operator()(const Arg1& x, const Arg2&) const { return x; }
};
template <class Arg1, class Arg2>
struct project2nd : public binary_function<Arg1, Arg2, Arg2> {
Arg2 operator()(const Arg1&, const Arg2& y) const { return y; }
};
template <class Result>
struct constant_void_fun
{
typedef Result result_type;
result_type val;
constant_void_fun(const result_type& v) : val(v) {}
const result_type& operator()() const { return val; }
};
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class Result, class Argument = Result>
#else
template <class Result, class Argument>
#endif
struct constant_unary_fun : public unary_function<Argument, Result> {
result_type val;
constant_unary_fun(const result_type& v) : val(v) {}
const result_type& operator()(const argument_type&) const { return val; }
};
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class Result, class Arg1 = Result, class Arg2 = Arg1>
#else
template <class Result, class Arg1, class Arg2>
#ifndef __SGI_STL_INTERNAL_RELOPS
#include <stl_relops.h>
#endif
#include <stddef.h>
#ifndef __SGI_STL_INTERNAL_FUNCTION_H
#include <stl_function.h>
#endif
struct constant_binary_fun : public binary_function<Arg1, Arg2, Result> {
result_type val;
constant_binary_fun(const result_type& v) : val(v) {}
const result_type& operator()(const first_argument_type&,
const second_argument_type&) const {
return val;
}
};
template <class Result>
inline constant_void_fun<Result> constant0(const Result& val)
{
return constant_void_fun<Result>(val);
}
#ifdef __STL_USE_NAMESPACE_FOR_RELOPS
template <class Result>
inline constant_unary_fun<Result,Result> constant1(const Result& val)
{
return constant_unary_fun<Result,Result>(val);
}
// Names from stl_relops.h
using __STD_RELOPS::operator!=;
using __STD_RELOPS::operator>;
using __STD_RELOPS::operator<=;
using __STD_RELOPS::operator>=;
template <class Result>
inline constant_binary_fun<Result,Result,Result> constant2(const Result& val)
{
return constant_binary_fun<Result,Result,Result>(val);
}
#endif /* __STL_USE_NAMESPACE_FOR_RELOPS */
// Note: this code assumes that int is 32 bits.
class subtractive_rng : public unary_function<unsigned int, unsigned int> {
private:
unsigned int table[55];
size_t index1;
size_t index2;
public:
unsigned int operator()(unsigned int limit) {
index1 = (index1 + 1) % 55;
index2 = (index2 + 1) % 55;
table[index1] = table[index1] - table[index2];
return table[index1] % limit;
}
#ifdef __STL_USE_NAMESPACES
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;
}
// 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;
subtractive_rng(unsigned int seed) { initialize(seed); }
subtractive_rng() { initialize(161803398u); }
};
// Adaptor function objects: pointers to member functions.
// There are a total of 16 = 2^4 function objects in this family.
// (1) Member functions taking no arguments vs member functions taking
// one argument.
// (2) Call through pointer vs call through reference.
// (3) Member function with void return type vs member function with
// non-void return type.
// (4) Const vs non-const member function.
// Note that choice (4) is not present in the 8/97 draft C++ standard,
// which only allows these adaptors to be used with non-const functions.
// This is likely to be recified before the standard becomes final.
// Note also that choice (3) is nothing more than a workaround: according
// to the draft, compilers should handle void and non-void the same way.
// This feature is not yet widely implemented, though. You can only use
// member functions returning void if your compiler supports partial
// specialization.
// All of this complexity is in the function objects themselves. You can
// ignore it by using the helper function mem_fun, mem_fun_ref,
// mem_fun1, and mem_fun1_ref, which create whichever type of adaptor
// is appropriate.
template <class S, class T>
class mem_fun_t : public unary_function<T*, S> {
public:
explicit mem_fun_t(S (T::*pf)()) : f(pf) {}
S operator()(T* p) const { return (p->*f)(); }
private:
S (T::*f)();
};
template <class S, class T>
class const_mem_fun_t : public unary_function<const T*, S> {
public:
explicit const_mem_fun_t(S (T::*pf)() const) : f(pf) {}
S operator()(const T* p) const { return (p->*f)(); }
private:
S (T::*f)() const;
};
template <class S, class T>
class mem_fun_ref_t : public unary_function<T, S> {
public:
explicit mem_fun_ref_t(S (T::*pf)()) : f(pf) {}
S operator()(T& r) const { return (r.*f)(); }
private:
S (T::*f)();
};
template <class S, class T>
class const_mem_fun_ref_t : public unary_function<T, S> {
public:
explicit const_mem_fun_ref_t(S (T::*pf)() const) : f(pf) {}
S operator()(const T& r) const { return (r.*f)(); }
private:
S (T::*f)() const;
};
template <class S, class T, class A>
class mem_fun1_t : public binary_function<T*, A, S> {
public:
explicit mem_fun1_t(S (T::*pf)(A)) : f(pf) {}
S operator()(T* p, A x) const { return (p->*f)(x); }
private:
S (T::*f)(A);
};
template <class S, class T, class A>
class const_mem_fun1_t : public binary_function<const T*, A, S> {
public:
explicit const_mem_fun1_t(S (T::*pf)(A) const) : f(pf) {}
S operator()(const T* p, A x) const { return (p->*f)(x); }
private:
S (T::*f)(A) const;
};
template <class S, class T, class A>
class mem_fun1_ref_t : public binary_function<T, A, S> {
public:
explicit mem_fun1_ref_t(S (T::*pf)(A)) : f(pf) {}
S operator()(T& r, A x) const { return (r.*f)(x); }
private:
S (T::*f)(A);
};
template <class S, class T, class A>
class const_mem_fun1_ref_t : public binary_function<T, A, S> {
public:
explicit const_mem_fun1_ref_t(S (T::*pf)(A) const) : f(pf) {}
S operator()(const T& r, A x) const { return (r.*f)(x); }
private:
S (T::*f)(A) const;
};
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
template <class T>
class mem_fun_t<void, T> : public unary_function<T*, void> {
public:
explicit mem_fun_t(void (T::*pf)()) : f(pf) {}
void operator()(T* p) const { (p->*f)(); }
private:
void (T::*f)();
};
template <class T>
class const_mem_fun_t<void, T> : public unary_function<const T*, void> {
public:
explicit const_mem_fun_t(void (T::*pf)() const) : f(pf) {}
void operator()(const T* p) const { (p->*f)(); }
private:
void (T::*f)() const;
};
template <class T>
class mem_fun_ref_t<void, T> : public unary_function<T, void> {
public:
explicit mem_fun_ref_t(void (T::*pf)()) : f(pf) {}
void operator()(T& r) const { (r.*f)(); }
private:
void (T::*f)();
};
template <class T>
class const_mem_fun_ref_t<void, T> : public unary_function<T, void> {
public:
explicit const_mem_fun_ref_t(void (T::*pf)() const) : f(pf) {}
void operator()(const T& r) const { (r.*f)(); }
private:
void (T::*f)() const;
};
template <class T, class A>
class mem_fun1_t<void, T, A> : public binary_function<T*, A, void> {
public:
explicit mem_fun1_t(void (T::*pf)(A)) : f(pf) {}
void operator()(T* p, A x) const { (p->*f)(x); }
private:
void (T::*f)(A);
};
template <class T, class A>
class const_mem_fun1_t<void, T, A> : public binary_function<const T*, A, void> {
public:
explicit const_mem_fun1_t(void (T::*pf)(A) const) : f(pf) {}
void operator()(const T* p, A x) const { (p->*f)(x); }
private:
void (T::*f)(A) const;
};
template <class T, class A>
class mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> {
public:
explicit mem_fun1_ref_t(void (T::*pf)(A)) : f(pf) {}
void operator()(T& r, A x) const { (r.*f)(x); }
private:
void (T::*f)(A);
};
template <class T, class A>
class const_mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> {
public:
explicit const_mem_fun1_ref_t(void (T::*pf)(A) const) : f(pf) {}
void operator()(const T& r, A x) const { (r.*f)(x); }
private:
void (T::*f)(A) const;
};
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
// Mem_fun adaptor helper functions. There are only four:
// mem_fun, mem_fun_ref, mem_fun1, mem_fun1_ref.
template <class S, class T>
inline mem_fun_t<S,T> mem_fun(S (T::*f)()) {
return mem_fun_t<S,T>(f);
}
template <class S, class T>
inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const) {
return const_mem_fun_t<S,T>(f);
}
template <class S, class T>
inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)()) {
return mem_fun_ref_t<S,T>(f);
}
template <class S, class T>
inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const) {
return const_mem_fun_ref_t<S,T>(f);
}
template <class S, class T, class A>
inline mem_fun1_t<S,T,A> mem_fun1(S (T::*f)(A)) {
return mem_fun1_t<S,T,A>(f);
}
template <class S, class T, class A>
inline const_mem_fun1_t<S,T,A> mem_fun1(S (T::*f)(A) const) {
return const_mem_fun1_t<S,T,A>(f);
}
template <class S, class T, class A>
inline mem_fun1_ref_t<S,T,A> mem_fun1_ref(S (T::*f)(A)) {
return mem_fun1_ref_t<S,T,A>(f);
}
template <class S, class T, class A>
inline const_mem_fun1_ref_t<S,T,A> mem_fun1_ref(S (T::*f)(A) const) {
return const_mem_fun1_ref_t<S,T,A>(f);
}
#endif /* __STL_USE_NAMESPACES */
#endif /* __SGI_STL_FUNCTION_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -27,293 +27,22 @@
#ifndef __SGI_STL_HASH_MAP_H
#define __SGI_STL_HASH_MAP_H
#ifndef __SGI_STL_HASHTABLE_H
#include <hashtable.h>
#endif /* __SGI_STL_HASHTABLE_H */
#ifndef __SGI_STL_INTERNAL_HASHTABLE_H
#include <stl_hashtable.h>
#endif
#include <stl_hash_map.h>
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class Key, class T, class HashFcn = hash<Key>,
class EqualKey = equal_to<Key>,
class Alloc = alloc>
#else
template <class Key, class T, class HashFcn, class EqualKey,
class Alloc = alloc>
#endif
class hash_map
{
private:
typedef hashtable<pair<const Key, T>, Key, HashFcn,
select1st<pair<const Key, T> >, EqualKey, Alloc> ht;
ht rep;
#ifdef __STL_USE_NAMESPACES
using __STD::hash;
using __STD::hashtable;
using __STD::hash_map;
using __STD::hash_multimap;
#endif /* __STL_USE_NAMESPACES */
public:
typedef ht::key_type key_type;
typedef ht::value_type value_type;
typedef ht::hasher hasher;
typedef ht::key_equal key_equal;
typedef T data_type;
typedef ht::size_type size_type;
typedef ht::difference_type difference_type;
typedef ht::pointer pointer;
typedef ht::const_pointer const_pointer;
typedef ht::reference reference;
typedef ht::const_reference const_reference;
typedef ht::iterator iterator;
typedef ht::const_iterator const_iterator;
hasher hash_funct() const { return rep.hash_funct(); }
key_equal key_eq() const { return rep.key_eq(); }
public:
hash_map() : rep(100, hasher(), key_equal()) {}
explicit hash_map(size_type n) : rep(n, hasher(), key_equal()) {}
hash_map(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
hash_map(size_type n, const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) {}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
hash_map(InputIterator f, InputIterator l)
: rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
template <class InputIterator>
hash_map(InputIterator f, InputIterator l, size_type n)
: rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
template <class InputIterator>
hash_map(InputIterator f, InputIterator l, size_type n,
const hasher& hf)
: rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
template <class InputIterator>
hash_map(InputIterator f, InputIterator l, size_type n,
const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) { rep.insert_unique(f, l); }
#else
hash_map(const value_type* f, const value_type* l)
: rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
hash_map(const value_type* f, const value_type* l, size_type n)
: rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
hash_map(const value_type* f, const value_type* l, size_type n,
const hasher& hf)
: rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
hash_map(const value_type* f, const value_type* l, size_type n,
const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) { rep.insert_unique(f, l); }
hash_map(const_iterator f, const_iterator l)
: rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
hash_map(const_iterator f, const_iterator l, size_type n)
: rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
hash_map(const_iterator f, const_iterator l, size_type n,
const hasher& hf)
: rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
hash_map(const_iterator f, const_iterator l, size_type n,
const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) { rep.insert_unique(f, l); }
#endif /*__STL_MEMBER_TEMPLATES */
public:
size_type size() const { return rep.size(); }
size_type max_size() const { return rep.max_size(); }
bool empty() const { return rep.empty(); }
void swap(hash_map& hs) { rep.swap(hs.rep); }
friend bool operator==(const hash_map<Key,T,HashFcn,EqualKey,Alloc>&,
const hash_map<Key,T,HashFcn,EqualKey,Alloc>&);
iterator begin() { return rep.begin(); }
iterator end() { return rep.end(); }
const_iterator begin() const { return rep.begin(); }
const_iterator end() const { return rep.end(); }
public:
pair<iterator, bool> insert(const value_type& obj)
{ return rep.insert_unique(obj); }
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); }
#else
void insert(const value_type* f, const value_type* l) {
rep.insert_unique(f,l);
}
void insert(const_iterator f, const_iterator l) { rep.insert_unique(f, l); }
#endif /*__STL_MEMBER_TEMPLATES */
pair<iterator, bool> insert_noresize(const value_type& obj)
{ return rep.insert_unique_noresize(obj); }
iterator find(const key_type& key) { return rep.find(key); }
const_iterator find(const key_type& key) const { return rep.find(key); }
T& operator[](const key_type& key)
{
return rep.find_or_insert(value_type(key, T())).second;
}
size_type count(const key_type& key) const { return rep.count(key); }
pair<iterator, iterator> equal_range(const key_type& key)
{ return rep.equal_range(key); }
pair<const_iterator, const_iterator> equal_range(const key_type& key) const
{ return rep.equal_range(key); }
size_type erase(const key_type& key) {return rep.erase(key); }
void erase(iterator it) { rep.erase(it); }
void erase(iterator f, iterator l) { rep.erase(f, l); }
void clear() { rep.clear(); }
public:
void resize(size_type hint) { rep.resize(hint); }
size_type bucket_count() const { return rep.bucket_count(); }
size_type max_bucket_count() const { return rep.max_bucket_count(); }
size_type elems_in_bucket(size_type n) const
{ return rep.elems_in_bucket(n); }
};
template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
inline bool operator==(const hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1,
const hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2)
{
return hm1.rep == hm2.rep;
}
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class Key, class T, class HashFcn = hash<Key>,
class EqualKey = equal_to<Key>,
class Alloc = alloc>
#else
template <class Key, class T, class HashFcn, class EqualKey,
class Alloc = alloc>
#endif
class hash_multimap
{
private:
typedef hashtable<pair<const Key, T>, Key, HashFcn,
select1st<pair<const Key, T> >, EqualKey, Alloc> ht;
ht rep;
public:
typedef ht::key_type key_type;
typedef ht::value_type value_type;
typedef ht::hasher hasher;
typedef ht::key_equal key_equal;
typedef T data_type;
typedef ht::size_type size_type;
typedef ht::difference_type difference_type;
typedef ht::pointer pointer;
typedef ht::const_pointer const_pointer;
typedef ht::reference reference;
typedef ht::const_reference const_reference;
typedef ht::iterator iterator;
typedef ht::const_iterator const_iterator;
hasher hash_funct() const { return rep.hash_funct(); }
key_equal key_eq() const { return rep.key_eq(); }
public:
hash_multimap() : rep(100, hasher(), key_equal()) {}
explicit hash_multimap(size_type n) : rep(n, hasher(), key_equal()) {}
hash_multimap(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
hash_multimap(size_type n, const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) {}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
hash_multimap(InputIterator f, InputIterator l)
: rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
template <class InputIterator>
hash_multimap(InputIterator f, InputIterator l, size_type n)
: rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
template <class InputIterator>
hash_multimap(InputIterator f, InputIterator l, size_type n,
const hasher& hf)
: rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
template <class InputIterator>
hash_multimap(InputIterator f, InputIterator l, size_type n,
const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) { rep.insert_equal(f, l); }
#else
hash_multimap(const value_type* f, const value_type* l)
: rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
hash_multimap(const value_type* f, const value_type* l, size_type n)
: rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
hash_multimap(const value_type* f, const value_type* l, size_type n,
const hasher& hf)
: rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
hash_multimap(const value_type* f, const value_type* l, size_type n,
const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) { rep.insert_equal(f, l); }
hash_multimap(const_iterator f, const_iterator l)
: rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
hash_multimap(const_iterator f, const_iterator l, size_type n)
: rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
hash_multimap(const_iterator f, const_iterator l, size_type n,
const hasher& hf)
: rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
hash_multimap(const_iterator f, const_iterator l, size_type n,
const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) { rep.insert_equal(f, l); }
#endif /*__STL_MEMBER_TEMPLATES */
public:
size_type size() const { return rep.size(); }
size_type max_size() const { return rep.max_size(); }
bool empty() const { return rep.empty(); }
void swap(hash_multimap& hs) { rep.swap(hs.rep); }
friend bool operator==(const hash_multimap<Key,T,HashFcn,EqualKey,Alloc>&,
const hash_multimap<Key,T,HashFcn,EqualKey,Alloc>&);
iterator begin() { return rep.begin(); }
iterator end() { return rep.end(); }
const_iterator begin() const { return rep.begin(); }
const_iterator end() const { return rep.end(); }
public:
iterator insert(const value_type& obj) { return rep.insert_equal(obj); }
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); }
#else
void insert(const value_type* f, const value_type* l) {
rep.insert_equal(f,l);
}
void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); }
#endif /*__STL_MEMBER_TEMPLATES */
iterator insert_noresize(const value_type& obj)
{ return rep.insert_equal_noresize(obj); }
iterator find(const key_type& key) { return rep.find(key); }
const_iterator find(const key_type& key) const { return rep.find(key); }
size_type count(const key_type& key) const { return rep.count(key); }
pair<iterator, iterator> equal_range(const key_type& key)
{ return rep.equal_range(key); }
pair<const_iterator, const_iterator> equal_range(const key_type& key) const
{ return rep.equal_range(key); }
size_type erase(const key_type& key) {return rep.erase(key); }
void erase(iterator it) { rep.erase(it); }
void erase(iterator f, iterator l) { rep.erase(f, l); }
void clear() { rep.clear(); }
public:
void resize(size_type hint) { rep.resize(hint); }
size_type bucket_count() const { return rep.bucket_count(); }
size_type max_bucket_count() const { return rep.max_bucket_count(); }
size_type elems_in_bucket(size_type n) const
{ return rep.elems_in_bucket(n); }
};
template <class Key, class T, class HF, class EqKey, class Alloc>
inline bool operator==(const hash_multimap<Key, T, HF, EqKey, Alloc>& hm1,
const hash_multimap<Key, T, HF, EqKey, Alloc>& hm2)
{
return hm1.rep == hm2.rep;
}
#endif /* __SGI_STL_HASH_MAP_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -27,280 +27,17 @@
#ifndef __SGI_STL_HASH_SET_H
#define __SGI_STL_HASH_SET_H
#ifndef __SGI_STL_HASHTABLE_H
#include <hashtable.h>
#endif /* __SGI_STL_HASHTABLE_H */
#ifndef __SGI_STL_INTERNAL_HASHTABLE_H
#include <stl_hashtable.h>
#endif
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class Value, class HashFcn = hash<Value>,
class EqualKey = equal_to<Value>,
class Alloc = alloc>
#else
template <class Value, class HashFcn, class EqualKey, class Alloc = alloc>
#endif
class hash_set
{
private:
typedef hashtable<Value, Value, HashFcn, identity<Value>,
EqualKey, Alloc> ht;
ht rep;
public:
typedef ht::key_type key_type;
typedef ht::value_type value_type;
typedef ht::hasher hasher;
typedef ht::key_equal key_equal;
typedef ht::size_type size_type;
typedef ht::difference_type difference_type;
typedef ht::const_pointer pointer;
typedef ht::const_pointer const_pointer;
typedef ht::const_reference reference;
typedef ht::const_reference const_reference;
typedef ht::const_iterator iterator;
typedef ht::const_iterator const_iterator;
hasher hash_funct() const { return rep.hash_funct(); }
key_equal key_eq() const { return rep.key_eq(); }
public:
hash_set() : rep(100, hasher(), key_equal()) {}
explicit hash_set(size_type n) : rep(n, hasher(), key_equal()) {}
hash_set(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
hash_set(size_type n, const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) {}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
hash_set(InputIterator f, InputIterator l)
: rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
template <class InputIterator>
hash_set(InputIterator f, InputIterator l, size_type n)
: rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
template <class InputIterator>
hash_set(InputIterator f, InputIterator l, size_type n,
const hasher& hf)
: rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
template <class InputIterator>
hash_set(InputIterator f, InputIterator l, size_type n,
const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) { rep.insert_unique(f, l); }
#else
hash_set(const value_type* f, const value_type* l)
: rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
hash_set(const value_type* f, const value_type* l, size_type n)
: rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
hash_set(const value_type* f, const value_type* l, size_type n,
const hasher& hf)
: rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
hash_set(const value_type* f, const value_type* l, size_type n,
const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) { rep.insert_unique(f, l); }
hash_set(const_iterator f, const_iterator l)
: rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
hash_set(const_iterator f, const_iterator l, size_type n)
: rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
hash_set(const_iterator f, const_iterator l, size_type n,
const hasher& hf)
: rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
hash_set(const_iterator f, const_iterator l, size_type n,
const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) { rep.insert_unique(f, l); }
#endif /*__STL_MEMBER_TEMPLATES */
public:
size_type size() const { return rep.size(); }
size_type max_size() const { return rep.max_size(); }
bool empty() const { return rep.empty(); }
void swap(hash_set& hs) { rep.swap(hs.rep); }
friend bool operator==(const hash_set<Value,HashFcn,EqualKey,Alloc>&,
const hash_set<Value,HashFcn,EqualKey,Alloc>&);
iterator begin() const { return rep.begin(); }
iterator end() const { return rep.end(); }
public:
pair<iterator, bool> insert(const value_type& obj)
{
pair<ht::iterator, bool> p = rep.insert_unique(obj);
return pair<iterator, bool>(p.first, p.second);
}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); }
#else
void insert(const value_type* f, const value_type* l) {
rep.insert_unique(f,l);
}
void insert(const_iterator f, const_iterator l) {rep.insert_unique(f, l); }
#endif /*__STL_MEMBER_TEMPLATES */
pair<iterator, bool> insert_noresize(const value_type& obj)
{
pair<ht::iterator, bool> p = rep.insert_unique_noresize(obj);
return pair<iterator, bool>(p.first, p.second);
}
iterator find(const key_type& key) const { return rep.find(key); }
size_type count(const key_type& key) const { return rep.count(key); }
pair<iterator, iterator> equal_range(const key_type& key) const
{ return rep.equal_range(key); }
size_type erase(const key_type& key) {return rep.erase(key); }
void erase(iterator it) { rep.erase(it); }
void erase(iterator f, iterator l) { rep.erase(f, l); }
void clear() { rep.clear(); }
public:
void resize(size_type hint) { rep.resize(hint); }
size_type bucket_count() const { return rep.bucket_count(); }
size_type max_bucket_count() const { return rep.max_bucket_count(); }
size_type elems_in_bucket(size_type n) const
{ return rep.elems_in_bucket(n); }
};
template <class Value, class HashFcn, class EqualKey, class Alloc>
inline bool operator==(const hash_set<Value, HashFcn, EqualKey, Alloc>& hs1,
const hash_set<Value, HashFcn, EqualKey, Alloc>& hs2)
{
return hs1.rep == hs2.rep;
}
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class Value, class HashFcn = hash<Value>,
class EqualKey = equal_to<Value>,
class Alloc = alloc>
#else
template <class Value, class HashFcn, class EqualKey, class Alloc = alloc>
#endif
class hash_multiset
{
private:
typedef hashtable<Value, Value, HashFcn, identity<Value>,
EqualKey, Alloc> ht;
ht rep;
public:
typedef ht::key_type key_type;
typedef ht::value_type value_type;
typedef ht::hasher hasher;
typedef ht::key_equal key_equal;
typedef ht::size_type size_type;
typedef ht::difference_type difference_type;
typedef ht::const_pointer pointer;
typedef ht::const_pointer const_pointer;
typedef ht::const_reference reference;
typedef ht::const_reference const_reference;
typedef ht::const_iterator iterator;
typedef ht::const_iterator const_iterator;
hasher hash_funct() const { return rep.hash_funct(); }
key_equal key_eq() const { return rep.key_eq(); }
public:
hash_multiset() : rep(100, hasher(), key_equal()) {}
explicit hash_multiset(size_type n) : rep(n, hasher(), key_equal()) {}
hash_multiset(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
hash_multiset(size_type n, const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) {}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
hash_multiset(InputIterator f, InputIterator l)
: rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
template <class InputIterator>
hash_multiset(InputIterator f, InputIterator l, size_type n)
: rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
template <class InputIterator>
hash_multiset(InputIterator f, InputIterator l, size_type n,
const hasher& hf)
: rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
template <class InputIterator>
hash_multiset(InputIterator f, InputIterator l, size_type n,
const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) { rep.insert_equal(f, l); }
#else
hash_multiset(const value_type* f, const value_type* l)
: rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
hash_multiset(const value_type* f, const value_type* l, size_type n)
: rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
hash_multiset(const value_type* f, const value_type* l, size_type n,
const hasher& hf)
: rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
hash_multiset(const value_type* f, const value_type* l, size_type n,
const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) { rep.insert_equal(f, l); }
hash_multiset(const_iterator f, const_iterator l)
: rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
hash_multiset(const_iterator f, const_iterator l, size_type n)
: rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
hash_multiset(const_iterator f, const_iterator l, size_type n,
const hasher& hf)
: rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
hash_multiset(const_iterator f, const_iterator l, size_type n,
const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) { rep.insert_equal(f, l); }
#endif /*__STL_MEMBER_TEMPLATES */
public:
size_type size() const { return rep.size(); }
size_type max_size() const { return rep.max_size(); }
bool empty() const { return rep.empty(); }
void swap(hash_multiset& hs) { rep.swap(hs.rep); }
friend bool operator==(const hash_multiset<Value,HashFcn,EqualKey,Alloc>&,
const hash_multiset<Value,HashFcn,EqualKey,Alloc>&);
iterator begin() const { return rep.begin(); }
iterator end() const { return rep.end(); }
public:
iterator insert(const value_type& obj) { return rep.insert_equal(obj); }
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); }
#else
void insert(const value_type* f, const value_type* l) {
rep.insert_equal(f,l);
}
void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); }
#endif /*__STL_MEMBER_TEMPLATES */
iterator insert_noresize(const value_type& obj)
{ return rep.insert_equal_noresize(obj); }
iterator find(const key_type& key) const { return rep.find(key); }
size_type count(const key_type& key) const { return rep.count(key); }
pair<iterator, iterator> equal_range(const key_type& key) const
{ return rep.equal_range(key); }
size_type erase(const key_type& key) {return rep.erase(key); }
void erase(iterator it) { rep.erase(it); }
void erase(iterator f, iterator l) { rep.erase(f, l); }
void clear() { rep.clear(); }
public:
void resize(size_type hint) { rep.resize(hint); }
size_type bucket_count() const { return rep.bucket_count(); }
size_type max_bucket_count() const { return rep.max_bucket_count(); }
size_type elems_in_bucket(size_type n) const
{ return rep.elems_in_bucket(n); }
};
template <class Val, class HashFcn, class EqualKey, class Alloc>
inline bool operator==(const hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs1,
const hash_multiset<Val, HashFcn, EqualKey, Alloc>& hs2)
{
return hs1.rep == hs2.rep;
}
#include <stl_hash_set.h>
#ifdef __STL_USE_NAMESPACES
using __STD::hash;
using __STD::hashtable;
using __STD::hash_set;
using __STD::hash_multiset;
#endif /* __STL_USE_NAMESPACES */
#endif /* __SGI_STL_HASH_SET_H */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1996
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
@@ -24,969 +24,25 @@
*
*/
/* NOTE: This is an internal header file, included by other STL headers.
* You should not attempt to use it directly.
*/
#ifndef __SGI_STL_HASHTABLE_H
#define __SGI_STL_HASHTABLE_H
// Hashtable class, used to implement the hashed associative containers
// hash_set, hash_map, hash_multiset, and hash_multimap.
#include <stdlib.h>
#include <stddef.h>
#include <stl_hashtable.h>
#include <algo.h>
#include <alloc.h>
#include <vector.h>
template <class Key> struct hash { };
inline size_t __stl_hash_string(const char* s)
{
unsigned long h = 0;
for ( ; *s; ++s)
h = 5*h + *s;
return size_t(h);
}
struct hash<char*>
{
size_t operator()(const char* s) const { return __stl_hash_string(s); }
};
struct hash<const char*>
{
size_t operator()(const char* s) const { return __stl_hash_string(s); }
};
struct hash<char> {
size_t operator()(char x) const { return x; }
};
struct hash<unsigned char> {
size_t operator()(unsigned char x) const { return x; }
};
struct hash<signed char> {
size_t operator()(unsigned char x) const { return x; }
};
struct hash<short> {
size_t operator()(short x) const { return x; }
};
struct hash<unsigned short> {
size_t operator()(unsigned short x) const { return x; }
};
struct hash<int> {
size_t operator()(int x) const { return x; }
};
struct hash<unsigned int> {
size_t operator()(unsigned int x) const { return x; }
};
struct hash<long> {
size_t operator()(long x) const { return x; }
};
struct hash<unsigned long> {
size_t operator()(unsigned long x) const { return x; }
};
template <class Value>
struct __hashtable_node
{
__hashtable_node* next;
Value val;
};
template <class Value, class Key, class HashFcn,
class ExtractKey, class EqualKey, class Alloc = alloc>
class hashtable;
template <class Value, class Key, class HashFcn,
class ExtractKey, class EqualKey, class Alloc>
struct __hashtable_iterator;
template <class Value, class Key, class HashFcn,
class ExtractKey, class EqualKey, class Alloc>
struct __hashtable_const_iterator;
template <class Value, class Key, class HashFcn,
class ExtractKey, class EqualKey, class Alloc>
struct __hashtable_iterator {
typedef hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>
hashtable;
typedef __hashtable_iterator<Value, Key, HashFcn,
ExtractKey, EqualKey, Alloc>
iterator;
typedef __hashtable_const_iterator<Value, Key, HashFcn,
ExtractKey, EqualKey, Alloc>
const_iterator;
typedef __hashtable_node<Value> node;
typedef forward_iterator_tag iterator_category;
typedef Value value_type;
typedef ptrdiff_t difference_type;
typedef size_t size_type;
typedef Value& reference;
typedef Value* pointer;
node* cur;
hashtable* ht;
__hashtable_iterator(node* n, hashtable* tab) : cur(n), ht(tab) {}
__hashtable_iterator() {}
reference operator*() const { return cur->val; }
#ifndef __SGI_STL_NO_ARROW_OPERATOR
pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
iterator& operator++();
iterator operator++(int);
bool operator==(const iterator& it) const { return cur == it.cur; }
bool operator!=(const iterator& it) const { return cur != it.cur; }
};
template <class Value, class Key, class HashFcn,
class ExtractKey, class EqualKey, class Alloc>
struct __hashtable_const_iterator {
typedef hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>
hashtable;
typedef __hashtable_iterator<Value, Key, HashFcn,
ExtractKey, EqualKey, Alloc>
iterator;
typedef __hashtable_const_iterator<Value, Key, HashFcn,
ExtractKey, EqualKey, Alloc>
const_iterator;
typedef __hashtable_node<Value> node;
typedef forward_iterator_tag iterator_category;
typedef Value value_type;
typedef ptrdiff_t difference_type;
typedef size_t size_type;
typedef const Value& reference;
typedef const Value* pointer;
const node* cur;
const hashtable* ht;
__hashtable_const_iterator(const node* n, const hashtable* tab)
: cur(n), ht(tab) {}
__hashtable_const_iterator() {}
__hashtable_const_iterator(const iterator& it) : cur(it.cur), ht(it.ht) {}
reference operator*() const { return cur->val; }
#ifndef __SGI_STL_NO_ARROW_OPERATOR
pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
const_iterator& operator++();
const_iterator operator++(int);
bool operator==(const const_iterator& it) const { return cur == it.cur; }
bool operator!=(const const_iterator& it) const { return cur != it.cur; }
};
// Note: assumes long is at least 32 bits.
static const int __stl_num_primes = 28;
static const unsigned long __stl_prime_list[__stl_num_primes] =
{
53, 97, 193, 389, 769,
1543, 3079, 6151, 12289, 24593,
49157, 98317, 196613, 393241, 786433,
1572869, 3145739, 6291469, 12582917, 25165843,
50331653, 100663319, 201326611, 402653189, 805306457,
1610612741, 3221225473, 4294967291
};
inline unsigned long __stl_next_prime(unsigned long n)
{
const unsigned long* first = __stl_prime_list;
const unsigned long* last = __stl_prime_list + __stl_num_primes;
const unsigned long* pos = lower_bound(first, last, n);
return pos == last ? *(last - 1) : *pos;
}
template <class Value, class Key, class HashFcn,
class ExtractKey, class EqualKey,
class Alloc>
class hashtable {
public:
typedef Key key_type;
typedef Value value_type;
typedef HashFcn hasher;
typedef EqualKey key_equal;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
hasher hash_funct() const { return hash; }
key_equal key_eq() const { return equals; }
private:
hasher hash;
key_equal equals;
ExtractKey get_key;
typedef __hashtable_node<Value> node;
typedef simple_alloc<node, Alloc> node_allocator;
vector<node*,Alloc> buckets;
size_type num_elements;
public:
typedef __hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey,
Alloc>
iterator;
typedef __hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey,
Alloc>
const_iterator;
friend struct
__hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>;
friend struct
__hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>;
public:
hashtable(size_type n,
const HashFcn& hf,
const EqualKey& eql,
const ExtractKey& ext)
: hash(hf), equals(eql), get_key(ext), num_elements(0)
{
initialize_buckets(n);
}
hashtable(size_type n,
const HashFcn& hf,
const EqualKey& eql)
: hash(hf), equals(eql), get_key(ExtractKey()), num_elements(0)
{
initialize_buckets(n);
}
hashtable(const hashtable& ht)
: hash(ht.hash), equals(ht.equals), get_key(ht.get_key), num_elements(0)
{
copy_from(ht);
}
hashtable& operator= (const hashtable& ht)
{
if (&ht != this) {
clear();
hash = ht.hash;
equals = ht.equals;
get_key = ht.get_key;
copy_from(ht);
}
return *this;
}
~hashtable() { clear(); }
size_type size() const { return num_elements; }
size_type max_size() const { return size_type(-1); }
bool empty() const { return size() == 0; }
void swap(hashtable& ht)
{
::swap(hash, ht.hash);
::swap(equals, ht.equals);
::swap(get_key, ht.get_key);
buckets.swap(ht.buckets);
::swap(num_elements, ht.num_elements);
}
iterator begin()
{
for (size_type n = 0; n < buckets.size(); ++n)
if (buckets[n])
return iterator(buckets[n], this);
return end();
}
iterator end() { return iterator(0, this); }
const_iterator begin() const
{
for (size_type n = 0; n < buckets.size(); ++n)
if (buckets[n])
return const_iterator(buckets[n], this);
return end();
}
const_iterator end() const { return const_iterator(0, this); }
friend bool operator== (const hashtable<Value, Key,
HashFcn, ExtractKey, EqualKey,
Alloc>&,
const hashtable<Value, Key,
HashFcn, ExtractKey, EqualKey,
Alloc>&);
public:
size_type bucket_count() const { return buckets.size(); }
size_type max_bucket_count() const
{ return __stl_prime_list[__stl_num_primes - 1]; }
size_type elems_in_bucket(size_type bucket) const
{
size_type result = 0;
for (node* cur = buckets[bucket]; cur; cur = cur->next)
result += 1;
return result;
}
pair<iterator, bool> insert_unique(const value_type& obj)
{
resize(num_elements + 1);
return insert_unique_noresize(obj);
}
iterator insert_equal(const value_type& obj)
{
resize(num_elements + 1);
return insert_equal_noresize(obj);
}
pair<iterator, bool> insert_unique_noresize(const value_type& obj);
iterator insert_equal_noresize(const value_type& obj);
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void insert_unique(InputIterator f, InputIterator l)
{
insert_unique(f, l, iterator_category(f));
}
template <class InputIterator>
void insert_equal(InputIterator f, InputIterator l)
{
insert_equal(f, l, iterator_category(f));
}
template <class InputIterator>
void insert_unique(InputIterator f, InputIterator l,
input_iterator_tag)
{
for ( ; f != l; ++f)
insert_unique(*f);
}
template <class InputIterator>
void insert_equal(InputIterator f, InputIterator l,
input_iterator_tag)
{
for ( ; f != l; ++f)
insert_equal(*f);
}
template <class ForwardIterator>
void insert_unique(ForwardIterator f, ForwardIterator l,
forward_iterator_tag)
{
size_type n = 0;
distance(f, l, n);
resize(num_elements + n);
for ( ; n > 0; --n, ++f)
insert_unique_noresize(*f);
}
template <class ForwardIterator>
void insert_equal(ForwardIterator f, ForwardIterator l,
forward_iterator_tag)
{
size_type n = 0;
distance(f, l, n);
resize(num_elements + n);
for ( ; n > 0; --n, ++f)
insert_equal_noresize(*f);
}
#else /* __STL_MEMBER_TEMPLATES */
void insert_unique(const value_type* f, const value_type* l)
{
size_type n = l - f;
resize(num_elements + n);
for ( ; n > 0; --n, ++f)
insert_unique_noresize(*f);
}
void insert_equal(const value_type* f, const value_type* l)
{
size_type n = l - f;
resize(num_elements + n);
for ( ; n > 0; --n, ++f)
insert_equal_noresize(*f);
}
void insert_unique(const_iterator f, const_iterator l)
{
size_type n = 0;
distance(f, l, n);
resize(num_elements + n);
for ( ; n > 0; --n, ++f)
insert_unique_noresize(*f);
}
void insert_equal(const_iterator f, const_iterator l)
{
size_type n = 0;
distance(f, l, n);
resize(num_elements + n);
for ( ; n > 0; --n, ++f)
insert_equal_noresize(*f);
}
#endif /*__STL_MEMBER_TEMPLATES */
reference find_or_insert(const value_type& obj);
iterator find(const key_type& key)
{
size_type n = bkt_num_key(key);
node* first;
for ( first = buckets[n];
first && !equals(get_key(first->val), key);
first = first->next)
{}
return iterator(first, this);
}
const_iterator find(const key_type& key) const
{
size_type n = bkt_num_key(key);
const node* first;
for ( first = buckets[n];
first && !equals(get_key(first->val), key);
first = first->next)
{}
return const_iterator(first, this);
}
size_type count(const key_type& key) const
{
const size_type n = bkt_num_key(key);
size_type result = 0;
for (const node* cur = buckets[n]; cur; cur = cur->next)
if (equals(get_key(cur->val), key))
++result;
return result;
}
pair<iterator, iterator> equal_range(const key_type& key);
pair<const_iterator, const_iterator> equal_range(const key_type& key) const;
size_type erase(const key_type& key);
void erase(const iterator& it);
void erase(iterator first, iterator last);
void erase(const const_iterator& it);
void erase(const_iterator first, const_iterator last);
void resize(size_type num_elements_hint);
void clear();
private:
size_type next_size(size_type n) const { return __stl_next_prime(n); }
void initialize_buckets(size_type n)
{
const size_type n_buckets = next_size(n);
buckets.reserve(n_buckets);
buckets.insert(buckets.end(), n_buckets, (node*) 0);
num_elements = 0;
}
size_type bkt_num_key(const key_type& key) const
{
return bkt_num_key(key, buckets.size());
}
size_type bkt_num(const value_type& obj) const
{
return bkt_num_key(get_key(obj));
}
size_type bkt_num_key(const key_type& key, size_t n) const
{
return hash(key) % n;
}
size_type bkt_num(const value_type& obj, size_t n) const
{
return bkt_num_key(get_key(obj), n);
}
node* new_node(const value_type& obj)
{
node* n = node_allocator::allocate();
n->next = 0;
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
construct(&n->val, obj);
return n;
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
node_allocator::deallocate(n);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
void delete_node(node* n)
{
destroy(&n->val);
node_allocator::deallocate(n);
}
void erase_bucket(const size_type n, node* first, node* last);
void erase_bucket(const size_type n, node* last);
void copy_from(const hashtable& ht);
};
template <class V, class K, class HF, class ExK, class EqK, class A>
__hashtable_iterator<V, K, HF, ExK, EqK, A>&
__hashtable_iterator<V, K, HF, ExK, EqK, A>::operator++()
{
const node* old = cur;
cur = cur->next;
if (!cur) {
size_type bucket = ht->bkt_num(old->val);
while (!cur && ++bucket < ht->buckets.size())
cur = ht->buckets[bucket];
}
return *this;
}
template <class V, class K, class HF, class ExK, class EqK, class A>
inline __hashtable_iterator<V, K, HF, ExK, EqK, A>
__hashtable_iterator<V, K, HF, ExK, EqK, A>::operator++(int)
{
iterator tmp = *this;
++*this;
return tmp;
}
template <class V, class K, class HF, class ExK, class EqK, class A>
__hashtable_const_iterator<V, K, HF, ExK, EqK, A>&
__hashtable_const_iterator<V, K, HF, ExK, EqK, A>::operator++()
{
const node* old = cur;
cur = cur->next;
if (!cur) {
size_type bucket = ht->bkt_num(old->val);
while (!cur && ++bucket < ht->buckets.size())
cur = ht->buckets[bucket];
}
return *this;
}
template <class V, class K, class HF, class ExK, class EqK, class A>
inline __hashtable_const_iterator<V, K, HF, ExK, EqK, A>
__hashtable_const_iterator<V, K, HF, ExK, EqK, A>::operator++(int)
{
const_iterator tmp = *this;
++*this;
return tmp;
}
#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
template <class V, class K, class HF, class ExK, class EqK, class All>
inline forward_iterator_tag
iterator_category(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&)
{
return forward_iterator_tag();
}
template <class V, class K, class HF, class ExK, class EqK, class All>
inline V* value_type(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&)
{
return (V*) 0;
}
template <class V, class K, class HF, class ExK, class EqK, class All>
inline hashtable<V, K, HF, ExK, EqK, All>::difference_type*
distance_type(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&)
{
return (hashtable<V, K, HF, ExK, EqK, All>::difference_type*) 0;
}
template <class V, class K, class HF, class ExK, class EqK, class All>
inline forward_iterator_tag
iterator_category(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&)
{
return forward_iterator_tag();
}
template <class V, class K, class HF, class ExK, class EqK, class All>
inline V*
value_type(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&)
{
return (V*) 0;
}
template <class V, class K, class HF, class ExK, class EqK, class All>
inline hashtable<V, K, HF, ExK, EqK, All>::difference_type*
distance_type(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&)
{
return (hashtable<V, K, HF, ExK, EqK, All>::difference_type*) 0;
}
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
template <class V, class K, class HF, class Ex, class Eq, class A>
bool operator==(const hashtable<V, K, HF, Ex, Eq, A>& ht1,
const hashtable<V, K, HF, Ex, Eq, A>& ht2)
{
typedef hashtable<V, K, HF, Ex, Eq, A>::node node;
if (ht1.buckets.size() != ht2.buckets.size())
return false;
for (int n = 0; n < ht1.buckets.size(); ++n) {
node* cur1 = ht1.buckets[n];
node* cur2 = ht2.buckets[n];
for ( ; cur1 && cur2 && cur1->val == cur2->val;
cur1 = cur1->next, cur2 = cur2->next)
{}
if (cur1 || cur2)
return false;
}
return true;
}
template <class V, class K, class HF, class Ex, class Eq, class A>
pair<hashtable<V, K, HF, Ex, Eq, A>::iterator, bool>
hashtable<V, K, HF, Ex, Eq, A>::insert_unique_noresize(const value_type& obj)
{
const size_type n = bkt_num(obj);
node* first = buckets[n];
for (node* cur = first; cur; cur = cur->next)
if (equals(get_key(cur->val), get_key(obj)))
return pair<iterator, bool>(iterator(cur, this), false);
node* tmp = new_node(obj);
tmp->next = first;
buckets[n] = tmp;
++num_elements;
return pair<iterator, bool>(iterator(tmp, this), true);
}
template <class V, class K, class HF, class Ex, class Eq, class A>
hashtable<V, K, HF, Ex, Eq, A>::iterator
hashtable<V, K, HF, Ex, Eq, A>::insert_equal_noresize(const value_type& obj)
{
const size_type n = bkt_num(obj);
node* first = buckets[n];
for (node* cur = first; cur; cur = cur->next)
if (equals(get_key(cur->val), get_key(obj))) {
node* tmp = new_node(obj);
tmp->next = cur->next;
cur->next = tmp;
++num_elements;
return iterator(tmp, this);
}
node* tmp = new_node(obj);
tmp->next = first;
buckets[n] = tmp;
++num_elements;
return iterator(tmp, this);
}
template <class V, class K, class HF, class Ex, class Eq, class A>
hashtable<V, K, HF, Ex, Eq, A>::reference
hashtable<V, K, HF, Ex, Eq, A>::find_or_insert(const value_type& obj)
{
resize(num_elements + 1);
size_type n = bkt_num(obj);
node* first = buckets[n];
for (node* cur = first; cur; cur = cur->next)
if (equals(get_key(cur->val), get_key(obj)))
return cur->val;
node* tmp = new_node(obj);
tmp->next = first;
buckets[n] = tmp;
++num_elements;
return tmp->val;
}
template <class V, class K, class HF, class Ex, class Eq, class A>
pair<hashtable<V, K, HF, Ex, Eq, A>::iterator,
hashtable<V, K, HF, Ex, Eq, A>::iterator>
hashtable<V, K, HF, Ex, Eq, A>::equal_range(const key_type& key)
{
typedef pair<iterator, iterator> pii;
const size_type n = bkt_num_key(key);
for (node* first = buckets[n]; first; first = first->next) {
if (equals(get_key(first->val), key)) {
for (node* cur = first->next; cur; cur = cur->next)
if (!equals(get_key(cur->val), key))
return pii(iterator(first, this), iterator(cur, this));
for (size_type m = n + 1; m < buckets.size(); ++m)
if (buckets[m])
return pii(iterator(first, this),
iterator(buckets[m], this));
return pii(iterator(first, this), end());
}
}
return pii(end(), end());
}
template <class V, class K, class HF, class Ex, class Eq, class A>
pair<hashtable<V, K, HF, Ex, Eq, A>::const_iterator,
hashtable<V, K, HF, Ex, Eq, A>::const_iterator>
hashtable<V, K, HF, Ex, Eq, A>::equal_range(const key_type& key) const
{
typedef pair<const_iterator, const_iterator> pii;
const size_type n = bkt_num_key(key);
for (const node* first = buckets[n] ; first; first = first->next) {
if (equals(get_key(first->val), key)) {
for (const node* cur = first->next; cur; cur = cur->next)
if (!equals(get_key(cur->val), key))
return pii(const_iterator(first, this),
const_iterator(cur, this));
for (size_type m = n + 1; m < buckets.size(); ++m)
if (buckets[m])
return pii(const_iterator(first, this),
const_iterator(buckets[m], this));
return pii(const_iterator(first, this), end());
}
}
return pii(end(), end());
}
template <class V, class K, class HF, class Ex, class Eq, class A>
hashtable<V, K, HF, Ex, Eq, A>::size_type
hashtable<V, K, HF, Ex, Eq, A>::erase(const key_type& key)
{
const size_type n = bkt_num_key(key);
node* first = buckets[n];
size_type erased = 0;
if (first) {
node* cur = first;
node* next = cur->next;
while (next) {
if (equals(get_key(next->val), key)) {
cur->next = next->next;
delete_node(next);
next = cur->next;
++erased;
--num_elements;
}
else {
cur = next;
next = cur->next;
}
}
if (equals(get_key(first->val), key)) {
buckets[n] = first->next;
delete_node(first);
++erased;
--num_elements;
}
}
return erased;
}
template <class V, class K, class HF, class Ex, class Eq, class A>
void hashtable<V, K, HF, Ex, Eq, A>::erase(const iterator& it)
{
if (node* const p = it.cur) {
const size_type n = bkt_num(p->val);
node* cur = buckets[n];
if (cur == p) {
buckets[n] = cur->next;
delete_node(cur);
--num_elements;
}
else {
node* next = cur->next;
while (next) {
if (next == p) {
cur->next = next->next;
delete_node(next);
--num_elements;
break;
}
else {
cur = next;
next = cur->next;
}
}
}
}
}
template <class V, class K, class HF, class Ex, class Eq, class A>
void hashtable<V, K, HF, Ex, Eq, A>::erase(iterator first, iterator last)
{
size_type f_bucket = first.cur ? bkt_num(first.cur->val) : buckets.size();
size_type l_bucket = last.cur ? bkt_num(last.cur->val) : buckets.size();
if (first.cur == last.cur)
return;
else if (f_bucket == l_bucket)
erase_bucket(f_bucket, first.cur, last.cur);
else {
erase_bucket(f_bucket, first.cur, 0);
for (size_type n = f_bucket + 1; n < l_bucket; ++n)
erase_bucket(n, 0);
if (l_bucket != buckets.size())
erase_bucket(l_bucket, last.cur);
}
}
template <class V, class K, class HF, class Ex, class Eq, class A>
inline void
hashtable<V, K, HF, Ex, Eq, A>::erase(const_iterator first,
const_iterator last)
{
erase(iterator(const_cast<hashtable::node*>(first.cur),
const_cast<hashtable*>(first.ht)),
iterator(const_cast<hashtable::node*>(last.cur),
const_cast<hashtable*>(last.ht)));
}
template <class V, class K, class HF, class Ex, class Eq, class A>
inline void
hashtable<V, K, HF, Ex, Eq, A>::erase(const const_iterator& it)
{
erase(iterator(const_cast<hashtable::node*>(it.cur),
const_cast<hashtable*>(it.ht)));
}
template <class V, class K, class HF, class Ex, class Eq, class A>
void hashtable<V, K, HF, Ex, Eq, A>::resize(size_type num_elements_hint)
{
const size_type old_n = buckets.size();
if (num_elements_hint > old_n) {
const size_type n = next_size(num_elements_hint);
if (n > old_n) {
vector<node*, A> tmp(n, (node*) 0);
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
for (size_type bucket = 0; bucket < old_n; ++bucket) {
node* first = buckets[bucket];
while (first) {
size_type new_bucket = bkt_num(first->val, n);
buckets[bucket] = first->next;
first->next = tmp[new_bucket];
tmp[new_bucket] = first;
first = buckets[bucket];
}
}
buckets.swap(tmp);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
for (size_type bucket = 0; bucket < tmp.size(); ++bucket) {
while (tmp[bucket]) {
node* next = tmp[bucket]->next;
delete_node(tmp[bucket]);
tmp[bucket] = next;
}
}
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
}
}
template <class V, class K, class HF, class Ex, class Eq, class A>
void hashtable<V, K, HF, Ex, Eq, A>::erase_bucket(const size_type n,
node* first, node* last)
{
node* cur = buckets[n];
if (cur == first)
erase_bucket(n, last);
else {
node* next;
for (next = cur->next; next != first; cur = next, next = cur->next)
;
while (next) {
cur->next = next->next;
delete_node(next);
next = cur->next;
--num_elements;
}
}
}
template <class V, class K, class HF, class Ex, class Eq, class A>
void
hashtable<V, K, HF, Ex, Eq, A>::erase_bucket(const size_type n, node* last)
{
node* cur = buckets[n];
while (cur != last) {
node* next = cur->next;
delete_node(cur);
cur = next;
buckets[n] = cur;
--num_elements;
}
}
template <class V, class K, class HF, class Ex, class Eq, class A>
void hashtable<V, K, HF, Ex, Eq, A>::clear()
{
for (size_type i = 0; i < buckets.size(); ++i) {
node* cur = buckets[i];
while (cur != 0) {
node* next = cur->next;
delete_node(cur);
cur = next;
}
buckets[i] = 0;
}
num_elements = 0;
}
template <class V, class K, class HF, class Ex, class Eq, class A>
void hashtable<V, K, HF, Ex, Eq, A>::copy_from(const hashtable& ht)
{
buckets.clear();
buckets.reserve(ht.buckets.size());
buckets.insert(buckets.end(), ht.buckets.size(), (node*) 0);
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
for (size_type i = 0; i < ht.buckets.size(); ++i) {
if (const node* cur = ht.buckets[i]) {
node* copy = new_node(cur->val);
buckets[i] = copy;
for (node* next = cur->next; next; cur = next, next = cur->next) {
copy->next = new_node(next->val);
copy = copy->next;
}
}
}
num_elements = ht.num_elements;
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
clear();
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
#ifdef __STL_USE_NAMESPACES
using __STD::hash;
using __STD::hashtable;
#endif /* __STL_USE_NAMESPACES */
#endif /* __SGI_STL_HASHTABLE_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -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
#include <stl_config.h>
#include <stl_heap.h>
template <class RandomAccessIterator, class Distance, class T>
void __push_heap(RandomAccessIterator first, Distance holeIndex,
Distance topIndex, T value) {
Distance parent = (holeIndex - 1) / 2;
while (holeIndex > topIndex && *(first + parent) < value) {
*(first + holeIndex) = *(first + parent);
holeIndex = parent;
parent = (holeIndex - 1) / 2;
}
*(first + holeIndex) = value;
}
#ifdef __STL_USE_NAMESPACES
template <class RandomAccessIterator, class Distance, class T>
inline void __push_heap_aux(RandomAccessIterator first,
RandomAccessIterator last, Distance*, T*) {
__push_heap(first, Distance((last - first) - 1), Distance(0),
T(*(last - 1)));
}
using __STD::push_heap;
using __STD::pop_heap;
using __STD::make_heap;
using __STD::sort_heap;
template <class RandomAccessIterator>
inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) {
__push_heap_aux(first, last, distance_type(first), value_type(first));
}
#endif /* __STL_USE_NAMESPACES */
template <class RandomAccessIterator, class Distance, class T, class Compare>
void __push_heap(RandomAccessIterator first, Distance holeIndex,
Distance topIndex, T value, Compare comp) {
Distance parent = (holeIndex - 1) / 2;
while (holeIndex > topIndex && comp(*(first + parent), value)) {
*(first + holeIndex) = *(first + parent);
holeIndex = parent;
parent = (holeIndex - 1) / 2;
}
*(first + holeIndex) = value;
}
template <class RandomAccessIterator, class Compare, class Distance, class T>
inline void __push_heap_aux(RandomAccessIterator first,
RandomAccessIterator last, Compare comp,
Distance*, T*) {
__push_heap(first, Distance((last - first) - 1), Distance(0),
T(*(last - 1)), comp);
}
template <class RandomAccessIterator, class Compare>
inline void push_heap(RandomAccessIterator first, RandomAccessIterator last,
Compare comp) {
__push_heap_aux(first, last, comp, distance_type(first), value_type(first));
}
template <class RandomAccessIterator, class Distance, class T>
void __adjust_heap(RandomAccessIterator first, Distance holeIndex,
Distance len, T value) {
Distance topIndex = holeIndex;
Distance secondChild = 2 * holeIndex + 2;
while (secondChild < len) {
if (*(first + secondChild) < *(first + (secondChild - 1)))
secondChild--;
*(first + holeIndex) = *(first + secondChild);
holeIndex = secondChild;
secondChild = 2 * (secondChild + 1);
}
if (secondChild == len) {
*(first + holeIndex) = *(first + (secondChild - 1));
holeIndex = secondChild - 1;
}
__push_heap(first, holeIndex, topIndex, value);
}
template <class RandomAccessIterator, class T, class Distance>
inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last,
RandomAccessIterator result, T value, Distance*) {
*result = *first;
__adjust_heap(first, Distance(0), Distance(last - first), value);
}
template <class RandomAccessIterator, class T>
inline void __pop_heap_aux(RandomAccessIterator first,
RandomAccessIterator last, T*) {
__pop_heap(first, last - 1, last - 1, T(*(last - 1)), distance_type(first));
}
template <class RandomAccessIterator>
inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last) {
__pop_heap_aux(first, last, value_type(first));
}
template <class RandomAccessIterator, class Distance, class T, class Compare>
void __adjust_heap(RandomAccessIterator first, Distance holeIndex,
Distance len, T value, Compare comp) {
Distance topIndex = holeIndex;
Distance secondChild = 2 * holeIndex + 2;
while (secondChild < len) {
if (comp(*(first + secondChild), *(first + (secondChild - 1))))
secondChild--;
*(first + holeIndex) = *(first + secondChild);
holeIndex = secondChild;
secondChild = 2 * (secondChild + 1);
}
if (secondChild == len) {
*(first + holeIndex) = *(first + (secondChild - 1));
holeIndex = secondChild - 1;
}
__push_heap(first, holeIndex, topIndex, value, comp);
}
template <class RandomAccessIterator, class T, class Compare, class Distance>
inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last,
RandomAccessIterator result, T value, Compare comp,
Distance*) {
*result = *first;
__adjust_heap(first, Distance(0), Distance(last - first), value, comp);
}
template <class RandomAccessIterator, class T, class Compare>
inline void __pop_heap_aux(RandomAccessIterator first,
RandomAccessIterator last, T*, Compare comp) {
__pop_heap(first, last - 1, last - 1, T(*(last - 1)), comp,
distance_type(first));
}
template <class RandomAccessIterator, class Compare>
inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last,
Compare comp) {
__pop_heap_aux(first, last, value_type(first), comp);
}
template <class RandomAccessIterator, class T, class Distance>
void __make_heap(RandomAccessIterator first, RandomAccessIterator last, T*,
Distance*) {
if (last - first < 2) return;
Distance len = last - first;
Distance parent = (len - 2)/2;
while (true) {
__adjust_heap(first, parent, len, T(*(first + parent)));
if (parent == 0) return;
parent--;
}
}
template <class RandomAccessIterator>
inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) {
__make_heap(first, last, value_type(first), distance_type(first));
}
template <class RandomAccessIterator, class Compare, class T, class Distance>
void __make_heap(RandomAccessIterator first, RandomAccessIterator last,
Compare comp, T*, Distance*) {
if (last - first < 2) return;
Distance len = last - first;
Distance parent = (len - 2)/2;
while (true) {
__adjust_heap(first, parent, len, T(*(first + parent)), comp);
if (parent == 0) return;
parent--;
}
}
template <class RandomAccessIterator, class Compare>
inline void make_heap(RandomAccessIterator first, RandomAccessIterator last,
Compare comp) {
__make_heap(first, last, comp, value_type(first), distance_type(first));
}
template <class RandomAccessIterator>
void sort_heap(RandomAccessIterator first, RandomAccessIterator last) {
while (last - first > 1) pop_heap(first, last--);
}
template <class RandomAccessIterator, class Compare>
void sort_heap(RandomAccessIterator first, RandomAccessIterator last,
Compare comp) {
while (last - first > 1) pop_heap(first, last--, comp);
}
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma reset woff 1209
#endif
#endif /* __SGI_STL_HEAP_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -27,765 +27,78 @@
#ifndef __SGI_STL_ITERATOR_H
#define __SGI_STL_ITERATOR_H
#ifndef __SGI_STL_FUNCTION_H
#include <function.h>
#endif
#include <stddef.h>
#include <iostream.h>
#include <function.h>
#ifndef __SGI_STL_INTERNAL_ITERATOR_H
#include <stl_iterator.h>
#endif
#ifndef __TYPE_TRAITS_H
#include <type_traits.h>
#endif
#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H
#include <stl_construct.h>
#endif
#ifndef __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H
#include <stl_raw_storage_iter.h>
#endif
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 {};
#ifdef __STL_USE_NAMESPACES
template <class T, class Distance> struct input_iterator {
typedef input_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
// Names from stl_iterator.h
struct output_iterator {
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
};
template <class T, class Distance> struct forward_iterator {
typedef forward_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
template <class T, class Distance> struct bidirectional_iterator {
typedef bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
template <class T, class Distance> struct random_access_iterator {
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
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;
#if 0
template <class Category, class T, class Distance = ptrdiff_t,
class Pointer = T*, class Reference = T&>
struct iterator {
typedef Category iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef Pointer pointer;
typedef Reference reference;
};
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
template <class Iterator>
struct iterator_traits {
typedef typename Iterator::iterator_category iterator_category;
typedef typename Iterator::value_type value_type;
typedef typename Iterator::difference_type difference_type;
typedef typename Iterator::pointer pointer;
typedef typename Iterator::reference reference;
};
template <class T>
struct iterator_traits<T*> {
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
};
template <class T>
struct iterator_traits<const T*> {
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef const T* pointer;
typedef const T& reference;
};
template <class Iterator>
inline iterator_traits<Iterator>::iterator_category
iterator_category(const Iterator&) {
return iterator_traits<Iterator>::iterator_category();
}
template <class Iterator>
inline iterator_traits<Iterator>::difference_type*
distance_type(const Iterator&) {
return static_cast<iterator_traits<Iterator>::difference_type*>(0);
}
template <class Iterator>
inline iterator_traits<Iterator>::value_type*
value_type(const Iterator&) {
return static_cast<iterator_traits<Iterator>::value_type*>(0);
}
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
template <class T, class Distance>
inline input_iterator_tag
iterator_category(const input_iterator<T, Distance>&) {
return input_iterator_tag();
}
inline output_iterator_tag iterator_category(const output_iterator&) {
return output_iterator_tag();
}
template <class T, class Distance>
inline forward_iterator_tag
iterator_category(const forward_iterator<T, Distance>&) {
return forward_iterator_tag();
}
template <class T, class Distance>
inline bidirectional_iterator_tag
iterator_category(const bidirectional_iterator<T, Distance>&) {
return bidirectional_iterator_tag();
}
template <class T, class Distance>
inline random_access_iterator_tag
iterator_category(const random_access_iterator<T, Distance>&) {
return random_access_iterator_tag();
}
template <class T>
inline random_access_iterator_tag iterator_category(const T*) {
return random_access_iterator_tag();
}
template <class T, class Distance>
inline T* value_type(const input_iterator<T, Distance>&) {
return (T*)(0);
}
template <class T, class Distance>
inline T* value_type(const forward_iterator<T, Distance>&) {
return (T*)(0);
}
template <class T, class Distance>
inline T* value_type(const bidirectional_iterator<T, Distance>&) {
return (T*)(0);
}
template <class T, class Distance>
inline T* value_type(const random_access_iterator<T, Distance>&) {
return (T*)(0);
}
template <class T>
inline T* value_type(const T*) { return (T*)(0); }
template <class T, class Distance>
inline Distance* distance_type(const input_iterator<T, Distance>&) {
return (Distance*)(0);
}
template <class T, class Distance>
inline Distance* distance_type(const forward_iterator<T, Distance>&) {
return (Distance*)(0);
}
template <class T, class Distance>
inline Distance*
distance_type(const bidirectional_iterator<T, Distance>&) {
return (Distance*)(0);
}
template <class T, class Distance>
inline Distance*
distance_type(const random_access_iterator<T, Distance>&) {
return (Distance*)(0);
}
template <class T>
inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); }
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
template <class Container>
class back_insert_iterator {
protected:
Container* container;
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit back_insert_iterator(Container& x) : container(&x) {}
back_insert_iterator<Container>&
operator=(const typename Container::value_type& value) {
container->push_back(value);
return *this;
}
back_insert_iterator<Container>& operator*() { return *this; }
back_insert_iterator<Container>& operator++() { return *this; }
back_insert_iterator<Container>& operator++(int) { return *this; }
};
#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
template <class Container>
inline output_iterator_tag
iterator_category(const back_insert_iterator<Container>&)
{
return output_iterator_tag();
}
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
template <class Container>
inline back_insert_iterator<Container> back_inserter(Container& x) {
return back_insert_iterator<Container>(x);
}
template <class Container>
class front_insert_iterator {
protected:
Container* container;
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit front_insert_iterator(Container& x) : container(&x) {}
front_insert_iterator<Container>&
operator=(const typename Container::value_type& value) {
container->push_front(value);
return *this;
}
front_insert_iterator<Container>& operator*() { return *this; }
front_insert_iterator<Container>& operator++() { return *this; }
front_insert_iterator<Container>& operator++(int) { return *this; }
};
#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
template <class Container>
inline output_iterator_tag
iterator_category(const front_insert_iterator<Container>&)
{
return output_iterator_tag();
}
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
template <class Container>
inline front_insert_iterator<Container> front_inserter(Container& x) {
return front_insert_iterator<Container>(x);
}
template <class Container>
class insert_iterator {
protected:
Container* container;
typename Container::iterator iter;
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
insert_iterator(Container& x, typename Container::iterator i)
: container(&x), iter(i) {}
insert_iterator<Container>&
operator=(const typename Container::value_type& value) {
iter = container->insert(iter, value);
++iter;
return *this;
}
insert_iterator<Container>& operator*() { return *this; }
insert_iterator<Container>& operator++() { return *this; }
insert_iterator<Container>& operator++(int) { return *this; }
};
#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
template <class Container>
inline output_iterator_tag
iterator_category(const insert_iterator<Container>&)
{
return output_iterator_tag();
}
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
template <class Container, class Iterator>
inline insert_iterator<Container> inserter(Container& x, Iterator i) {
typedef typename Container::iterator iter;
return insert_iterator<Container>(x, iter(i));
}
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class BidirectionalIterator, class T, class Reference = T&,
class Distance = ptrdiff_t>
#else
template <class BidirectionalIterator, class T, class Reference,
class Distance>
using __STD::iterator_traits;
#endif
class reverse_bidirectional_iterator {
typedef reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
Distance> self;
friend bool operator==(const self& x, const self& y);
protected:
BidirectionalIterator current;
public:
typedef bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef Reference reference;
reverse_bidirectional_iterator() {}
explicit reverse_bidirectional_iterator(BidirectionalIterator x)
: current(x) {}
BidirectionalIterator base() { return current; }
Reference operator*() const {
BidirectionalIterator tmp = current;
return *--tmp;
}
#ifndef __SGI_STL_NO_ARROW_OPERATOR
pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
self& operator++() {
--current;
return *this;
}
self operator++(int) {
self tmp = *this;
--current;
return tmp;
}
self& operator--() {
++current;
return *this;
}
self operator--(int) {
self tmp = *this;
++current;
return tmp;
}
};
using __STD::iterator_category;
using __STD::distance_type;
using __STD::value_type;
#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
using __STD::distance;
using __STD::advance;
template <class BidirectionalIterator, class T, class Reference,
class Distance>
inline bidirectional_iterator_tag
iterator_category(const reverse_bidirectional_iterator<BidirectionalIterator,
T,
Reference, Distance>&) {
return bidirectional_iterator_tag();
}
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;
template <class BidirectionalIterator, class T, class Reference,
class Distance>
inline T*
value_type(const reverse_bidirectional_iterator<BidirectionalIterator, T,
Reference, Distance>&) {
return (T*) 0;
}
using __STD::reverse_iterator;
using __STD::reverse_bidirectional_iterator;
template <class BidirectionalIterator, class T, class Reference,
class Distance>
inline Distance*
distance_type(const reverse_bidirectional_iterator<BidirectionalIterator, T,
Reference, Distance>&) {
return (Distance*) 0;
}
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 BidirectionalIterator, class T, class Reference,
class Distance>
inline bool operator==(
const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
Distance>& x,
const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
Distance>& y) {
return x.current == y.current;
}
// Names from stl_raw_storage_iter.h
using __STD::raw_storage_iterator;
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
// This is the new version of reverse_iterator, as defined in the
// draft C++ standard. It relies on the iterator_traits template,
// which in turn relies on partial specialization. The class
// reverse_bidirectional_iterator is no longer part of the draft
// standard, but it is retained for backward compatibility.
template <class Iterator>
class reverse_iterator : public iterator_traits<Iterator>
{
protected:
Iterator current;
public:
typedef Iterator iterator_type;
typedef reverse_iterator<Iterator> self;
public:
reverse_iterator() {}
explicit reverse_iterator(iterator_type x) : current(x) {}
reverse_iterator(const self& x) : current(x.current) {}
#ifdef __STL_MEMBER_TEMPLATES
template <class Iter>
reverse_iterator(const reverse_iterator<Iter>& x) : current(x.current) {}
#endif /* __STL_MEMBER_TEMPLATES */
iterator_type base() const { return current; }
reference operator*() const {
Iterator tmp = current;
return *--tmp;
}
#ifndef __SGI_STL_NO_ARROW_OPERATOR
pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
self& operator++() {
--current;
return *this;
}
self operator++(int) {
self tmp = *this;
--current;
return tmp;
}
self& operator--() {
++current;
return *this;
}
self operator--(int) {
self tmp = *this;
++current;
return tmp;
}
self operator+(difference_type n) const {
return self(current - n);
}
self& operator+=(difference_type n) {
current -= n;
return *this;
}
self operator-(difference_type n) const {
return self(current + n);
}
self& operator-=(difference_type n) {
current += n;
return *this;
}
reference operator[](difference_type n) { return *(*this + n); }
};
template <class Iterator>
inline bool operator==(const reverse_iterator<Iterator>& x,
const reverse_iterator<Iterator>& y) {
return x.base() == y.base();
}
template <class Iterator>
inline bool operator<(const reverse_iterator<Iterator>& x,
const reverse_iterator<Iterator>& y) {
return y.base() < x.base();
}
template <class Iterator>
inline reverse_iterator<Iterator>::difference_type
operator-(const reverse_iterator<Iterator>& x,
const reverse_iterator<Iterator>& y) {
return y.base() - x.base();
}
template <class Iterator>
inline reverse_iterator<Iterator>
operator+(reverse_iterator<Iterator>::difference_type n,
const reverse_iterator<Iterator>& x) {
return reverse_iterator<Iterator>(x.base() - n);
}
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
// This is the old version of reverse_iterator, as found in the original
// HP STL. It does not use partial specialization.
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class RandomAccessIterator, class T, class Reference = T&,
class Distance = ptrdiff_t>
#else
template <class RandomAccessIterator, class T, class Reference,
class Distance>
#endif
class reverse_iterator {
typedef reverse_iterator<RandomAccessIterator, T, Reference, Distance>
self;
friend bool operator==(const self& x, const self& y);
friend bool operator<(const self& x, const self& y);
friend Distance operator-(const self& x, const self& y);
friend self operator+(Distance n, const self& x);
protected:
RandomAccessIterator current;
public:
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef Reference reference;
reverse_iterator() {}
explicit reverse_iterator(RandomAccessIterator x) : current(x) {}
RandomAccessIterator base() { return current; }
Reference operator*() const { return *(current - 1); }
#ifndef __SGI_STL_NO_ARROW_OPERATOR
pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
self& operator++() {
--current;
return *this;
}
self operator++(int) {
self tmp = *this;
--current;
return tmp;
}
self& operator--() {
++current;
return *this;
}
self operator--(int) {
self tmp = *this;
++current;
return tmp;
}
self operator+(Distance n) const {
return self(current - n);
}
self& operator+=(Distance n) {
current -= n;
return *this;
}
self operator-(Distance n) const {
return self(current + n);
}
self& operator-=(Distance n) {
current += n;
return *this;
}
Reference operator[](Distance n) { return *(*this + n); }
};
template <class RandomAccessIterator, class T, class Reference, class Distance>
inline random_access_iterator_tag
iterator_category(const reverse_iterator<RandomAccessIterator, T,
Reference, Distance>&) {
return random_access_iterator_tag();
}
template <class RandomAccessIterator, class T, class Reference, class Distance>
inline T* value_type(const reverse_iterator<RandomAccessIterator, T,
Reference, Distance>&) {
return (T*) 0;
}
template <class RandomAccessIterator, class T, class Reference, class Distance>
inline Distance* distance_type(const reverse_iterator<RandomAccessIterator, T,
Reference, Distance>&) {
return (Distance*) 0;
}
template <class RandomAccessIterator, class T, class Reference, class Distance>
inline bool operator==(const reverse_iterator<RandomAccessIterator, T,
Reference, Distance>& x,
const reverse_iterator<RandomAccessIterator, T,
Reference, Distance>& y) {
return x.current == y.current;
}
template <class RandomAccessIterator, class T, class Reference, class Distance>
inline bool operator<(const reverse_iterator<RandomAccessIterator, T,
Reference, Distance>& x,
const reverse_iterator<RandomAccessIterator, T,
Reference, Distance>& y) {
return y.current < x.current;
}
template <class RandomAccessIterator, class T, class Reference, class Distance>
inline Distance operator-(const reverse_iterator<RandomAccessIterator, T,
Reference, Distance>& x,
const reverse_iterator<RandomAccessIterator, T,
Reference, Distance>& y) {
return y.current - x.current;
}
template <class RandomAccessIterator, class T, class Reference, class Distance>
inline reverse_iterator<RandomAccessIterator, T, Reference, Distance>
operator+(Distance n,
const reverse_iterator<RandomAccessIterator, T, Reference,
Distance>& x) {
return reverse_iterator<RandomAccessIterator, T, Reference, Distance>
(x.current - n);
}
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
template <class ForwardIterator, class T>
class raw_storage_iterator {
protected:
ForwardIterator iter;
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit raw_storage_iterator(ForwardIterator x) : iter(x) {}
raw_storage_iterator<ForwardIterator, T>& operator*() { return *this; }
raw_storage_iterator<ForwardIterator, T>& operator=(const T& element) {
construct(&*iter, element);
return *this;
}
raw_storage_iterator<ForwardIterator, T>& operator++() {
++iter;
return *this;
}
raw_storage_iterator<ForwardIterator, T> operator++(int) {
raw_storage_iterator<ForwardIterator, T> tmp = *this;
++iter;
return tmp;
}
};
#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
template <class ForwardIterator, class T>
inline output_iterator_tag
iterator_category(const raw_storage_iterator<ForwardIterator, T>&)
{
return output_iterator_tag();
}
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
template <class T, class Distance = ptrdiff_t>
class istream_iterator {
friend bool operator==(const istream_iterator<T, Distance>& x,
const istream_iterator<T, Distance>& y);
protected:
istream* stream;
T value;
bool end_marker;
void read() {
end_marker = (*stream) ? true : false;
if (end_marker) *stream >> value;
end_marker = (*stream) ? true : false;
}
public:
typedef input_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef const T* pointer;
typedef const T& reference;
istream_iterator() : stream(&cin), end_marker(false) {}
istream_iterator(istream& s) : stream(&s) { read(); }
reference operator*() const { return value; }
#ifndef __SGI_STL_NO_ARROW_OPERATOR
pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
istream_iterator<T, Distance>& operator++() {
read();
return *this;
}
istream_iterator<T, Distance> operator++(int) {
istream_iterator<T, Distance> tmp = *this;
read();
return tmp;
}
};
#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
template <class T, class Distance>
inline input_iterator_tag
iterator_category(const istream_iterator<T, Distance>&) {
return input_iterator_tag();
}
template <class T, class Distance>
inline T* value_type(const istream_iterator<T, Distance>&) { return (T*) 0; }
template <class T, class Distance>
inline Distance* distance_type(const istream_iterator<T, Distance>&) {
return (Distance*) 0;
}
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
template <class T, class Distance>
bool operator==(const istream_iterator<T, Distance>& x,
const istream_iterator<T, Distance>& y) {
return x.stream == y.stream && x.end_marker == y.end_marker ||
x.end_marker == false && y.end_marker == false;
}
template <class T>
class ostream_iterator {
protected:
ostream* stream;
const char* string;
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
ostream_iterator(ostream& s) : stream(&s), string(0) {}
ostream_iterator(ostream& s, const char* c) : stream(&s), string(c) {}
ostream_iterator<T>& operator=(const T& value) {
*stream << value;
if (string) *stream << string;
return *this;
}
ostream_iterator<T>& operator*() { return *this; }
ostream_iterator<T>& operator++() { return *this; }
ostream_iterator<T>& operator++(int) { return *this; }
};
#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
template <class T>
inline output_iterator_tag
iterator_category(const ostream_iterator<T>&) {
return output_iterator_tag();
}
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
#endif /* __STL_USE_NAMESPACES */
#endif /* __SGI_STL_ITERATOR_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -12,7 +12,7 @@
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
@@ -27,608 +27,16 @@
#ifndef __SGI_STL_LIST_H
#define __SGI_STL_LIST_H
#include <stddef.h>
#include <algobase.h>
#include <iterator.h>
#include <alloc.h>
#include <stl_list.h>
template <class T>
struct __list_node {
typedef void* void_pointer;
void_pointer next;
void_pointer prev;
T data;
};
template<class T, class Ref, class Ptr>
struct __list_iterator {
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;
typedef __list_iterator<T, Ref, Ptr> self;
typedef bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef __list_node<T>* link_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
link_type node;
__list_iterator(link_type x) : node(x) {}
__list_iterator() {}
__list_iterator(const iterator& x) : node(x.node) {}
bool operator==(const self& x) const { return node == x.node; }
bool operator!=(const self& x) const { return node != x.node; }
reference operator*() const { return (*node).data; }
#ifndef __SGI_STL_NO_ARROW_OPERATOR
pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
self& operator++() {
node = (link_type)((*node).next);
return *this;
}
self operator++(int) {
self tmp = *this;
++*this;
return tmp;
}
self& operator--() {
node = (link_type)((*node).prev);
return *this;
}
self operator--(int) {
self tmp = *this;
--*this;
return tmp;
}
};
#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
template <class T, class Ref, class Ptr>
inline bidirectional_iterator_tag
iterator_category(const __list_iterator<T, Ref, Ptr>&) {
return bidirectional_iterator_tag();
}
template <class T, class Ref, class Ptr>
inline T*
value_type(const __list_iterator<T, Ref, Ptr>&) {
return 0;
}
template <class T, class Ref, class Ptr>
inline ptrdiff_t*
distance_type(const __list_iterator<T, Ref, Ptr>&) {
return 0;
}
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
template <class T, class Alloc = alloc>
class list {
protected:
typedef void* void_pointer;
typedef __list_node<T> list_node;
typedef simple_alloc<list_node, Alloc> list_node_allocator;
public:
typedef T value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef list_node* link_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
public:
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator;
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
typedef reverse_bidirectional_iterator<const_iterator, value_type,
const_reference, difference_type>
const_reverse_iterator;
typedef reverse_bidirectional_iterator<iterator, value_type, reference,
difference_type>
reverse_iterator;
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
protected:
link_type get_node() { return list_node_allocator::allocate(); }
void put_node(link_type p) { list_node_allocator::deallocate(p); }
link_type create_node(const T& x) {
link_type p = get_node();
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
construct(&p->data, x);
return p;
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
put_node(p);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
void destroy_node(link_type p) {
destroy(&p->data);
put_node(p);
}
protected:
void empty_initialize() {
node = get_node();
node->next = node;
node->prev = node;
}
void fill_initialize(size_type n, const T& value) {
empty_initialize();
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
insert(begin(), n, value);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
clear();
put_node(node);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void range_initialize(InputIterator first, InputIterator last) {
empty_initialize();
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
insert(begin(), first, last);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
clear();
put_node(node);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
#else /* __STL_MEMBER_TEMPLATES */
void range_initialize(const T* first, const T* last) {
empty_initialize();
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
insert(begin(), first, last);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
clear();
put_node(node);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
void range_initialize(const_iterator first, const_iterator last) {
empty_initialize();
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
insert(begin(), first, last);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
clear();
put_node(node);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
#endif /* __STL_MEMBER_TEMPLATES */
protected:
link_type node;
public:
list() { empty_initialize(); }
iterator begin() { return (link_type)((*node).next); }
const_iterator begin() const { return (link_type)((*node).next); }
iterator end() { return node; }
const_iterator end() const { return node; }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
bool empty() const { return node->next == node; }
size_type size() const {
size_type result = 0;
distance(begin(), end(), result);
return result;
}
size_type max_size() const { return size_type(-1); }
reference front() { return *begin(); }
const_reference front() const { return *begin(); }
reference back() { return *(--end()); }
const_reference back() const { return *(--end()); }
void swap(list<T, Alloc>& x) { ::swap(node, x.node); }
iterator insert(iterator position, const T& x) {
link_type tmp = create_node(x);
tmp->next = position.node;
tmp->prev = position.node->prev;
(link_type(position.node->prev))->next = tmp;
position.node->prev = tmp;
return tmp;
}
iterator insert(iterator position) { return insert(position, T()); }
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void insert(iterator position, InputIterator first, InputIterator last);
#else /* __STL_MEMBER_TEMPLATES */
void insert(iterator position, const T* first, const T* last);
void insert(iterator position,
const_iterator first, const_iterator last);
#endif /* __STL_MEMBER_TEMPLATES */
void insert(iterator pos, size_type n, const T& x);
void insert(iterator pos, int n, const T& x) {
insert(pos, (size_type)n, x);
}
void insert(iterator pos, long n, const T& x) {
insert(pos, (size_type)n, x);
}
void push_front(const T& x) { insert(begin(), x); }
void push_back(const T& x) { insert(end(), x); }
void erase(iterator position) {
(link_type(position.node->prev))->next = position.node->next;
(link_type(position.node->next))->prev = position.node->prev;
destroy_node(position.node);
}
void erase(iterator first, iterator last);
void resize(size_type new_size, const T& x);
void resize(size_type new_size) { resize(new_size, T()); }
void clear();
void pop_front() { erase(begin()); }
void pop_back() {
iterator tmp = end();
erase(--tmp);
}
list(size_type n, const T& value) { fill_initialize(n, value); }
list(int n, const T& value) { fill_initialize(n, value); }
list(long n, const T& value) { fill_initialize(n, value); }
explicit list(size_type n) { fill_initialize(n, T()); }
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
list(InputIterator first, InputIterator last) {
range_initialize(first, last);
}
#else /* __STL_MEMBER_TEMPLATES */
list(const T* first, const T* last) { range_initialize(first, last); }
list(const_iterator first, const_iterator last) {
range_initialize(first, last);
}
#endif /* __STL_MEMBER_TEMPLATES */
list(const list<T, Alloc>& x) {
range_initialize(x.begin(), x.end());
}
~list() {
clear();
put_node(node);
}
list<T, Alloc>& operator=(const list<T, Alloc>& x);
protected:
void transfer(iterator position, iterator first, iterator last) {
if (position != last) {
(*(link_type((*last.node).prev))).next = position.node;
(*(link_type((*first.node).prev))).next = last.node;
(*(link_type((*position.node).prev))).next = first.node;
link_type tmp = link_type((*position.node).prev);
(*position.node).prev = (*last.node).prev;
(*last.node).prev = (*first.node).prev;
(*first.node).prev = tmp;
}
}
public:
void splice(iterator position, list& x) {
if (!x.empty())
transfer(position, x.begin(), x.end());
}
void splice(iterator position, list&, iterator i) {
iterator j = i;
++j;
if (position == i || position == j) return;
transfer(position, i, j);
}
void splice(iterator position, list&, iterator first, iterator last) {
if (first != last)
transfer(position, first, last);
}
void remove(const T& value);
void unique();
void merge(list& x);
void reverse();
void sort();
#ifdef __STL_MEMBER_TEMPLATES
template <class Predicate> void remove_if(Predicate);
template <class BinaryPredicate> void unique(BinaryPredicate);
template <class StrictWeakOrdering> void merge(list&, StrictWeakOrdering);
template <class StrictWeakOrdering> void sort(StrictWeakOrdering);
#endif /* __STL_MEMBER_TEMPLATES */
friend bool operator== (const list& x, const list& y);
};
template <class T, class Alloc>
inline bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y) {
typedef list<T,Alloc>::link_type link_type;
link_type e1 = x.node;
link_type e2 = y.node;
link_type n1 = (link_type) e1->next;
link_type n2 = (link_type) e2->next;
for ( ; n1 != e1 && n2 != e2 ;
n1 = (link_type) n1->next, n2 = (link_type) n2->next)
if (n1->data != n2->data)
return false;
return n1 == e1 && n2 == e2;
}
template <class T, class Alloc>
inline bool operator<(const list<T, Alloc>& x, const list<T, Alloc>& y) {
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
#ifdef __STL_MEMBER_TEMPLATES
template <class T, class Alloc> template <class InputIterator>
void list<T, Alloc>::insert(iterator position,
InputIterator first, InputIterator last) {
for ( ; first != last; ++first)
insert(position, *first);
}
#else /* __STL_MEMBER_TEMPLATES */
template <class T, class Alloc>
void list<T, Alloc>::insert(iterator position, const T* first, const T* last) {
for ( ; first != last; ++first)
insert(position, *first);
}
template <class T, class Alloc>
void list<T, Alloc>::insert(iterator position,
const_iterator first, const_iterator last) {
for ( ; first != last; ++first)
insert(position, *first);
}
#endif /* __STL_MEMBER_TEMPLATES */
template <class T, class Alloc>
void list<T, Alloc>::insert(iterator position, size_type n, const T& x) {
for ( ; n > 0; --n)
insert(position, x);
}
template <class T, class Alloc>
void list<T, Alloc>::erase(iterator first, iterator last) {
while (first != last) erase(first++);
}
template <class T, class Alloc>
void list<T, Alloc>::resize(size_type new_size, const T& x)
{
size_type len = size();
if (new_size < len) {
iterator f;
if (new_size < len / 2) {
f = begin();
advance(f, new_size);
}
else {
f = end();
advance(f, difference_type(len) - difference_type(new_size));
}
erase(f, end());
}
else
insert(end(), new_size - len, x);
}
template <class T, class Alloc>
void list<T, Alloc>::clear()
{
link_type cur = (link_type) node->next;
while (cur != node) {
link_type tmp = cur;
cur = (link_type) cur->next;
destroy_node(tmp);
}
node->next = node;
node->prev = node;
}
template <class T, class Alloc>
list<T, Alloc>& list<T, Alloc>::operator=(const list<T, Alloc>& x) {
if (this != &x) {
iterator first1 = begin();
iterator last1 = end();
const_iterator first2 = x.begin();
const_iterator last2 = x.end();
while (first1 != last1 && first2 != last2) *first1++ = *first2++;
if (first2 == last2)
erase(first1, last1);
else
insert(last1, first2, last2);
}
return *this;
}
template <class T, class Alloc>
void list<T, Alloc>::remove(const T& value) {
iterator first = begin();
iterator last = end();
while (first != last) {
iterator next = first;
++next;
if (*first == value) erase(first);
first = next;
}
}
template <class T, class Alloc>
void list<T, Alloc>::unique() {
iterator first = begin();
iterator last = end();
if (first == last) return;
iterator next = first;
while (++next != last) {
if (*first == *next)
erase(next);
else
first = next;
next = first;
}
}
template <class T, class Alloc>
void list<T, Alloc>::merge(list<T, Alloc>& x) {
iterator first1 = begin();
iterator last1 = end();
iterator first2 = x.begin();
iterator last2 = x.end();
while (first1 != last1 && first2 != last2)
if (*first2 < *first1) {
iterator next = first2;
transfer(first1, first2, ++next);
first2 = next;
}
else
++first1;
if (first2 != last2) transfer(last1, first2, last2);
}
template <class T, class Alloc>
void list<T, Alloc>::reverse() {
if (node->next == node || link_type(node->next)->next == node) return;
iterator first = begin();
++first;
while (first != end()) {
iterator old = first;
++first;
transfer(begin(), old, first);
}
}
template <class T, class Alloc>
void list<T, Alloc>::sort() {
if (node->next == node || link_type(node->next)->next == node) return;
list<T, Alloc> carry;
list<T, Alloc> counter[64];
int fill = 0;
while (!empty()) {
carry.splice(carry.begin(), *this, begin());
int i = 0;
while(i < fill && !counter[i].empty()) {
counter[i].merge(carry);
carry.swap(counter[i++]);
}
carry.swap(counter[i]);
if (i == fill) ++fill;
}
for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1]);
swap(counter[fill-1]);
}
#ifdef __STL_MEMBER_TEMPLATES
template <class T, class Alloc> template <class Predicate>
void list<T, Alloc>::remove_if(Predicate pred) {
iterator first = begin();
iterator last = end();
while (first != last) {
iterator next = first;
++next;
if (pred(*first)) erase(first);
first = next;
}
}
template <class T, class Alloc> template <class BinaryPredicate>
void list<T, Alloc>::unique(BinaryPredicate binary_pred) {
iterator first = begin();
iterator last = end();
if (first == last) return;
iterator next = first;
while (++next != last) {
if (binary_pred(*first, *next))
erase(next);
else
first = next;
next = first;
}
}
template <class T, class Alloc> template <class StrictWeakOrdering>
void list<T, Alloc>::merge(list<T, Alloc>& x, StrictWeakOrdering comp) {
iterator first1 = begin();
iterator last1 = end();
iterator first2 = x.begin();
iterator last2 = x.end();
while (first1 != last1 && first2 != last2)
if (comp(*first2, *first1)) {
iterator next = first2;
transfer(first1, first2, ++next);
first2 = next;
}
else
++first1;
if (first2 != last2) transfer(last1, first2, last2);
}
template <class T, class Alloc> template <class StrictWeakOrdering>
void list<T, Alloc>::sort(StrictWeakOrdering comp) {
if (node->next == node || link_type(node->next)->next == node) return;
list<T, Alloc> carry;
list<T, Alloc> counter[64];
int fill = 0;
while (!empty()) {
carry.splice(carry.begin(), *this, begin());
int i = 0;
while(i < fill && !counter[i].empty()) {
counter[i].merge(carry, comp);
carry.swap(counter[i++]);
}
carry.swap(counter[i]);
if (i == fill) ++fill;
}
for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1], comp);
swap(counter[fill-1]);
}
#endif /* __STL_MEMBER_TEMPLATES */
#ifdef __STL_USE_NAMESPACES
using __STD::list;
#endif /* __STL_USE_NAMESPACES */
#endif /* __SGI_STL_LIST_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -12,7 +12,7 @@
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
@@ -28,161 +28,14 @@
#define __SGI_STL_MAP_H
#include <tree.h>
#include <stl_map.h>
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
#else
template <class Key, class T, class Compare, class Alloc = alloc>
#endif
class map {
public:
// typedefs:
typedef Key key_type;
typedef T data_type;
typedef pair<const Key, T> value_type;
typedef Compare key_compare;
class value_compare
: public binary_function<value_type, value_type, bool> {
friend class map<Key, T, Compare, Alloc>;
protected :
Compare comp;
value_compare(Compare c) : comp(c) {}
public:
bool operator()(const value_type& x, const value_type& y) const {
return comp(x.first, y.first);
}
};
private:
typedef rb_tree<key_type, value_type,
select1st<value_type>, key_compare, Alloc> rep_type;
rep_type t; // red-black tree representing map
public:
typedef rep_type::pointer pointer;
typedef rep_type::reference reference;
typedef rep_type::const_reference const_reference;
typedef rep_type::iterator iterator;
typedef rep_type::const_iterator const_iterator;
typedef rep_type::reverse_iterator reverse_iterator;
typedef rep_type::const_reverse_iterator const_reverse_iterator;
typedef rep_type::size_type size_type;
typedef rep_type::difference_type difference_type;
// allocation/deallocation
map() : t(Compare()) {}
explicit map(const Compare& comp) : t(comp) {}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
map(InputIterator first, InputIterator last)
: t(Compare()) { t.insert_unique(first, last); }
template <class InputIterator>
map(InputIterator first, InputIterator last, const Compare& comp)
: t(comp) { t.insert_unique(first, last); }
#else
map(const value_type* first, const value_type* last)
: t(Compare()) { t.insert_unique(first, last); }
map(const value_type* first, const value_type* last, const Compare& comp)
: t(comp) { t.insert_unique(first, last); }
map(const_iterator first, const_iterator last)
: t(Compare()) { t.insert_unique(first, last); }
map(const_iterator first, const_iterator last, const Compare& comp)
: t(comp) { t.insert_unique(first, last); }
#endif /* __STL_MEMBER_TEMPLATES */
map(const map<Key, T, Compare, Alloc>& x) : t(x.t) {}
map<Key, T, Compare, Alloc>& operator=(const map<Key, T, Compare, Alloc>& x)
{
t = x.t;
return *this;
}
// accessors:
key_compare key_comp() const { return t.key_comp(); }
value_compare value_comp() const { return value_compare(t.key_comp()); }
iterator begin() { return t.begin(); }
const_iterator begin() const { return t.begin(); }
iterator end() { return t.end(); }
const_iterator end() const { return t.end(); }
reverse_iterator rbegin() { return t.rbegin(); }
const_reverse_iterator rbegin() const { return t.rbegin(); }
reverse_iterator rend() { return t.rend(); }
const_reverse_iterator rend() const { return t.rend(); }
bool empty() const { return t.empty(); }
size_type size() const { return t.size(); }
size_type max_size() const { return t.max_size(); }
T& operator[](const key_type& k) {
return (*((insert(value_type(k, T()))).first)).second;
}
void swap(map<Key, T, Compare, Alloc>& x) { t.swap(x.t); }
// insert/erase
pair<iterator,bool> insert(const value_type& x) { return t.insert_unique(x); }
iterator insert(iterator position, const value_type& x) {
return t.insert_unique(position, x);
}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void insert(InputIterator first, InputIterator last) {
t.insert_unique(first, last);
}
#else
void insert(const value_type* first, const value_type* last) {
t.insert_unique(first, last);
}
void insert(const_iterator first, const_iterator last) {
t.insert_unique(first, last);
}
#endif /* __STL_MEMBER_TEMPLATES */
void erase(iterator position) { t.erase(position); }
size_type erase(const key_type& x) { return t.erase(x); }
void erase(iterator first, iterator last) { t.erase(first, last); }
void clear() { t.clear(); }
// map operations:
iterator find(const key_type& x) { return t.find(x); }
const_iterator find(const key_type& x) const { return t.find(x); }
size_type count(const key_type& x) const { return t.count(x); }
iterator lower_bound(const key_type& x) {return t.lower_bound(x); }
const_iterator lower_bound(const key_type& x) const {
return t.lower_bound(x);
}
iterator upper_bound(const key_type& x) {return t.upper_bound(x); }
const_iterator upper_bound(const key_type& x) const {
return t.upper_bound(x);
}
pair<iterator,iterator> equal_range(const key_type& x) {
return t.equal_range(x);
}
pair<const_iterator,const_iterator> equal_range(const key_type& x) const {
return t.equal_range(x);
}
friend bool operator==(const map&, const map&);
friend bool operator<(const map&, const map&);
};
template <class Key, class T, class Compare, class Alloc>
inline bool operator==(const map<Key, T, Compare, Alloc>& x,
const map<Key, T, Compare, Alloc>& y) {
return x.t == y.t;
}
template <class Key, class T, class Compare, class Alloc>
inline bool operator<(const map<Key, T, Compare, Alloc>& x,
const map<Key, T, Compare, Alloc>& y) {
return x.t < y.t;
}
#ifdef __STL_USE_NAMESPACES
using __STD::map;
#endif /* __STL_USE_NAMESPACES */
#endif /* __SGI_STL_MAP_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -12,7 +12,7 @@
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
@@ -28,155 +28,14 @@
#define __SGI_STL_MULTIMAP_H
#include <tree.h>
#include <stl_multimap.h>
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
#else
template <class Key, class T, class Compare, class Alloc = alloc>
#endif
class multimap {
public:
// typedefs:
typedef Key key_type;
typedef T data_type;
typedef pair<const Key, T> value_type;
typedef Compare key_compare;
class value_compare : public binary_function<value_type, value_type, bool> {
friend class multimap<Key, T, Compare, Alloc>;
protected:
Compare comp;
value_compare(Compare c) : comp(c) {}
public:
bool operator()(const value_type& x, const value_type& y) const {
return comp(x.first, y.first);
}
};
private:
typedef rb_tree<key_type, value_type,
select1st<value_type>, key_compare, Alloc> rep_type;
rep_type t; // red-black tree representing multimap
public:
typedef rep_type::pointer pointer;
typedef rep_type::reference reference;
typedef rep_type::const_reference const_reference;
typedef rep_type::iterator iterator;
typedef rep_type::const_iterator const_iterator;
typedef rep_type::reverse_iterator reverse_iterator;
typedef rep_type::const_reverse_iterator const_reverse_iterator;
typedef rep_type::size_type size_type;
typedef rep_type::difference_type difference_type;
// allocation/deallocation
multimap() : t(Compare()) { }
explicit multimap(const Compare& comp) : t(comp) { }
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
multimap(InputIterator first, InputIterator last)
: t(Compare()) { t.insert_equal(first, last); }
template <class InputIterator>
multimap(InputIterator first, InputIterator last, const Compare& comp)
: t(comp) { t.insert_equal(first, last); }
#else
multimap(const value_type* first, const value_type* last)
: t(Compare()) { t.insert_equal(first, last); }
multimap(const value_type* first, const value_type* last,
const Compare& comp)
: t(comp) { t.insert_equal(first, last); }
multimap(const_iterator first, const_iterator last)
: t(Compare()) { t.insert_equal(first, last); }
multimap(const_iterator first, const_iterator last, const Compare& comp)
: t(comp) { t.insert_equal(first, last); }
#endif /* __STL_MEMBER_TEMPLATES */
multimap(const multimap<Key, T, Compare, Alloc>& x) : t(x.t) { }
multimap<Key, T, Compare, Alloc>&
operator=(const multimap<Key, T, Compare, Alloc>& x) {
t = x.t;
return *this;
}
// accessors:
key_compare key_comp() const { return t.key_comp(); }
value_compare value_comp() const { return value_compare(t.key_comp()); }
iterator begin() { return t.begin(); }
const_iterator begin() const { return t.begin(); }
iterator end() { return t.end(); }
const_iterator end() const { return t.end(); }
reverse_iterator rbegin() { return t.rbegin(); }
const_reverse_iterator rbegin() const { return t.rbegin(); }
reverse_iterator rend() { return t.rend(); }
const_reverse_iterator rend() const { return t.rend(); }
bool empty() const { return t.empty(); }
size_type size() const { return t.size(); }
size_type max_size() const { return t.max_size(); }
void swap(multimap<Key, T, Compare, Alloc>& x) { t.swap(x.t); }
// insert/erase
iterator insert(const value_type& x) { return t.insert_equal(x); }
iterator insert(iterator position, const value_type& x) {
return t.insert_equal(position, x);
}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void insert(InputIterator first, InputIterator last) {
t.insert_equal(first, last);
}
#else
void insert(const value_type* first, const value_type* last) {
t.insert_equal(first, last);
}
void insert(const_iterator first, const_iterator last) {
t.insert_equal(first, last);
}
#endif /* __STL_MEMBER_TEMPLATES */
void erase(iterator position) { t.erase(position); }
size_type erase(const key_type& x) { return t.erase(x); }
void erase(iterator first, iterator last) { t.erase(first, last); }
void clear() { t.clear(); }
// multimap operations:
iterator find(const key_type& x) { return t.find(x); }
const_iterator find(const key_type& x) const { return t.find(x); }
size_type count(const key_type& x) const { return t.count(x); }
iterator lower_bound(const key_type& x) {return t.lower_bound(x); }
const_iterator lower_bound(const key_type& x) const {
return t.lower_bound(x);
}
iterator upper_bound(const key_type& x) {return t.upper_bound(x); }
const_iterator upper_bound(const key_type& x) const {
return t.upper_bound(x);
}
pair<iterator,iterator> equal_range(const key_type& x) {
return t.equal_range(x);
}
pair<const_iterator,const_iterator> equal_range(const key_type& x) const {
return t.equal_range(x);
}
friend bool operator==(const multimap&, const multimap&);
friend bool operator<(const multimap&, const multimap&);
};
template <class Key, class T, class Compare, class Alloc>
inline bool operator==(const multimap<Key, T, Compare, Alloc>& x,
const multimap<Key, T, Compare, Alloc>& y) {
return x.t == y.t;
}
template <class Key, class T, class Compare, class Alloc>
inline bool operator<(const multimap<Key, T, Compare, Alloc>& x,
const multimap<Key, T, Compare, Alloc>& y) {
return x.t < y.t;
}
#ifdef __STL_USE_NAMESPACES
using __STD::multimap;
#endif /* __STL_USE_NAMESPACES */
#endif /* __SGI_STL_MULTIMAP_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -12,7 +12,7 @@
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
@@ -28,140 +28,14 @@
#define __SGI_STL_MULTISET_H
#include <tree.h>
#include <stl_multiset.h>
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class Key, class Compare = less<Key>, class Alloc = alloc>
#else
template <class Key, class Compare, class Alloc = alloc>
#endif
class multiset {
public:
// typedefs:
typedef Key key_type;
typedef Key value_type;
typedef Compare key_compare;
typedef Compare value_compare;
private:
typedef rb_tree<key_type, value_type,
identity<value_type>, key_compare, Alloc> rep_type;
rep_type t; // red-black tree representing multiset
public:
typedef rep_type::const_pointer pointer;
typedef rep_type::const_reference reference;
typedef rep_type::const_reference const_reference;
typedef rep_type::const_iterator iterator;
typedef rep_type::const_iterator const_iterator;
typedef rep_type::const_reverse_iterator reverse_iterator;
typedef rep_type::const_reverse_iterator const_reverse_iterator;
typedef rep_type::size_type size_type;
typedef rep_type::difference_type difference_type;
// allocation/deallocation
multiset() : t(Compare()) {}
explicit multiset(const Compare& comp) : t(comp) {}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
multiset(InputIterator first, InputIterator last)
: t(Compare()) { t.insert_equal(first, last); }
template <class InputIterator>
multiset(InputIterator first, InputIterator last, const Compare& comp)
: t(comp) { t.insert_equal(first, last); }
#else
multiset(const value_type* first, const value_type* last)
: t(Compare()) { t.insert_equal(first, last); }
multiset(const value_type* first, const value_type* last,
const Compare& comp)
: t(comp) { t.insert_equal(first, last); }
multiset(const_iterator first, const_iterator last)
: t(Compare()) { t.insert_equal(first, last); }
multiset(const_iterator first, const_iterator last, const Compare& comp)
: t(comp) { t.insert_equal(first, last); }
#endif /* __STL_MEMBER_TEMPLATES */
multiset(const multiset<Key, Compare, Alloc>& x) : t(x.t) {}
multiset<Key, Compare, Alloc>&
operator=(const multiset<Key, Compare, Alloc>& x) {
t = x.t;
return *this;
}
// accessors:
key_compare key_comp() const { return t.key_comp(); }
value_compare value_comp() const { return t.key_comp(); }
iterator begin() const { return t.begin(); }
iterator end() const { return t.end(); }
reverse_iterator rbegin() const { return t.rbegin(); }
reverse_iterator rend() const { return t.rend(); }
bool empty() const { return t.empty(); }
size_type size() const { return t.size(); }
size_type max_size() const { return t.max_size(); }
void swap(multiset<Key, Compare, Alloc>& x) { t.swap(x.t); }
// insert/erase
iterator insert(const value_type& x) {
return t.insert_equal(x);
}
iterator insert(iterator position, const value_type& x) {
return t.insert_equal((rep_type::iterator&)position, x);
}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void insert(InputIterator first, InputIterator last) {
t.insert_equal(first, last);
}
#else
void insert(const value_type* first, const value_type* last) {
t.insert_equal(first, last);
}
void insert(const_iterator first, const_iterator last) {
t.insert_equal(first, last);
}
#endif /* __STL_MEMBER_TEMPLATES */
void erase(iterator position) {
t.erase((rep_type::iterator&)position);
}
size_type erase(const key_type& x) {
return t.erase(x);
}
void erase(iterator first, iterator last) {
t.erase((rep_type::iterator&)first,
(rep_type::iterator&)last);
}
void clear() { t.clear(); }
// multiset operations:
iterator find(const key_type& x) const { return t.find(x); }
size_type count(const key_type& x) const { return t.count(x); }
iterator lower_bound(const key_type& x) const {
return t.lower_bound(x);
}
iterator upper_bound(const key_type& x) const {
return t.upper_bound(x);
}
pair<iterator,iterator> equal_range(const key_type& x) const {
return t.equal_range(x);
}
friend bool operator==(const multiset&, const multiset&);
friend bool operator<(const multiset&, const multiset&);
};
template <class Key, class Compare, class Alloc>
inline bool operator==(const multiset<Key, Compare, Alloc>& x,
const multiset<Key, Compare, Alloc>& y) {
return x.t == y.t;
}
template <class Key, class Compare, class Alloc>
inline bool operator<(const multiset<Key, Compare, Alloc>& x,
const multiset<Key, Compare, Alloc>& y) {
return x.t < y.t;
}
#ifdef __STL_USE_NAMESPACES
using __STD::multiset;
#endif /* __STL_USE_NAMESPACES */
#endif /* __SGI_STL_MULTISET_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -12,7 +12,7 @@
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
@@ -24,40 +24,28 @@
* purpose. It is provided "as is" without express or implied warranty.
*/
#ifndef PAIR_H
#define PAIR_H
#ifndef __SGI_STL_PAIR_H
#define __SGI_STL_PAIR_H
#ifndef __STL_CONFIG_H
#include <stl_config.h>
template <class T1, class T2>
struct pair {
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair() : first(T1()), second(T2()) {}
pair(const T1& a, const T2& b) : first(a), second(b) {}
#ifdef __STL_MEMBER_TEMPLATES
template <class U1, class U2>
pair(const pair<U1, U2>& p) : first(p.first), second(p.second) {}
#endif
};
template <class T1, class T2>
inline bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y) {
return x.first == y.first && x.second == y.second;
}
template <class T1, class T2>
inline bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y) {
return x.first < y.first || (!(y.first < x.first) && x.second < y.second);
}
template <class T1, class T2>
inline pair<T1, T2> make_pair(const T1& x, const T2& y) {
return pair<T1, T2>(x, y);
}
#ifndef __SGI_STL_INTERNAL_RELOPS
#include <stl_relops.h>
#endif
#ifndef __SGI_STL_INTERNAL_PAIR_H
#include <stl_pair.h>
#endif
#ifdef __STL_USE_NAMESPACES
using __STD::pair;
using __STD::make_pair;
#endif /* __STL_USE_NAMESPACES */
#endif /* __SGI_STL_PAIR_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1996
* Copyright (c) 1996-1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
@@ -11,334 +11,21 @@
* purpose. It is provided "as is" without express or implied warranty.
*/
#ifndef __PTHREAD_ALLOC_H
#define __PTHREAD_ALLOC_H
#ifndef __SGI_STL_PTHREAD_ALLOC_H
#define __SGI_STL_PTHREAD_ALLOC_H
// Pthread-specific node allocator.
// This is similar to the default allocator, except that free-list
// information is kept separately for each thread, avoiding locking.
// This should be reasonably fast even in the presence of threads.
// The down side is that storage may not be well-utilized.
// It is not an error to allocate memory in thread A and deallocate
// it n thread B. But this effectively transfers ownership of the memory,
// so that it can only be reallocated by thread B. Thus this can effectively
// result in a storage leak if it's done on a regular basis.
// It can also result in frequent sharing of
// cache lines among processors, with potentially serious performance
// consequences.
#include <pthread_alloc>
#ifdef __STL_USE_NAMESPACES
using __STD::__pthread_alloc_template;
using __STL::pthread_alloc;
#endif /* __STL_USE_NAMESPACES */
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <alloc.h>
#ifndef __RESTRICT
# define __RESTRICT
#endif
#endif /* __SGI_STL_PTHREAD_ALLOC_H */
// Note that this class has nonstatic members. We instantiate it once
// per thread.
template <bool dummy>
class __pthread_alloc_template {
private:
enum {ALIGN = 8};
enum {MAX_BYTES = 128}; // power of 2
enum {NFREELISTS = MAX_BYTES/ALIGN};
union obj {
union obj * free_list_link;
char client_data[ALIGN]; /* The client sees this. */
};
// Per instance state
obj* volatile free_list[NFREELISTS];
__pthread_alloc_template<dummy>* next; // Free list link
static size_t ROUND_UP(size_t bytes) {
return (((bytes) + ALIGN-1) & ~(ALIGN - 1));
}
static size_t FREELIST_INDEX(size_t bytes) {
return (((bytes) + ALIGN-1)/ALIGN - 1);
}
// Returns an object of size n, and optionally adds to size n free list.
void *refill(size_t n);
// Allocates a chunk for nobjs of size size. nobjs may be reduced
// if it is inconvenient to allocate the requested number.
static char *chunk_alloc(size_t size, int &nobjs);
// Chunk allocation state. And other shared state.
// Protected by chunk_allocator_lock.
static pthread_mutex_t chunk_allocator_lock;
static char *start_free;
static char *end_free;
static size_t heap_size;
static __pthread_alloc_template<dummy>* free_allocators;
static pthread_key_t key;
static bool key_initialized;
// Pthread key under which allocator is stored.
// Allocator instances that are currently unclaimed by any thread.
static void destructor(void *instance);
// Function to be called on thread exit to reclaim allocator
// instance.
static __pthread_alloc_template<dummy> *new_allocator();
// Return a recycled or new allocator instance.
static __pthread_alloc_template<dummy> *get_allocator_instance();
// ensure that the current thread has an associated
// allocator instance.
class lock {
public:
lock () { pthread_mutex_lock(&chunk_allocator_lock); }
~lock () { pthread_mutex_unlock(&chunk_allocator_lock); }
};
friend class lock;
public:
__pthread_alloc_template() : next(0)
{
memset((void *)free_list, 0, NFREELISTS * sizeof(obj *));
}
/* n must be > 0 */
static void * allocate(size_t n)
{
obj * volatile * my_free_list;
obj * __RESTRICT result;
__pthread_alloc_template<dummy>* a;
if (n > MAX_BYTES) {
return(malloc(n));
}
if (!key_initialized ||
!(a = (__pthread_alloc_template<dummy>*)
pthread_getspecific(key))) {
a = get_allocator_instance();
}
my_free_list = a -> free_list + FREELIST_INDEX(n);
result = *my_free_list;
if (result == 0) {
void *r = a -> refill(ROUND_UP(n));
return r;
}
*my_free_list = result -> free_list_link;
return (result);
};
/* p may not be 0 */
static void deallocate(void *p, size_t n)
{
obj *q = (obj *)p;
obj * volatile * my_free_list;
__pthread_alloc_template<dummy>* a;
if (n > MAX_BYTES) {
free(p);
return;
}
if (!key_initialized ||
!(a = (__pthread_alloc_template<dummy>*)
pthread_getspecific(key))) {
a = get_allocator_instance();
}
my_free_list = a->free_list + FREELIST_INDEX(n);
q -> free_list_link = *my_free_list;
*my_free_list = q;
}
static void * reallocate(void *p, size_t old_sz, size_t new_sz);
} ;
typedef __pthread_alloc_template<false> pthread_alloc;
template <bool dummy>
void __pthread_alloc_template<dummy>::destructor(void * instance)
{
__pthread_alloc_template<dummy>* a =
(__pthread_alloc_template<dummy>*)instance;
a -> next = free_allocators;
free_allocators = a;
}
template <bool dummy>
__pthread_alloc_template<dummy>*
__pthread_alloc_template<dummy>::new_allocator()
{
if (0 != free_allocators) {
__pthread_alloc_template<dummy>* result = free_allocators;
free_allocators = free_allocators -> next;
return result;
} else {
return new __pthread_alloc_template<dummy>;
}
}
template <bool dummy>
__pthread_alloc_template<dummy>*
__pthread_alloc_template<dummy>::get_allocator_instance()
{
__pthread_alloc_template<dummy>* result;
if (!key_initialized) {
/*REFERENCED*/
lock lock_instance;
if (!key_initialized) {
if (pthread_key_create(&key, destructor)) {
abort(); // failed
}
key_initialized = true;
}
}
result = new_allocator();
if (pthread_setspecific(key, result)) abort();
return result;
}
/* We allocate memory in large chunks in order to avoid fragmenting */
/* the malloc heap too much. */
/* We assume that size is properly aligned. */
template <bool dummy>
char *__pthread_alloc_template<dummy>
::chunk_alloc(size_t size, int &nobjs)
{
{
char * result;
size_t total_bytes;
size_t bytes_left;
/*REFERENCED*/
lock lock_instance; // Acquire lock for this routine
total_bytes = size * nobjs;
bytes_left = end_free - start_free;
if (bytes_left >= total_bytes) {
result = start_free;
start_free += total_bytes;
return(result);
} else if (bytes_left >= size) {
nobjs = bytes_left/size;
total_bytes = size * nobjs;
result = start_free;
start_free += total_bytes;
return(result);
} else {
size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);
// Try to make use of the left-over piece.
if (bytes_left > 0) {
__pthread_alloc_template<dummy>* a =
(__pthread_alloc_template<dummy>*)pthread_getspecific(key);
obj * volatile * my_free_list =
a->free_list + FREELIST_INDEX(bytes_left);
((obj *)start_free) -> free_list_link = *my_free_list;
*my_free_list = (obj *)start_free;
}
# ifdef _SGI_SOURCE
// Try to get memory that's aligned on something like a
// cache line boundary, so as to avoid parceling out
// parts of the same line to different threads and thus
// possibly different processors.
{
const int cache_line_size = 128; // probable upper bound
bytes_to_get &= ~(cache_line_size-1);
start_free = (char *)memalign(cache_line_size, bytes_to_get);
if (0 == start_free) {
start_free = (char *)malloc_alloc::allocate(bytes_to_get);
}
}
# else /* !SGI_SOURCE */
start_free = (char *)malloc_alloc::allocate(bytes_to_get);
# endif
heap_size += bytes_to_get;
end_free = start_free + bytes_to_get;
}
}
// lock is released here
return(chunk_alloc(size, nobjs));
}
/* Returns an object of size n, and optionally adds to size n free list.*/
/* We assume that n is properly aligned. */
/* We hold the allocation lock. */
template <bool dummy>
void *__pthread_alloc_template<dummy>
::refill(size_t n)
{
int nobjs = 128;
char * chunk = chunk_alloc(n, nobjs);
obj * volatile * my_free_list;
obj * result;
obj * current_obj, * next_obj;
int i;
if (1 == nobjs) {
return(chunk);
}
my_free_list = free_list + FREELIST_INDEX(n);
/* Build free list in chunk */
result = (obj *)chunk;
*my_free_list = next_obj = (obj *)(chunk + n);
for (i = 1; ; i++) {
current_obj = next_obj;
next_obj = (obj *)((char *)next_obj + n);
if (nobjs - 1 == i) {
current_obj -> free_list_link = 0;
break;
} else {
current_obj -> free_list_link = next_obj;
}
}
return(result);
}
template <bool dummy>
void *__pthread_alloc_template<dummy>
::reallocate(void *p, size_t old_sz, size_t new_sz)
{
void * result;
size_t copy_sz;
if (old_sz > MAX_BYTES && new_sz > MAX_BYTES) {
return(realloc(p, new_sz));
}
if (ROUND_UP(old_sz) == ROUND_UP(new_sz)) return(p);
result = allocate(new_sz);
copy_sz = new_sz > old_sz? old_sz : new_sz;
memcpy(result, p, copy_sz);
deallocate(p, old_sz);
return(result);
}
template <bool dummy>
__pthread_alloc_template<dummy> *
__pthread_alloc_template<dummy>::free_allocators = 0;
template <bool dummy>
pthread_key_t __pthread_alloc_template<dummy>::key;
template <bool dummy>
bool __pthread_alloc_template<dummy>::key_initialized = false;
template <bool dummy>
pthread_mutex_t __pthread_alloc_template<dummy>::chunk_allocator_lock
= PTHREAD_MUTEX_INITIALIZER;
template <bool dummy>
char *__pthread_alloc_template<dummy>
::start_free = 0;
template <bool dummy>
char *__pthread_alloc_template<dummy>
::end_free = 0;
template <bool dummy>
size_t __pthread_alloc_template<dummy>
::heap_size = 0;
#endif /* __NODE_ALLOC_H */
// Local Variables:
// mode:C++
// End:

File diff suppressed because it is too large Load Diff

View File

@@ -11,9 +11,19 @@
* purpose. It is provided "as is" without express or implied warranty.
*/
/* NOTE: This is an internal header file, included by other STL headers.
* You should not attempt to use it directly.
*/
# include <stdio.h>
# include <iostream.h>
__STL_BEGIN_NAMESPACE
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma set woff 1174
#endif
// Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf
// if necessary. Assumes path_end[leaf_index] and leaf_pos are correct.
// Results in a valid buf_ptr if the iterator can be legitimately
@@ -416,8 +426,9 @@ rope<charT,Alloc>::leaf_concat_char_iter
uninitialized_copy_n(r -> data, old_len, new_data);
uninitialized_copy_n(iter, len, new_data + old_len);
__cond_store_eos(new_data[old_len + len]);
__STL_TRY
__STL_TRY {
result = RopeLeaf_from_char_ptr(new_data, old_len + len);
}
__STL_UNWIND(RopeBase::free_string(new_data, old_len + len));
return result;
}
@@ -482,7 +493,7 @@ rope<charT,Alloc>::tree_concat (RopeBase * left, RopeBase * right)
if (depth > 20 && (rsize < 1000 || depth > RopeBase::max_rope_depth)) {
RopeBase * balanced;
__STL_TRY
__STL_TRY {
balanced = balance(result);
# ifndef __GC
if (result != balanced) {
@@ -491,6 +502,7 @@ rope<charT,Alloc>::tree_concat (RopeBase * left, RopeBase * right)
}
# endif
result -> unref_nonnil();
}
__STL_UNWIND(CAlloc::deallocate(result));
// In case of exception, we need to deallocate
// otherwise dangling result node. But caller
@@ -526,8 +538,9 @@ rope<charT,Alloc>::RopeBase * rope<charT,Alloc>::concat_char_iter
RopeBase * left = ((RopeConcatenation *)r) -> left;
RopeBase * nright = leaf_concat_char_iter((RopeLeaf *)right, s, slen);
left -> ref_nonnil();
__STL_TRY
__STL_TRY {
result = tree_concat(left, nright);
}
__STL_UNWIND(unref(left); unref(nright));
# ifndef __GC
__stl_assert(1 == result -> refcount);
@@ -536,9 +549,10 @@ rope<charT,Alloc>::RopeBase * rope<charT,Alloc>::concat_char_iter
}
}
RopeBase * nright = RopeLeaf_from_unowned_char_ptr(s, slen);
__STL_TRY
__STL_TRY {
r -> ref_nonnil();
result = tree_concat(r, nright);
}
__STL_UNWIND(unref(r); unref(nright));
# ifndef __GC
__stl_assert(1 == result -> refcount);
@@ -591,8 +605,9 @@ rope<charT,Alloc>::RopeBase * rope<charT,Alloc>
}
RopeBase *right = RopeLeaf_from_unowned_char_ptr(s, slen);
r -> ref_nonnil();
__STL_TRY
__STL_TRY {
result = tree_concat(r, right);
}
__STL_UNWIND(unref(r); unref(right))
__stl_assert(1 == result -> refcount);
return result;
@@ -629,16 +644,18 @@ rope<charT,Alloc>::concat(RopeBase * left, RopeBase * right)
((RopeLeaf *)right) -> data,
right -> size);
leftleft -> ref_nonnil();
__STL_TRY
__STL_TRY {
return(tree_concat(leftleft, rest));
}
__STL_UNWIND(unref(leftleft); unref(rest))
}
}
}
left -> ref_nonnil();
right -> ref_nonnil();
__STL_TRY
__STL_TRY {
return(tree_concat(left, right));
}
__STL_UNWIND(unref(left); unref(right));
}
@@ -732,8 +749,9 @@ rope<charT,Alloc>::substring(RopeBase * base, size_t start, size_t endp1)
if (result_len > lazy_threshold) goto lazy;
section = (charT *)
DataAlloc::allocate(rounded_up_size(result_len));
__STL_TRY
__STL_TRY {
(*(f -> fn))(start, result_len, section);
}
__STL_UNWIND(RopeBase::free_string(section, result_len));
__cond_store_eos(section[result_len]);
return RopeLeaf_from_char_ptr(section, result_len);
@@ -872,10 +890,12 @@ bool rope<charT, Alloc>::apply_to_pieces(
size_t len = end - begin;
bool result;
charT * buffer = DataAlloc::allocate(len);
__STL_TRY
__STL_TRY {
(*(f -> fn))(begin, end, buffer);
result = c(buffer, len);
__STL_ALWAYS(DataAlloc::deallocate(buffer, len))
DataAlloc::deallocate(buffer, len);
}
__STL_UNWIND(DataAlloc::deallocate(buffer, len))
return result;
}
default:
@@ -915,7 +935,7 @@ ostream& operator<< (ostream& o, const rope<charT, Alloc>& r)
pad_len = 0;
}
if (!is_simple) o.width(w/rope_len);
__STL_TRY
__STL_TRY {
if (is_simple && !left && pad_len > 0) {
__rope_fill(o, pad_len);
}
@@ -923,7 +943,10 @@ ostream& operator<< (ostream& o, const rope<charT, Alloc>& r)
if (is_simple && left && pad_len > 0) {
__rope_fill(o, pad_len);
}
__STL_ALWAYS(if (!is_simple) o.width(w))
if (!is_simple)
o.width(w);
}
__STL_UNWIND(if (!is_simple) o.width(w))
return o;
}
@@ -964,7 +987,7 @@ rope<charT,Alloc>::flatten(RopeBase * r, charT * buffer)
case RopeBase::leaf:
{
RopeLeaf * l = (RopeLeaf *)r;
return copy_n(l -> data, l -> size, buffer);
return copy_n(l -> data, l -> size, buffer).second;
}
case RopeBase::function:
case RopeBase::substringfn:
@@ -1076,7 +1099,7 @@ rope<charT,Alloc>::balance(RopeBase *r)
// References from forest are included in refcount.
for (i = 0; i <= RopeBase::max_rope_depth; ++i) forest[i] = 0;
__STL_TRY
__STL_TRY {
add_to_forest(r, forest);
for (i = 0; i <= RopeBase::max_rope_depth; ++i) if (0 != forest[i]) {
# ifndef __GC
@@ -1088,6 +1111,7 @@ rope<charT,Alloc>::balance(RopeBase *r)
forest[i] = 0;
# endif
}
}
__STL_UNWIND(for(i = 0; i <= RopeBase::max_rope_depth; i++)
unref(forest[i]))
if (result -> depth > RopeBase::max_rope_depth) abort();
@@ -1366,8 +1390,9 @@ rope<charT, Alloc>::rope(size_t n, charT c)
rest_buffer = DataAlloc::allocate(rounded_up_size(rest));
uninitialized_fill_n(rest_buffer, rest, c);
__cond_store_eos(rest_buffer[rest]);
__STL_TRY
__STL_TRY {
remainder = RopeLeaf_from_char_ptr(rest_buffer, rest);
}
__STL_UNWIND(RopeBase::free_string(rest_buffer, rest))
}
remainder_rope.tree_ptr = remainder;
@@ -1378,9 +1403,10 @@ rope<charT, Alloc>::rope(size_t n, charT c)
rope base_rope;
uninitialized_fill_n(base_buffer, exponentiate_threshold, c);
__cond_store_eos(base_buffer[exponentiate_threshold]);
__STL_TRY
base_leaf = RopeLeaf_from_char_ptr(base_buffer,
exponentiate_threshold);
__STL_TRY {
base_leaf = RopeLeaf_from_char_ptr(base_buffer,
exponentiate_threshold);
}
__STL_UNWIND(RopeBase::free_string(base_buffer, exponentiate_threshold))
base_rope.tree_ptr = base_leaf;
if (1 == exponent) {
@@ -1499,3 +1525,13 @@ inline void rotate(__rope_iterator<wchar_t,__ALLOC> first,
}
# endif
#endif /* _MSC_VER */
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma reset woff 1174
#endif
__STL_END_NAMESPACE
// Local Variables:
// mode:C++
// End:

View File

@@ -12,7 +12,7 @@
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
@@ -28,140 +28,14 @@
#define __SGI_STL_SET_H
#include <tree.h>
#include <stl_set.h>
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class Key, class Compare = less<Key>, class Alloc = alloc>
#else
template <class Key, class Compare, class Alloc = alloc>
#endif
class set {
public:
// typedefs:
typedef Key key_type;
typedef Key value_type;
typedef Compare key_compare;
typedef Compare value_compare;
private:
typedef rb_tree<key_type, value_type,
identity<value_type>, key_compare, Alloc> rep_type;
rep_type t; // red-black tree representing set
public:
typedef rep_type::const_pointer pointer;
typedef rep_type::const_reference reference;
typedef rep_type::const_reference const_reference;
typedef rep_type::const_iterator iterator;
typedef rep_type::const_iterator const_iterator;
typedef rep_type::const_reverse_iterator reverse_iterator;
typedef rep_type::const_reverse_iterator const_reverse_iterator;
typedef rep_type::size_type size_type;
typedef rep_type::difference_type difference_type;
// allocation/deallocation
set() : t(Compare()) {}
explicit set(const Compare& comp) : t(comp) {}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
set(InputIterator first, InputIterator last)
: t(Compare()) { t.insert_unique(first, last); }
template <class InputIterator>
set(InputIterator first, InputIterator last, const Compare& comp)
: t(comp) { t.insert_unique(first, last); }
#else
set(const value_type* first, const value_type* last)
: t(Compare()) { t.insert_unique(first, last); }
set(const value_type* first, const value_type* last, const Compare& comp)
: t(comp) { t.insert_unique(first, last); }
set(const_iterator first, const_iterator last)
: t(Compare()) { t.insert_unique(first, last); }
set(const_iterator first, const_iterator last, const Compare& comp)
: t(comp) { t.insert_unique(first, last); }
#endif /* __STL_MEMBER_TEMPLATES */
set(const set<Key, Compare, Alloc>& x) : t(x.t) {}
set<Key, Compare, Alloc>& operator=(const set<Key, Compare, Alloc>& x) {
t = x.t;
return *this;
}
// accessors:
key_compare key_comp() const { return t.key_comp(); }
value_compare value_comp() const { return t.key_comp(); }
iterator begin() const { return t.begin(); }
iterator end() const { return t.end(); }
reverse_iterator rbegin() const { return t.rbegin(); }
reverse_iterator rend() const { return t.rend(); }
bool empty() const { return t.empty(); }
size_type size() const { return t.size(); }
size_type max_size() const { return t.max_size(); }
void swap(set<Key, Compare, Alloc>& x) { t.swap(x.t); }
// insert/erase
typedef pair<iterator, bool> pair_iterator_bool;
pair<iterator,bool> insert(const value_type& x) {
pair<rep_type::iterator, bool> p = t.insert_unique(x);
return pair<iterator, bool>(p.first, p.second);
}
iterator insert(iterator position, const value_type& x) {
return t.insert_unique((rep_type::iterator&)position, x);
}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void insert(InputIterator first, InputIterator last) {
t.insert_unique(first, last);
}
#else
void insert(const_iterator first, const_iterator last) {
t.insert_unique(first, last);
}
void insert(const value_type* first, const value_type* last) {
t.insert_unique(first, last);
}
#endif /* __STL_MEMBER_TEMPLATES */
void erase(iterator position) {
t.erase((rep_type::iterator&)position);
}
size_type erase(const key_type& x) {
return t.erase(x);
}
void erase(iterator first, iterator last) {
t.erase((rep_type::iterator&)first,
(rep_type::iterator&)last);
}
void clear() { t.clear(); }
// set operations:
iterator find(const key_type& x) const { return t.find(x); }
size_type count(const key_type& x) const { return t.count(x); }
iterator lower_bound(const key_type& x) const {
return t.lower_bound(x);
}
iterator upper_bound(const key_type& x) const {
return t.upper_bound(x);
}
pair<iterator,iterator> equal_range(const key_type& x) const {
return t.equal_range(x);
}
friend bool operator==(const set&, const set&);
friend bool operator<(const set&, const set&);
};
template <class Key, class Compare, class Alloc>
inline bool operator==(const set<Key, Compare, Alloc>& x,
const set<Key, Compare, Alloc>& y) {
return x.t == y.t;
}
template <class Key, class Compare, class Alloc>
inline bool operator<(const set<Key, Compare, Alloc>& x,
const set<Key, Compare, Alloc>& y) {
return x.t < y.t;
}
#ifdef __STL_USE_NAMESPACES
using __STD::set;
#endif /* __STL_USE_NAMESPACES */
#endif /* __SGI_STL_SET_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -17,720 +17,14 @@
#include <algobase.h>
#include <alloc.h>
#include <stl_slist.h>
struct __slist_node_base
{
__slist_node_base* next;
};
inline __slist_node_base* __slist_make_link(__slist_node_base* prev_node,
__slist_node_base* new_node)
{
new_node->next = prev_node->next;
prev_node->next = new_node;
return new_node;
}
inline __slist_node_base* __slist_previous(__slist_node_base* head,
const __slist_node_base* node)
{
while (head && head->next != node)
head = head->next;
return head;
}
inline const __slist_node_base* __slist_previous(const __slist_node_base* head,
const __slist_node_base* node)
{
while (head && head->next != node)
head = head->next;
return head;
}
inline void __slist_splice_after(__slist_node_base* pos,
__slist_node_base* before_first,
__slist_node_base* before_last)
{
if (pos != before_first && pos != before_last) {
__slist_node_base* first = before_first->next;
__slist_node_base* after = pos->next;
before_first->next = before_last->next;
pos->next = first;
before_last->next = after;
}
}
inline __slist_node_base* __slist_reverse(__slist_node_base* node)
{
__slist_node_base* result = node;
node = node->next;
result->next = 0;
while(node) {
__slist_node_base* next = node->next;
node->next = result;
result = node;
node = next;
}
return result;
}
template <class T>
struct __slist_node : public __slist_node_base
{
T data;
};
struct __slist_iterator_base
{
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef forward_iterator_tag iterator_category;
__slist_node_base* node;
__slist_iterator_base(__slist_node_base* x) : node(x) {}
void incr() { node = node->next; }
bool operator==(const __slist_iterator_base& x) const {
return node == x.node;
}
bool operator!=(const __slist_iterator_base& x) const {
return node != x.node;
}
};
template <class T, class Ref, class Ptr>
struct __slist_iterator : public __slist_iterator_base
{
typedef __slist_iterator<T, T&, T*> iterator;
typedef __slist_iterator<T, const T&, const T*> const_iterator;
typedef __slist_iterator<T, Ref, Ptr> self;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef __slist_node<T> list_node;
__slist_iterator(list_node* x) : __slist_iterator_base(x) {}
__slist_iterator() : __slist_iterator_base(0) {}
__slist_iterator(const iterator& x) : __slist_iterator_base(x.node) {}
reference operator*() const { return ((list_node*) node)->data; }
#ifndef __SGI_STL_NO_ARROW_OPERATOR
pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
self& operator++()
{
incr();
return *this;
}
self operator++(int)
{
self tmp = *this;
incr();
return tmp;
}
};
#ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
inline ptrdiff_t*
distance_type(const __slist_iterator_base&)
{
return 0;
}
inline forward_iterator_tag
iterator_category(const __slist_iterator_base&)
{
return forward_iterator_tag();
}
template <class T, class Ref, class Ptr>
inline T*
value_type(const __slist_iterator<T, Ref, Ptr>&) {
return 0;
}
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
inline size_t __slist_size(__slist_node_base* node)
{
size_t result = 0;
for ( ; node != 0; node = node->next)
++result;
return result;
}
template <class T, class Alloc = alloc>
class slist
{
public:
typedef T value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef __slist_iterator<T, T&, T*> iterator;
typedef __slist_iterator<T, const T&, const T*> const_iterator;
private:
typedef __slist_node<T> list_node;
typedef __slist_node_base list_node_base;
typedef __slist_iterator_base iterator_base;
typedef simple_alloc<list_node, Alloc> list_node_allocator;
static list_node* create_node(const value_type& x) {
list_node* node = list_node_allocator::allocate();
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
construct(&node->data, x);
node->next = 0;
return node;
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
list_node_allocator::deallocate(node);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
static void destroy_node(list_node* node) {
destroy(&node->data);
list_node_allocator::deallocate(node);
}
void fill_initialize(size_type n, const value_type& x) {
head.next = 0;
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
_insert_after_fill(&head, n, x);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
clear();
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void range_initialize(InputIterator first, InputIterator last) {
head.next = 0;
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
_insert_after_range(&head, first, last);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
clear();
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
#else /* __STL_MEMBER_TEMPLATES */
void range_initialize(const value_type* first, const value_type* last) {
head.next = 0;
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
_insert_after_range(&head, first, last);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
clear();
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
void range_initialize(const_iterator first, const_iterator last) {
head.next = 0;
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
_insert_after_range(&head, first, last);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
clear();
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
#endif /* __STL_MEMBER_TEMPLATES */
private:
list_node_base head;
public:
slist() { head.next = 0; }
slist(size_type n, const value_type& x) { fill_initialize(n, x); }
slist(int n, const value_type& x) { fill_initialize(n, x); }
slist(long n, const value_type& x) { fill_initialize(n, x); }
explicit slist(size_type n) { fill_initialize(n, value_type()); }
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
slist(InputIterator first, InputIterator last) {
range_initialize(first, last);
}
#else /* __STL_MEMBER_TEMPLATES */
slist(const_iterator first, const_iterator last) {
range_initialize(first, last);
}
slist(const value_type* first, const value_type* last) {
range_initialize(first, last);
}
#endif /* __STL_MEMBER_TEMPLATES */
slist(const slist& L) { range_initialize(L.begin(), L.end()); }
slist& operator= (const slist& L);
~slist() { clear(); }
public:
iterator begin() { return iterator((list_node*)head.next); }
const_iterator begin() const { return const_iterator((list_node*)head.next);}
iterator end() { return iterator(0); }
const_iterator end() const { return const_iterator(0); }
size_type size() const { return __slist_size(head.next); }
size_type max_size() const { return size_type(-1); }
bool empty() const { return head.next == 0; }
void swap(slist& L)
{
list_node_base* tmp = head.next;
head.next = L.head.next;
L.head.next = tmp;
}
public:
friend bool operator==(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2);
public:
reference front() { return ((list_node*) head.next)->data; }
const_reference front() const { return ((list_node*) head.next)->data; }
void push_front(const value_type& x) {
__slist_make_link(&head, create_node(x));
}
void pop_front() {
list_node* node = (list_node*) head.next;
head.next = node->next;
destroy_node(node);
}
iterator previous(const_iterator pos) {
return iterator((list_node*) __slist_previous(&head, pos.node));
}
const_iterator previous(const_iterator pos) const {
return const_iterator((list_node*) __slist_previous(&head, pos.node));
}
private:
list_node* _insert_after(list_node_base* pos, const value_type& x) {
return (list_node*) (__slist_make_link(pos, create_node(x)));
}
void _insert_after_fill(list_node_base* pos,
size_type n, const value_type& x) {
for (size_type i = 0; i < n; ++i)
pos = __slist_make_link(pos, create_node(x));
}
#ifdef __STL_MEMBER_TEMPLATES
template <class InIter>
void _insert_after_range(list_node_base* pos, InIter first, InIter last) {
while (first != last) {
pos = __slist_make_link(pos, create_node(*first));
++first;
}
}
#else /* __STL_MEMBER_TEMPLATES */
void _insert_after_range(list_node_base* pos,
const_iterator first, const_iterator last) {
while (first != last) {
pos = __slist_make_link(pos, create_node(*first));
++first;
}
}
void _insert_after_range(list_node_base* pos,
const value_type* first, const value_type* last) {
while (first != last) {
pos = __slist_make_link(pos, create_node(*first));
++first;
}
}
#endif /* __STL_MEMBER_TEMPLATES */
void erase_after(list_node_base* pos) {
list_node* next = (list_node*) (pos->next);
pos->next = next->next;
destroy_node(next);
}
void erase_after(list_node_base* before_first, list_node_base* last_node) {
list_node* cur = (list_node*) (before_first->next);
while (cur != last_node) {
list_node* tmp = cur;
cur = (list_node*) cur->next;
destroy_node(tmp);
}
before_first->next = last_node;
}
public:
iterator insert_after(iterator pos, const value_type& x) {
return iterator(_insert_after(pos.node, x));
}
iterator insert_after(iterator pos) {
return insert_after(pos, value_type());
}
void insert_after(iterator pos, size_type n, const value_type& x) {
_insert_after_fill(pos.node, n, x);
}
void insert_after(iterator pos, int n, const value_type& x) {
_insert_after_fill(pos.node, (size_type) n, x);
}
void insert_after(iterator pos, long n, const value_type& x) {
_insert_after_fill(pos.node, (size_type) n, x);
}
#ifdef __STL_MEMBER_TEMPLATES
template <class InIter>
void insert_after(iterator pos, InIter first, InIter last) {
_insert_after_range(pos.node, first, last);
}
#else /* __STL_MEMBER_TEMPLATES */
void insert_after(iterator pos, const_iterator first, const_iterator last) {
_insert_after_range(pos.node, first, last);
}
void insert_after(iterator pos,
const value_type* first, const value_type* last) {
_insert_after_range(pos.node, first, last);
}
#endif /* __STL_MEMBER_TEMPLATES */
iterator insert(iterator pos, const value_type& x) {
return iterator(_insert_after(__slist_previous(&head, pos.node), x));
}
iterator insert(iterator pos) {
return iterator(_insert_after(__slist_previous(&head, pos.node),
value_type()));
}
void insert(iterator pos, size_type n, const value_type& x) {
_insert_after_fill(__slist_previous(&head, pos.node), n, x);
}
void insert(iterator pos, int n, const value_type& x) {
_insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x);
}
void insert(iterator pos, long n, const value_type& x) {
_insert_after_fill(__slist_previous(&head, pos.node), (size_type) n, x);
}
#ifdef __STL_MEMBER_TEMPLATES
template <class InIter>
void insert(iterator pos, InIter first, InIter last) {
_insert_after_range(__slist_previous(&head, pos.node), first, last);
}
#else /* __STL_MEMBER_TEMPLATES */
void insert(iterator pos, const_iterator first, const_iterator last) {
_insert_after_range(__slist_previous(&head, pos.node), first, last);
}
void insert(iterator pos, const value_type* first, const value_type* last) {
_insert_after_range(__slist_previous(&head, pos.node), first, last);
}
#endif /* __STL_MEMBER_TEMPLATES */
public:
void erase_after(iterator pos) { erase_after(pos.node); }
void erase_after(iterator before_first, iterator last) {
erase_after(before_first.node, last.node);
}
void erase(iterator pos) { erase_after(__slist_previous(&head, pos.node)); }
void erase(iterator first, iterator last) {
erase_after(__slist_previous(&head, first.node), last.node);
}
void resize(size_type new_size, const T& x);
void resize(size_type new_size) { resize(new_size, T()); }
void clear() { erase_after(&head, 0); }
public:
// Moves the range [before_first + 1, before_last + 1) to *this,
// inserting it immediately after pos. This is constant time.
void splice_after(iterator pos,
iterator before_first, iterator before_last)
{
if (before_first != before_last)
__slist_splice_after(pos.node, before_first.node, before_last.node);
}
// Moves the element that follows prev to *this, inserting it immediately
// after pos. This is constant time.
void splice_after(iterator pos, iterator prev)
{
__slist_splice_after(pos.node, prev.node, prev.node->next);
}
// Linear in distance(begin(), pos), and linear in L.size().
void splice(iterator pos, slist& L) {
if (L.head.next)
__slist_splice_after(__slist_previous(&head, pos.node),
&L.head,
__slist_previous(&L.head, 0));
}
// Linear in distance(begin(), pos), and in distance(L.begin(), i).
void splice(iterator pos, slist& L, iterator i) {
__slist_splice_after(__slist_previous(&head, pos.node),
__slist_previous(&L.head, i.node),
i.node);
}
// Linear in distance(begin(), pos), in distance(L.begin(), first),
// and in distance(first, last).
void splice(iterator pos, slist& L, iterator first, iterator last)
{
if (first != last)
__slist_splice_after(__slist_previous(&head, pos.node),
__slist_previous(&L.head, first.node),
__slist_previous(first.node, last.node));
}
public:
void reverse() { if (head.next) head.next = __slist_reverse(head.next); }
void remove(const T& val);
void unique();
void merge(slist& L);
void sort();
#ifdef __STL_MEMBER_TEMPLATES
template <class Predicate> void remove_if(Predicate pred);
template <class BinaryPredicate> void unique(BinaryPredicate pred);
template <class StrictWeakOrdering> void merge(slist&, StrictWeakOrdering);
template <class StrictWeakOrdering> void sort(StrictWeakOrdering comp);
#endif /* __STL_MEMBER_TEMPLATES */
};
template <class T, class Alloc>
slist<T, Alloc>& slist<T,Alloc>::operator=(const slist<T, Alloc>& L)
{
if (&L != this) {
list_node_base* p1 = &head;
list_node* n1 = (list_node*) head.next;
const list_node* n2 = (const list_node*) L.head.next;
while (n1 && n2) {
n1->data = n2->data;
p1 = n1;
n1 = (list_node*) n1->next;
n2 = (const list_node*) n2->next;
}
if (n2 == 0)
erase_after(p1, 0);
else
_insert_after_range(p1,
const_iterator((list_node*)n2), const_iterator(0));
}
return *this;
}
template <class T, class Alloc>
bool operator==(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2)
{
typedef typename slist<T,Alloc>::list_node list_node;
list_node* n1 = (list_node*) L1.head.next;
list_node* n2 = (list_node*) L2.head.next;
while (n1 && n2 && n1->data == n2->data) {
n1 = (list_node*) n1->next;
n2 = (list_node*) n2->next;
}
return n1 == 0 && n2 == 0;
}
template <class T, class Alloc>
inline bool operator<(const slist<T, Alloc>& L1, const slist<T, Alloc>& L2)
{
return lexicographical_compare(L1.begin(), L1.end(), L2.begin(), L2.end());
}
template <class T, class Alloc>
void slist<T, Alloc>::resize(size_type len, const T& x)
{
list_node_base* cur = &head;
while (cur->next != 0 && len > 0) {
--len;
cur = cur->next;
}
if (cur->next)
erase_after(cur, 0);
else
_insert_after_fill(cur, len, x);
}
template <class T, class Alloc>
void slist<T,Alloc>::remove(const T& val)
{
list_node_base* cur = &head;
while (cur && cur->next) {
if (((list_node*) cur->next)->data == val)
erase_after(cur);
else
cur = cur->next;
}
}
template <class T, class Alloc>
void slist<T,Alloc>::unique()
{
list_node_base* cur = head.next;
if (cur) {
while (cur->next) {
if (((list_node*)cur)->data == ((list_node*)(cur->next))->data)
erase_after(cur);
else
cur = cur->next;
}
}
}
template <class T, class Alloc>
void slist<T,Alloc>::merge(slist<T,Alloc>& L)
{
list_node_base* n1 = &head;
while (n1->next && L.head.next) {
if (((list_node*) L.head.next)->data < ((list_node*) n1->next)->data)
__slist_splice_after(n1, &L.head, L.head.next);
n1 = n1->next;
}
if (L.head.next) {
n1->next = L.head.next;
L.head.next = 0;
}
}
template <class T, class Alloc>
void slist<T,Alloc>::sort()
{
if (head.next && head.next->next) {
slist carry;
slist counter[64];
int fill = 0;
while (!empty()) {
__slist_splice_after(&carry.head, &head, head.next);
int i = 0;
while (i < fill && !counter[i].empty()) {
counter[i].merge(carry);
carry.swap(counter[i]);
++i;
}
carry.swap(counter[i]);
if (i == fill)
++fill;
}
for (int i = 1; i < fill; ++i)
counter[i].merge(counter[i-1]);
this->swap(counter[fill-1]);
}
}
#ifdef __STL_MEMBER_TEMPLATES
template <class T, class Alloc>
template <class Predicate> void slist<T,Alloc>::remove_if(Predicate pred)
{
list_node_base* cur = &head;
while (cur->next) {
if (pred(((list_node*) cur->next)->data))
erase_after(cur);
else
cur = cur->next;
}
}
template <class T, class Alloc> template <class BinaryPredicate>
void slist<T,Alloc>::unique(BinaryPredicate pred)
{
list_node* cur = (list_node*) head.next;
if (cur) {
while (cur->next) {
if (pred(((list_node*)cur)->data, ((list_node*)(cur->next))->data))
erase_after(cur);
else
cur = (list_node*) cur->next;
}
}
}
template <class T, class Alloc> template <class StrictWeakOrdering>
void slist<T,Alloc>::merge(slist<T,Alloc>& L, StrictWeakOrdering comp)
{
list_node_base* n1 = &head;
while (n1->next && L.head.next) {
if (comp(((list_node*) L.head.next)->data,
((list_node*) n1->next)->data))
__slist_splice_after(n1, &L.head, L.head.next);
n1 = n1->next;
}
if (L.head.next) {
n1->next = L.head.next;
L.head.next = 0;
}
}
template <class T, class Alloc> template <class StrictWeakOrdering>
void slist<T,Alloc>::sort(StrictWeakOrdering comp)
{
if (head.next && head.next->next) {
slist carry;
slist counter[64];
int fill = 0;
while (!empty()) {
__slist_splice_after(&carry.head, &head, head.next);
int i = 0;
while (i < fill && !counter[i].empty()) {
counter[i].merge(carry, comp);
carry.swap(counter[i]);
++i;
}
carry.swap(counter[i]);
if (i == fill)
++fill;
}
for (int i = 1; i < fill; ++i)
counter[i].merge(counter[i-1], comp);
this->swap(counter[fill-1]);
}
}
#endif /* __STL_MEMBER_TEMPLATES */
#ifdef __STL_USE_NAMESPACES
using __STD::slist;
#endif /* __STL_USE_NAMESPACES */
#endif /* __SGI_STL_SLIST_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -12,7 +12,7 @@
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
@@ -24,148 +24,23 @@
* purpose. It is provided "as is" without express or implied warranty.
*/
#ifndef STACK_H
#define STACK_H
#ifndef __SGI_STL_STACK_H
#define __SGI_STL_STACK_H
#include <function.h>
#include <heap.h>
#include <vector.h>
#include <deque.h>
#include <heap.h>
#include <stl_stack.h>
#include <stl_queue.h>
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class T, class Sequence = deque<T> >
#else
template <class T, class Sequence>
#endif
class stack {
friend bool operator==(const stack<T, Sequence>& x,
const stack<T, Sequence>& y);
friend bool operator<(const stack<T, Sequence>& x,
const stack<T, Sequence>& y);
public:
typedef typename Sequence::value_type value_type;
typedef typename Sequence::size_type size_type;
protected:
Sequence c;
public:
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
value_type& top() { return c.back(); }
const value_type& top() const { return c.back(); }
void push(const value_type& x) { c.push_back(x); }
void pop() { c.pop_back(); }
};
#ifdef __STL_USE_NAMESPACES
using __STD::stack;
using __STD::queue;
using __STD::priority_queue;
#endif /* __STL_USE_NAMESPACES */
template <class T, class Sequence>
bool operator==(const stack<T, Sequence>& x, const stack<T, Sequence>& y) {
return x.c == y.c;
}
#endif /* __SGI_STL_STACK_H */
template <class T, class Sequence>
bool operator<(const stack<T, Sequence>& x, const stack<T, Sequence>& y) {
return x.c < y.c;
}
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class T, class Sequence = deque<T> >
#else
template <class T, class Sequence>
#endif
class queue {
friend bool operator==(const queue<T, Sequence>& x, const queue<T, Sequence>& y);
friend bool operator<(const queue<T, Sequence>& x, const queue<T, Sequence>& y);
public:
typedef typename Sequence::value_type value_type;
typedef typename Sequence::size_type size_type;
protected:
Sequence c;
public:
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
value_type& front() { return c.front(); }
const value_type& front() const { return c.front(); }
value_type& back() { return c.back(); }
const value_type& back() const { return c.back(); }
void push(const value_type& x) { c.push_back(x); }
void pop() { c.pop_front(); }
};
template <class T, class Sequence>
bool operator==(const queue<T, Sequence>& x, const queue<T, Sequence>& y) {
return x.c == y.c;
}
template <class T, class Sequence>
bool operator<(const queue<T, Sequence>& x, const queue<T, Sequence>& y) {
return x.c < y.c;
}
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class T, class Sequence = vector<T>,
class Compare = less<typename Sequence::value_type> >
#else
template <class T, class Sequence, class Compare>
#endif
class priority_queue {
public:
typedef typename Sequence::value_type value_type;
typedef typename Sequence::size_type size_type;
protected:
Sequence c;
Compare comp;
public:
priority_queue() : c() {}
explicit priority_queue(const Compare& x) : c(), comp(x) {}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last, const Compare& x)
: c(first, last), comp(x) { make_heap(c.begin(), c.end(), comp); }
template <class InputIterator>
priority_queue(InputIterator first, InputIterator last)
: c(first, last) { make_heap(c.begin(), c.end(), comp); }
#else /* __STL_MEMBER_TEMPLATES */
priority_queue(const value_type* first, const value_type* last,
const Compare& x) : c(first, last), comp(x) {
make_heap(c.begin(), c.end(), comp);
}
priority_queue(const value_type* first, const value_type* last)
: c(first, last) { make_heap(c.begin(), c.end(), comp); }
#endif /* __STL_MEMBER_TEMPLATES */
bool empty() const { return c.empty(); }
size_type size() const { return c.size(); }
const value_type& top() const { return c.front(); }
void push(const value_type& x) {
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
c.push_back(x);
push_heap(c.begin(), c.end(), comp);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
c.clear();
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
void pop() {
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
pop_heap(c.begin(), c.end(), comp);
c.pop_back();
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
c.clear();
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
};
// no equality is provided
#endif
// Local Variables:
// mode:C++
// End:

View File

@@ -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:

View File

@@ -27,95 +27,32 @@
#ifndef __SGI_STL_TEMPBUF_H
#define __SGI_STL_TEMPBUF_H
#ifndef __SGI_STL_PAIR_H
#include <pair.h>
#endif
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#include <pair.h>
#ifndef __TYPE_TRAITS_H
#include <type_traits.h>
#endif
#ifndef __SGI_STL_INTERNAL_CONSTRUCT_H
#include <stl_construct.h>
#endif
#ifndef __SGI_STL_INTERNAL_TEMPBUF_H
#include <stl_tempbuf.h>
#endif
template <class T>
pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t len, T*) {
if (len > ptrdiff_t(INT_MAX / sizeof(T)))
len = INT_MAX / sizeof(T);
#ifdef __STL_USE_NAMESPACES
while (len > 0) {
T* tmp = (T*) malloc((size_t)len * sizeof(T));
if (tmp != 0)
return pair<T*, ptrdiff_t>(tmp, len);
len /= 2;
}
using __STD::get_temporary_buffer;
using __STD::return_temporary_buffer;
using __STD::temporary_buffer;
return pair<T*, ptrdiff_t>((T*)0, 0);
}
template <class T>
void return_temporary_buffer(T* p) {
free(p);
}
template <class ForwardIterator,
class T /* = iterator_traits<ForwardIterator>::value_type */>
class temporary_buffer {
private:
ptrdiff_t original_len;
ptrdiff_t len;
T* buffer;
void allocate_buffer() {
original_len = len;
buffer = 0;
if (len > (ptrdiff_t)(INT_MAX / sizeof(T)))
len = INT_MAX / sizeof(T);
while (len > 0) {
buffer = (T*) malloc(len * sizeof(T));
if (buffer)
break;
len /= 2;
}
}
void initialize_buffer(const T&, __true_type) {}
void initialize_buffer(const T& val, __false_type) {
uninitialized_fill_n(buffer, len, val);
}
public:
ptrdiff_t size() const { return len; }
ptrdiff_t requested_size() const { return original_len; }
T* begin() { return buffer; }
T* end() { return buffer + len; }
temporary_buffer(ForwardIterator first, ForwardIterator last) {
#ifdef __STL_USE_EXCEPTIONS
try {
#endif
len = 0;
distance(first, last, len);
allocate_buffer();
if (len > 0)
initialize_buffer(*first,
__type_traits<T>::has_trivial_default_constructor());
#ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
free(buffer);
buffer = 0;
len = 0;
throw;
}
#endif
}
~temporary_buffer() {
destroy(buffer, buffer + len);
free(buffer);
}
private:
temporary_buffer(const temporary_buffer&) {}
void operator=(const temporary_buffer&) {}
};
#endif /* __STL_USE_NAMESPACES */
#endif /* __SGI_STL_TEMPBUF_H */
// Local Variables:
// mode:C++
// End:

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,9 @@
#ifndef __TYPE_TRAITS_H
#define __TYPE_TRAITS_H
#ifndef __STL_CONFIG_H
#include <stl_config.h>
#endif
/*
This header file provides a framework for allowing compile time dispatch
@@ -88,7 +90,7 @@ struct __type_traits {
// have built-in __types_traits support, and essential for compilers
// that don't.
struct __type_traits<char> {
__STL_TEMPLATE_NULL struct __type_traits<char> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
@@ -96,7 +98,7 @@ struct __type_traits<char> {
typedef __true_type is_POD_type;
};
struct __type_traits<signed char> {
__STL_TEMPLATE_NULL struct __type_traits<signed char> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
@@ -104,7 +106,7 @@ struct __type_traits<signed char> {
typedef __true_type is_POD_type;
};
struct __type_traits<unsigned char> {
__STL_TEMPLATE_NULL struct __type_traits<unsigned char> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
@@ -112,7 +114,7 @@ struct __type_traits<unsigned char> {
typedef __true_type is_POD_type;
};
struct __type_traits<short> {
__STL_TEMPLATE_NULL struct __type_traits<short> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
@@ -120,7 +122,7 @@ struct __type_traits<short> {
typedef __true_type is_POD_type;
};
struct __type_traits<unsigned short> {
__STL_TEMPLATE_NULL struct __type_traits<unsigned short> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
@@ -128,7 +130,7 @@ struct __type_traits<unsigned short> {
typedef __true_type is_POD_type;
};
struct __type_traits<int> {
__STL_TEMPLATE_NULL struct __type_traits<int> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
@@ -136,7 +138,7 @@ struct __type_traits<int> {
typedef __true_type is_POD_type;
};
struct __type_traits<unsigned int> {
__STL_TEMPLATE_NULL struct __type_traits<unsigned int> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
@@ -144,7 +146,7 @@ struct __type_traits<unsigned int> {
typedef __true_type is_POD_type;
};
struct __type_traits<long> {
__STL_TEMPLATE_NULL struct __type_traits<long> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
@@ -152,7 +154,7 @@ struct __type_traits<long> {
typedef __true_type is_POD_type;
};
struct __type_traits<unsigned long> {
__STL_TEMPLATE_NULL struct __type_traits<unsigned long> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
@@ -160,7 +162,7 @@ struct __type_traits<unsigned long> {
typedef __true_type is_POD_type;
};
struct __type_traits<float> {
__STL_TEMPLATE_NULL struct __type_traits<float> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
@@ -168,7 +170,7 @@ struct __type_traits<float> {
typedef __true_type is_POD_type;
};
struct __type_traits<double> {
__STL_TEMPLATE_NULL struct __type_traits<double> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
@@ -176,7 +178,7 @@ struct __type_traits<double> {
typedef __true_type is_POD_type;
};
struct __type_traits<long double> {
__STL_TEMPLATE_NULL struct __type_traits<long double> {
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
@@ -225,3 +227,7 @@ struct __type_traits<unsigned char*> {
#endif /* __TYPE_TRAITS_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -27,507 +27,16 @@
#ifndef __SGI_STL_VECTOR_H
#define __SGI_STL_VECTOR_H
#include <stddef.h>
#include <algobase.h>
#include <alloc.h>
#include <stl_vector.h>
template <class T, class Alloc = alloc>
class vector {
public:
typedef T value_type;
typedef value_type* pointer;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator;
#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
typedef reverse_iterator<const_iterator, value_type, const_reference,
difference_type> const_reverse_iterator;
typedef reverse_iterator<iterator, value_type, reference, difference_type>
reverse_iterator;
#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
protected:
typedef simple_alloc<value_type, Alloc> data_allocator;
iterator start;
iterator finish;
iterator end_of_storage;
void insert_aux(iterator position, const T& x);
void deallocate() {
if (start) data_allocator::deallocate(start, end_of_storage - start);
}
void fill_initialize(size_type n, const T& value) {
start = allocate_and_fill(n, value);
finish = start + n;
end_of_storage = finish;
}
public:
iterator begin() { return start; }
const_iterator begin() const { return start; }
iterator end() { return finish; }
const_iterator end() const { return finish; }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
size_type size() const { return size_type(end() - begin()); }
size_type max_size() const { return size_type(-1) / sizeof(T); }
size_type capacity() const { return size_type(end_of_storage - begin()); }
bool empty() const { return begin() == end(); }
reference operator[](size_type n) { return *(begin() + n); }
const_reference operator[](size_type n) const { return *(begin() + n); }
vector() : start(0), finish(0), end_of_storage(0) {}
vector(size_type n, const T& value) { fill_initialize(n, value); }
vector(int n, const T& value) { fill_initialize(n, value); }
vector(long n, const T& value) { fill_initialize(n, value); }
explicit vector(size_type n) { fill_initialize(n, T()); }
vector(const vector<T, Alloc>& x) {
start = allocate_and_copy(x.end() - x.begin(), x.begin(), x.end());
finish = start + (x.end() - x.begin());
end_of_storage = finish;
}
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
vector(InputIterator first, InputIterator last) :
start(0), finish(0), end_of_storage(0) {
range_initialize(first, last, iterator_category(first));
}
#else /* __STL_MEMBER_TEMPLATES */
vector(const_iterator first, const_iterator last) {
size_type n = 0;
distance(first, last, n);
start = allocate_and_copy(n, first, last);
finish = start + n;
end_of_storage = finish;
}
#endif /* __STL_MEMBER_TEMPLATES */
~vector() {
destroy(start, finish);
deallocate();
}
vector<T, Alloc>& operator=(const vector<T, Alloc>& x);
void reserve(size_type n) {
if (capacity() < n) {
const size_type old_size = size();
iterator tmp = allocate_and_copy(n, start, finish);
destroy(start, finish);
deallocate();
start = tmp;
finish = tmp + old_size;
end_of_storage = start + n;
}
}
reference front() { return *begin(); }
const_reference front() const { return *begin(); }
reference back() { return *(end() - 1); }
const_reference back() const { return *(end() - 1); }
void push_back(const T& x) {
if (finish != end_of_storage) {
construct(finish, x);
++finish;
} else
insert_aux(end(), x);
}
void swap(vector<T, Alloc>& x) {
::swap(start, x.start);
::swap(finish, x.finish);
::swap(end_of_storage, x.end_of_storage);
}
iterator insert(iterator position, const T& x) {
size_type n = position - begin();
if (finish != end_of_storage && position == end()) {
construct(finish, x);
++finish;
} else
insert_aux(position, x);
return begin() + n;
}
iterator insert(iterator position) { return insert(position, T()); }
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void insert(iterator position, InputIterator first, InputIterator last) {
range_insert(position, first, last, iterator_category(first));
}
#else /* __STL_MEMBER_TEMPLATES */
void insert(iterator position,
const_iterator first, const_iterator last);
#endif /* __STL_MEMBER_TEMPLATES */
void insert (iterator pos, size_type n, const T& x);
void insert (iterator pos, int n, const T& x) {
insert(pos, (size_type) n, x);
}
void insert (iterator pos, long n, const T& x) {
insert(pos, (size_type) n, x);
}
void pop_back() {
--finish;
destroy(finish);
}
void erase(iterator position) {
if (position + 1 != end())
copy(position + 1, finish, position);
--finish;
destroy(finish);
}
void erase(iterator first, iterator last) {
iterator i = copy(last, finish, first);
destroy(i, finish);
finish = finish - (last - first);
}
void resize(size_type new_size, const T& x) {
if (new_size < size())
erase(begin() + new_size, end());
else
insert(end(), new_size - size(), x);
}
void resize(size_type new_size) { resize(new_size, T()); }
void clear() { erase(begin(), end()); }
protected:
iterator allocate_and_fill(size_type n, const T& x) {
iterator result = data_allocator::allocate(n);
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
uninitialized_fill_n(result, n, x);
return result;
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
data_allocator::deallocate(result, n);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
#ifdef __STL_MEMBER_TEMPLATES
template <class ForwardIterator>
iterator allocate_and_copy(size_type n,
ForwardIterator first, ForwardIterator last) {
iterator result = data_allocator::allocate(n);
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
uninitialized_copy(first, last, result);
return result;
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
data_allocator::deallocate(result, n);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
#else /* __STL_MEMBER_TEMPLATES */
iterator allocate_and_copy(size_type n,
const_iterator first, const_iterator last) {
iterator result = data_allocator::allocate(n);
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
uninitialized_copy(first, last, result);
return result;
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
data_allocator::deallocate(result, n);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
}
#endif /* __STL_MEMBER_TEMPLATES */
#ifdef __STL_MEMBER_TEMPLATES
template <class InputIterator>
void range_initialize(InputIterator first, InputIterator last,
input_iterator_tag) {
for ( ; first != last; ++first)
push_back(*first);
}
// This function is only called by the constructor. We have to worry
// about resource leaks, but not about maintaining invariants.
template <class ForwardIterator>
void range_initialize(ForwardIterator first, ForwardIterator last,
forward_iterator_tag) {
size_type n = 0;
distance(first, last, n);
start = allocate_and_copy(n, first, last);
finish = start + n;
end_of_storage = finish;
}
template <class InputIterator>
void range_insert(iterator pos,
InputIterator first, InputIterator last,
input_iterator_tag);
template <class ForwardIterator>
void range_insert(iterator pos,
ForwardIterator first, ForwardIterator last,
forward_iterator_tag);
#endif /* __STL_MEMBER_TEMPLATES */
};
template <class T, class Alloc>
inline bool operator==(const vector<T, Alloc>& x, const vector<T, Alloc>& y) {
return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
}
template <class T, class Alloc>
inline bool operator<(const vector<T, Alloc>& x, const vector<T, Alloc>& y) {
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
template <class T, class Alloc>
vector<T, Alloc>& vector<T, Alloc>::operator=(const vector<T, Alloc>& x) {
if (&x != this) {
if (x.size() > capacity()) {
iterator tmp = allocate_and_copy(x.end() - x.begin(),
x.begin(), x.end());
destroy(start, finish);
deallocate();
start = tmp;
end_of_storage = start + (x.end() - x.begin());
}
else if (size() >= x.size()) {
iterator i = copy(x.begin(), x.end(), begin());
destroy(i, finish);
}
else {
copy(x.begin(), x.begin() + size(), start);
uninitialized_copy(x.begin() + size(), x.end(), finish);
}
finish = start + x.size();
}
return *this;
}
template <class T, class Alloc>
void vector<T, Alloc>::insert_aux(iterator position, const T& x) {
if (finish != end_of_storage) {
construct(finish, *(finish - 1));
++finish;
T x_copy = x;
copy_backward(position, finish - 2, finish - 1);
*position = x_copy;
}
else {
const size_type old_size = size();
const size_type len = old_size != 0 ? 2 * old_size : 1;
iterator new_start = data_allocator::allocate(len);
iterator new_finish = new_start;
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
new_finish = uninitialized_copy(start, position, new_start);
construct(new_finish, x);
++new_finish;
new_finish = uninitialized_copy(position, finish, new_finish);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
destroy(new_start, new_finish);
data_allocator::deallocate(new_start, len);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
destroy(begin(), end());
deallocate();
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}
}
template <class T, class Alloc>
void vector<T, Alloc>::insert(iterator position, size_type n, const T& x) {
if (n != 0) {
if (size_type(end_of_storage - finish) >= n) {
T x_copy = x;
const size_type elems_after = finish - position;
iterator old_finish = finish;
if (elems_after > n) {
uninitialized_copy(finish - n, finish, finish);
finish += n;
copy_backward(position, old_finish - n, old_finish);
fill(position, position + n, x_copy);
}
else {
uninitialized_fill_n(finish, n - elems_after, x_copy);
finish += n - elems_after;
uninitialized_copy(position, old_finish, finish);
finish += elems_after;
fill(position, old_finish, x_copy);
}
}
else {
const size_type old_size = size();
const size_type len = old_size + max(old_size, n);
iterator new_start = data_allocator::allocate(len);
iterator new_finish = new_start;
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
new_finish = uninitialized_copy(start, position, new_start);
new_finish = uninitialized_fill_n(new_finish, n, x);
new_finish = uninitialized_copy(position, finish, new_finish);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
destroy(new_start, new_finish);
data_allocator::deallocate(new_start, len);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
destroy(start, finish);
deallocate();
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}
}
}
#ifdef __STL_MEMBER_TEMPLATES
template <class T, class Alloc> template <class InputIterator>
void vector<T, Alloc>::range_insert(iterator pos,
InputIterator first, InputIterator last,
input_iterator_tag) {
for ( ; first != last; ++first) {
pos = insert(pos, *first);
++pos;
}
}
template <class T, class Alloc> template <class ForwardIterator>
void vector<T, Alloc>::range_insert(iterator position,
ForwardIterator first,
ForwardIterator last,
forward_iterator_tag) {
if (first != last) {
size_type n = 0;
distance(first, last, n);
if (size_type(end_of_storage - finish) >= n) {
const size_type elems_after = finish - position;
iterator old_finish = finish;
if (elems_after > n) {
uninitialized_copy(finish - n, finish, finish);
finish += n;
copy_backward(position, old_finish - n, old_finish);
copy(first, last, position);
}
else {
ForwardIterator mid = first;
advance(mid, elems_after);
uninitialized_copy(mid, last, finish);
finish += n - elems_after;
uninitialized_copy(position, old_finish, finish);
finish += elems_after;
copy(first, mid, position);
}
}
else {
const size_type old_size = size();
const size_type len = old_size + max(old_size, n);
iterator new_start = data_allocator::allocate(len);
iterator new_finish = new_start;
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
new_finish = uninitialized_copy(start, position, new_start);
new_finish = uninitialized_copy(first, last, new_finish);
new_finish = uninitialized_copy(position, finish, new_finish);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
destroy(new_start, new_finish);
data_allocator::deallocate(new_start, len);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
destroy(start, finish);
deallocate();
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}
}
}
#else /* __STL_MEMBER_TEMPLATES */
template <class T, class Alloc>
void vector<T, Alloc>::insert(iterator position,
const_iterator first,
const_iterator last) {
if (first != last) {
size_type n = 0;
distance(first, last, n);
if (size_type(end_of_storage - finish) >= n) {
const size_type elems_after = finish - position;
iterator old_finish = finish;
if (elems_after > n) {
uninitialized_copy(finish - n, finish, finish);
finish += n;
copy_backward(position, old_finish - n, old_finish);
copy(first, last, position);
}
else {
uninitialized_copy(first + elems_after, last, finish);
finish += n - elems_after;
uninitialized_copy(position, old_finish, finish);
finish += elems_after;
copy(first, first + elems_after, position);
}
}
else {
const size_type old_size = size();
const size_type len = old_size + max(old_size, n);
iterator new_start = data_allocator::allocate(len);
iterator new_finish = new_start;
# ifdef __STL_USE_EXCEPTIONS
try {
# endif /* __STL_USE_EXCEPTIONS */
new_finish = uninitialized_copy(start, position, new_start);
new_finish = uninitialized_copy(first, last, new_finish);
new_finish = uninitialized_copy(position, finish, new_finish);
# ifdef __STL_USE_EXCEPTIONS
}
catch(...) {
destroy(new_start, new_finish);
data_allocator::deallocate(new_start, len);
throw;
}
# endif /* __STL_USE_EXCEPTIONS */
destroy(start, finish);
deallocate();
start = new_start;
finish = new_finish;
end_of_storage = new_start + len;
}
}
}
#endif /* __STL_MEMBER_TEMPLATES */
#ifdef __STL_USE_NAMESPACES
using __STD::vector;
#endif /* __STL_USE_NAMESPACES */
#endif /* __SGI_STL_VECTOR_H */
// Local Variables:
// mode:C++
// End:

View File

@@ -1,8 +0,0 @@
// -*- C++ -*- forwarding header.
// This file is part of the GNU ANSI C++ Library.
#ifndef __UTILITY__
#define __UTILITY__
#include <function.h>
#include <pair.h>
#endif

View File

@@ -1,7 +0,0 @@
// -*- C++ -*- forwarding header.
// This file is part of the GNU ANSI C++ Library.
#ifndef __VECTOR__
#define __VECTOR__
#include <vector.h>
#endif