mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 12:00:03 -05:00
update to 10/27 STL snapshot
From-SVN: r16311
This commit is contained in:
committed by
Jason Merrill
parent
9c82d0d1fd
commit
ff5b5c164a
@@ -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:
|
||||
|
||||
@@ -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 ; \
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
2927
libstdc++/stl/algo.h
2927
libstdc++/stl/algo.h
File diff suppressed because it is too large
Load Diff
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
2072
libstdc++/stl/rope.h
2072
libstdc++/stl/rope.h
File diff suppressed because it is too large
Load Diff
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
1073
libstdc++/stl/tree.h
1073
libstdc++/stl/tree.h
File diff suppressed because it is too large
Load Diff
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user