From 79f8bd54b87824aefef05ecc6431fb51215b1af7 Mon Sep 17 00:00:00 2001 From: jason Date: Wed, 2 Sep 1998 17:25:15 +0000 Subject: [PATCH] * algorithm alloc.h defalloc.h hash_map.h hash_set.h iterator memory pthread_alloc pthread_alloc.h rope ropeimpl.h stl_algo.h stl_algobase.h stl_alloc.h stl_bvector.h stl_config.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 tempbuf.h type_traits.h: Update to SGI STL 3.11. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@22190 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++/stl/ChangeLog | 13 + libstdc++/stl/algorithm | 1 + libstdc++/stl/alloc.h | 4 +- libstdc++/stl/defalloc.h | 11 +- libstdc++/stl/hash_map.h | 1 + libstdc++/stl/hash_set.h | 1 + libstdc++/stl/iterator | 6 +- libstdc++/stl/memory | 103 +- libstdc++/stl/pthread_alloc | 590 +++-- libstdc++/stl/pthread_alloc.h | 4 +- libstdc++/stl/rope | 2 +- libstdc++/stl/ropeimpl.h | 1939 +++++++-------- libstdc++/stl/stl_algo.h | 4358 ++++++++++++++++++---------------- libstdc++/stl/stl_algobase.h | 588 +++-- libstdc++/stl/stl_alloc.h | 888 ++++--- libstdc++/stl/stl_bvector.h | 896 ++++--- libstdc++/stl/stl_config.h | 198 +- libstdc++/stl/stl_construct.h | 50 +- libstdc++/stl/stl_deque.h | 1929 +++++++++------ libstdc++/stl/stl_function.h | 754 +++--- libstdc++/stl/stl_hash_fun.h | 36 +- libstdc++/stl/stl_hash_map.h | 500 ++-- libstdc++/stl/stl_hash_set.h | 450 ++-- libstdc++/stl/stl_hashtable.h | 1147 +++++---- libstdc++/stl/stl_heap.h | 317 ++- libstdc++/stl/stl_iterator.h | 906 +++---- libstdc++/stl/stl_list.h | 1003 +++++--- libstdc++/stl/stl_map.h | 229 +- libstdc++/stl/stl_multimap.h | 220 +- libstdc++/stl/stl_multiset.h | 208 +- libstdc++/stl/stl_numeric.h | 309 +-- libstdc++/stl/stl_pair.h | 40 +- libstdc++/stl/stl_queue.h | 178 +- libstdc++/stl/stl_raw_storage_iter.h | 34 +- libstdc++/stl/stl_relops.h | 24 +- libstdc++/stl/stl_rope.h | 3821 ++++++++++++++++------------- libstdc++/stl/stl_set.h | 204 +- libstdc++/stl/stl_slist.h | 1077 +++++---- libstdc++/stl/stl_stack.h | 73 +- libstdc++/stl/stl_tempbuf.h | 141 +- libstdc++/stl/stl_tree.h | 1614 +++++++------ libstdc++/stl/stl_uninitialized.h | 295 ++- libstdc++/stl/stl_vector.h | 983 +++++--- libstdc++/stl/tempbuf.h | 9 +- libstdc++/stl/type_traits.h | 158 +- 45 files changed, 15026 insertions(+), 11286 deletions(-) diff --git a/libstdc++/stl/ChangeLog b/libstdc++/stl/ChangeLog index c94d6a9d71b..ad471c3bcd2 100644 --- a/libstdc++/stl/ChangeLog +++ b/libstdc++/stl/ChangeLog @@ -1,3 +1,16 @@ +1998-09-02 Jason Merrill + + * algorithm alloc.h defalloc.h hash_map.h hash_set.h iterator + memory pthread_alloc pthread_alloc.h rope ropeimpl.h stl_algo.h + stl_algobase.h stl_alloc.h stl_bvector.h stl_config.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 + tempbuf.h type_traits.h: Update to SGI STL 3.11. + Fri Jul 10 15:20:09 1998 Klaus-Georg Adams * stl_tempbuf.h (temporary_buffer): Add missing typename. diff --git a/libstdc++/stl/algorithm b/libstdc++/stl/algorithm index 515e9bd25da..1ba584f06d4 100644 --- a/libstdc++/stl/algorithm +++ b/libstdc++/stl/algorithm @@ -29,6 +29,7 @@ #include #include +#include #include #include diff --git a/libstdc++/stl/alloc.h b/libstdc++/stl/alloc.h index 7cc96100605..f99a862316e 100644 --- a/libstdc++/stl/alloc.h +++ b/libstdc++/stl/alloc.h @@ -33,7 +33,9 @@ using __STD::single_client_alloc; #ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG using __STD::__malloc_alloc_oom_handler; #endif /* __STL_STATIC_TEMPLATE_MEMBER_BUG */ - +#ifdef __STL_USE_STD_ALLOCATORS +using __STD::allocator; +#endif /* __STL_USE_STD_ALLOCATORS */ #endif /* __STL_USE_NAMESPACES */ diff --git a/libstdc++/stl/defalloc.h b/libstdc++/stl/defalloc.h index 49690f8d6e0..0bfcc2c20a5 100644 --- a/libstdc++/stl/defalloc.h +++ b/libstdc++/stl/defalloc.h @@ -15,12 +15,13 @@ // Inclusion of this file is DEPRECATED. This is the original HP // default allocator. It is provided only for backward compatibility. -// +// This file WILL BE REMOVED in a future release. +// // 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. +// that requires an allocator with the HP-style interface. +// +// Standard-conforming allocators have a very different interface. The +// standard default allocator is declared in the header . #ifndef DEFALLOC_H #define DEFALLOC_H diff --git a/libstdc++/stl/hash_map.h b/libstdc++/stl/hash_map.h index 81cb5784f47..f3471627044 100644 --- a/libstdc++/stl/hash_map.h +++ b/libstdc++/stl/hash_map.h @@ -31,6 +31,7 @@ #include #endif +#include #include #ifdef __STL_USE_NAMESPACES diff --git a/libstdc++/stl/hash_set.h b/libstdc++/stl/hash_set.h index c938ccc467a..d3e93c0c26b 100644 --- a/libstdc++/stl/hash_set.h +++ b/libstdc++/stl/hash_set.h @@ -31,6 +31,7 @@ #include #endif +#include #include #ifdef __STL_USE_NAMESPACES diff --git a/libstdc++/stl/iterator b/libstdc++/stl/iterator index 90e6c9c8b68..4ddd208f275 100644 --- a/libstdc++/stl/iterator +++ b/libstdc++/stl/iterator @@ -29,8 +29,12 @@ #include #include -#include +#include /* XXX should use */ +#if 0 /* XXX define a flag for this */ +#include +#else #include +#endif #include #endif /* __SGI_STL_ITERATOR */ diff --git a/libstdc++/stl/memory b/libstdc++/stl/memory index a80658875ee..168843d5d1f 100644 --- a/libstdc++/stl/memory +++ b/libstdc++/stl/memory @@ -22,64 +22,83 @@ #include #include -// Note: auto_ptr is commented out in this release because the details -// of the interface are still being discussed by the C++ standardization -// committee. It will be included once the iterface is finalized. -#if 0 -#if defined(_MUTABLE_IS_KEYWORD) && defined(_EXPLICIT_IS_KEYWORD) && \ - defined(__STL_MEMBER_TEMPLATES) +#if defined(__STL_MEMBER_TEMPLATES) __STL_BEGIN_NAMESPACE -template class auto_ptr { +template class auto_ptr { private: - X* ptr; - mutable bool owns; + _Tp* _M_ptr; + public: - typedef X element_type; - explicit auto_ptr(X* p = 0) __STL_NOTHROW : ptr(p), owns(p) {} - auto_ptr(const auto_ptr& a) __STL_NOTHROW : ptr(a.ptr), owns(a.owns) { - a.owns = 0; + typedef _Tp element_type; + explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {} + auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {} + template auto_ptr(auto_ptr<_Tp1>& __a) __STL_NOTHROW + : _M_ptr(__a.release()) {} + auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW { + if (&__a != this) { + delete _M_ptr; + _M_ptr = __a.release(); + } + return *this; } - template auto_ptr(const auto_ptr& a) __STL_NOTHROW - : ptr(a.ptr), owns(a.owns) { - a.owns = 0; + template + auto_ptr& operator=(auto_ptr<_Tp1>& __a) __STL_NOTHROW { + if (__a.get() != this->get()) { + delete _M_ptr; + _M_ptr = __a.release(); + } + return *this; } + ~auto_ptr() __STL_NOTHROW { delete _M_ptr; } - auto_ptr& operator=(const auto_ptr& a) __STL_NOTHROW { - if (&a != this) { - if (owns) - delete ptr; - owns = a.owns; - ptr = a.ptr; - a.owns = 0; - } + _Tp& operator*() const __STL_NOTHROW { + return *_M_ptr; } - template auto_ptr& operator=(const auto_ptr& a) __STL_NOTHROW { - if (&a != this) { - if (owns) - delete ptr; - owns = a.owns; - ptr = a.ptr; - a.owns = 0; - } + _Tp* operator->() const __STL_NOTHROW { + return _M_ptr; + } + _Tp* get() const __STL_NOTHROW { + return _M_ptr; + } + _Tp* release() __STL_NOTHROW { + _Tp* __tmp = _M_ptr; + _M_ptr = 0; + return __tmp; } - ~auto_ptr() { - if (owns) - delete ptr; + void reset(_Tp* __p = 0) __STL_NOTHROW { + delete _M_ptr; + _M_ptr = __p; } - X& operator*() const __STL_NOTHROW { return *ptr; } - X* operator->() const __STL_NOTHROW { return ptr; } - X* get() const __STL_NOTHROW { return ptr; } - X* release const __STL_NOTHROW { owns = false; return ptr } + // According to the C++ standard, these conversions are required. Most + // present-day compilers, however, do not enforce that requirement---and, + // in fact, most present-day compilers do not support the language + // features that these conversions rely on. + +#ifdef __SGI_STL_USE_AUTO_PTR_CONVERSIONS + +private: + template struct auto_ptr_ref { + _Tp1* _M_ptr; + auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) {} + }; + +public: + auto_ptr(auto_ptr_ref<_Tp> __ref) __STL_NOTHROW + : _M_ptr(__ref._M_ptr) {} + template operator auto_ptr_ref<_Tp1>() __STL_NOTHROW + { return auto_ptr_ref<_Tp>(this.release()); } + template operator auto_ptr<_Tp1>() __STL_NOTHROW + { return auto_ptr<_Tp1>(this->release()) } + +#endif /* __SGI_STL_USE_AUTO_PTR_CONVERSIONS */ }; __STL_END_NAMESPACE -#endif /* mutable && explicit && member templates */ -#endif /* 0 */ - +#endif /* member templates */ #endif /* __SGI_STL_MEMORY */ diff --git a/libstdc++/stl/pthread_alloc b/libstdc++/stl/pthread_alloc index 4ca9d9e1f71..887d8e8a154 100644 --- a/libstdc++/stl/pthread_alloc +++ b/libstdc++/stl/pthread_alloc @@ -20,7 +20,7 @@ // 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, +// it in 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 @@ -35,308 +35,440 @@ __STL_BEGIN_NAMESPACE -// Note that this class has nonstatic members. We instantiate it once -// per thread. -template -class __pthread_alloc_template { - -private: - enum {ALIGN = 8}; - enum {MAX_BYTES = 128}; // power of 2 - enum {NFREELISTS = MAX_BYTES/ALIGN}; +#define __STL_DATA_ALIGNMENT 8 + +union _Pthread_alloc_obj { + union _Pthread_alloc_obj * __free_list_link; + char __client_data[__STL_DATA_ALIGNMENT]; /* The client sees this. */ +}; + +// Pthread allocators don't appear to the client to have meaningful +// instances. We do in fact need to associate some state with each +// thread. That state is represented by +// _Pthread_alloc_per_thread_state<_Max_size>. + +template +struct _Pthread_alloc_per_thread_state { + typedef _Pthread_alloc_obj __obj; + enum { _S_NFREELISTS = _Max_size/__STL_DATA_ALIGNMENT }; + _Pthread_alloc_obj* volatile __free_list[_S_NFREELISTS]; + _Pthread_alloc_per_thread_state<_Max_size> * __next; + // Free list link for list of available per thread structures. + // When one of these becomes available for reuse due to thread + // termination, any objects in its free list remain associated + // with it. The whole structure may then be used by a newly + // created thread. + _Pthread_alloc_per_thread_state() : __next(0) + { + memset((void *)__free_list, 0, _S_NFREELISTS * sizeof(__obj *)); + } + // Returns an object of size __n, and possibly adds to size n free list. + void *_M_refill(size_t __n); +}; - union obj { - union obj * free_list_link; - char client_data[ALIGN]; /* The client sees this. */ - }; +// Pthread-specific allocator. +// The argument specifies the largest object size allocated from per-thread +// free lists. Larger objects are allocated using malloc_alloc. +// Max_size must be a power of 2. +template +class _Pthread_alloc_template { - // Per instance state - obj* volatile free_list[NFREELISTS]; - __pthread_alloc_template* next; // Free list link +public: // but only for internal use: - 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); - } + typedef _Pthread_alloc_obj __obj; - // 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); + static char *_S_chunk_alloc(size_t __size, int &__nobjs); + + enum {_S_ALIGN = __STL_DATA_ALIGNMENT}; + + static size_t _S_round_up(size_t __bytes) { + return (((__bytes) + _S_ALIGN-1) & ~(_S_ALIGN - 1)); + } + static size_t _S_freelist_index(size_t __bytes) { + return (((__bytes) + _S_ALIGN-1)/_S_ALIGN - 1); + } +private: // Chunk allocation state. And other shared state. - // Protected by chunk_allocator_lock. - static pthread_mutex_t chunk_allocator_lock; - static char *start_free; - static char *end_free; - static size_t heap_size; - static __pthread_alloc_template* free_allocators; - static pthread_key_t key; - static bool key_initialized; - // Pthread key under which allocator is stored. - // Allocator instances that are currently unclaimed by any thread. - static void destructor(void *instance); - // Function to be called on thread exit to reclaim allocator - // instance. - static __pthread_alloc_template *new_allocator(); - // Return a recycled or new allocator instance. - static __pthread_alloc_template *get_allocator_instance(); - // ensure that the current thread has an associated - // allocator instance. - class lock { + // Protected by _S_chunk_allocator_lock. + static pthread_mutex_t _S_chunk_allocator_lock; + static char *_S_start_free; + static char *_S_end_free; + static size_t _S_heap_size; + static _Pthread_alloc_per_thread_state<_Max_size>* _S_free_per_thread_states; + static pthread_key_t _S_key; + static bool _S_key_initialized; + // Pthread key under which per thread state is stored. + // Allocator instances that are currently unclaimed by any thread. + static void _S_destructor(void *instance); + // Function to be called on thread exit to reclaim per thread + // state. + static _Pthread_alloc_per_thread_state<_Max_size> *_S_new_per_thread_state(); + // Return a recycled or new per thread state. + static _Pthread_alloc_per_thread_state<_Max_size> *_S_get_per_thread_state(); + // ensure that the current thread has an associated + // per thread state. + friend class _M_lock; + class _M_lock { public: - lock () { pthread_mutex_lock(&chunk_allocator_lock); } - ~lock () { pthread_mutex_unlock(&chunk_allocator_lock); } + _M_lock () { pthread_mutex_lock(&_S_chunk_allocator_lock); } + ~_M_lock () { pthread_mutex_unlock(&_S_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) + /* n must be > 0 */ + static void * allocate(size_t __n) { - obj * volatile * my_free_list; - obj * __RESTRICT result; - __pthread_alloc_template* a; + __obj * volatile * __my_free_list; + __obj * __RESTRICT __result; + _Pthread_alloc_per_thread_state<_Max_size>* __a; - if (n > MAX_BYTES) { - return(malloc(n)); + if (__n > _Max_size) { + return(malloc_alloc::allocate(__n)); } - if (!key_initialized || - !(a = (__pthread_alloc_template*) - pthread_getspecific(key))) { - a = get_allocator_instance(); + if (!_S_key_initialized || + !(__a = (_Pthread_alloc_per_thread_state<_Max_size>*) + pthread_getspecific(_S_key))) { + __a = _S_get_per_thread_state(); } - 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 = __a -> __free_list + _S_freelist_index(__n); + __result = *__my_free_list; + if (__result == 0) { + void *__r = __a -> _M_refill(_S_round_up(__n)); + return __r; } - *my_free_list = result -> free_list_link; - return (result); + *__my_free_list = __result -> __free_list_link; + return (__result); }; /* p may not be 0 */ - static void deallocate(void *p, size_t n) + static void deallocate(void *__p, size_t __n) { - obj *q = (obj *)p; - obj * volatile * my_free_list; - __pthread_alloc_template* a; + __obj *__q = (__obj *)__p; + __obj * volatile * __my_free_list; + _Pthread_alloc_per_thread_state<_Max_size>* __a; - if (n > MAX_BYTES) { - free(p); - return; + if (__n > _Max_size) { + malloc_alloc::deallocate(__p, __n); + return; } - if (!key_initialized || - !(a = (__pthread_alloc_template*) - pthread_getspecific(key))) { - a = get_allocator_instance(); + if (!_S_key_initialized || + !(__a = (_Pthread_alloc_per_thread_state<_Max_size> *) + pthread_getspecific(_S_key))) { + __a = _S_get_per_thread_state(); } - my_free_list = a->free_list + FREELIST_INDEX(n); - q -> free_list_link = *my_free_list; - *my_free_list = q; + __my_free_list = __a->__free_list + _S_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); + static void * reallocate(void *__p, size_t __old_sz, size_t __new_sz); } ; -typedef __pthread_alloc_template pthread_alloc; +typedef _Pthread_alloc_template<> pthread_alloc; -template -void __pthread_alloc_template::destructor(void * instance) +template +void _Pthread_alloc_template<_Max_size>::_S_destructor(void * __instance) { - __pthread_alloc_template* a = - (__pthread_alloc_template*)instance; - a -> next = free_allocators; - free_allocators = a; + _M_lock __lock_instance; // Need to acquire lock here. + _Pthread_alloc_per_thread_state<_Max_size>* __s = + (_Pthread_alloc_per_thread_state<_Max_size> *)__instance; + __s -> __next = _S_free_per_thread_states; + _S_free_per_thread_states = __s; } -template -__pthread_alloc_template* -__pthread_alloc_template::new_allocator() -{ - if (0 != free_allocators) { - __pthread_alloc_template* result = free_allocators; - free_allocators = free_allocators -> next; - return result; +template +_Pthread_alloc_per_thread_state<_Max_size> * +_Pthread_alloc_template<_Max_size>::_S_new_per_thread_state() +{ + /* lock already held here. */ + if (0 != _S_free_per_thread_states) { + _Pthread_alloc_per_thread_state<_Max_size> *__result = + _S_free_per_thread_states; + _S_free_per_thread_states = _S_free_per_thread_states -> __next; + return __result; } else { - return new __pthread_alloc_template; + return new _Pthread_alloc_per_thread_state<_Max_size>; } } -template -__pthread_alloc_template* -__pthread_alloc_template::get_allocator_instance() +template +_Pthread_alloc_per_thread_state<_Max_size> * +_Pthread_alloc_template<_Max_size>::_S_get_per_thread_state() { - __pthread_alloc_template* result; - if (!key_initialized) { - /*REFERENCED*/ - lock lock_instance; - if (!key_initialized) { - if (pthread_key_create(&key, destructor)) { - abort(); // failed - } - key_initialized = true; - } + /*REFERENCED*/ + _M_lock __lock_instance; // Need to acquire lock here. + _Pthread_alloc_per_thread_state<_Max_size> * __result; + if (!_S_key_initialized) { + if (pthread_key_create(&_S_key, _S_destructor)) { + abort(); // failed + } + _S_key_initialized = true; } - result = new_allocator(); - if (pthread_setspecific(key, result)) abort(); - return result; + __result = _S_new_per_thread_state(); + if (pthread_setspecific(_S_key, __result)) abort(); + return __result; } -/* We allocate memory in large chunks in order to avoid fragmenting */ -/* the malloc heap too much. */ -/* We assume that size is properly aligned. */ -template -char *__pthread_alloc_template -::chunk_alloc(size_t size, int &nobjs) +/* We allocate memory in large chunks in order to avoid fragmenting */ +/* the malloc heap too much. */ +/* We assume that size is properly aligned. */ +template +char *_Pthread_alloc_template<_Max_size> +::_S_chunk_alloc(size_t __size, int &__nobjs) { { - char * result; - size_t total_bytes; - size_t bytes_left; + 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); + _M_lock __lock_instance; // Acquire lock for this routine + + __total_bytes = __size * __nobjs; + __bytes_left = _S_end_free - _S_start_free; + if (__bytes_left >= __total_bytes) { + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); + } else if (__bytes_left >= __size) { + __nobjs = __bytes_left/__size; + __total_bytes = __size * __nobjs; + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); } else { - size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4); - // Try to make use of the left-over piece. - if (bytes_left > 0) { - __pthread_alloc_template* a = - (__pthread_alloc_template*)pthread_getspecific(key); - obj * volatile * my_free_list = - a->free_list + FREELIST_INDEX(bytes_left); - - ((obj *)start_free) -> free_list_link = *my_free_list; - *my_free_list = (obj *)start_free; - } -# ifdef _SGI_SOURCE - // Try to get memory that's aligned on something like a - // cache line boundary, so as to avoid parceling out - // parts of the same line to different threads and thus - // possibly different processors. - { - const int cache_line_size = 128; // probable upper bound - bytes_to_get &= ~(cache_line_size-1); - start_free = (char *)memalign(cache_line_size, bytes_to_get); - if (0 == start_free) { - start_free = (char *)malloc_alloc::allocate(bytes_to_get); - } - } -# else /* !SGI_SOURCE */ - start_free = (char *)malloc_alloc::allocate(bytes_to_get); + size_t __bytes_to_get = + 2 * __total_bytes + _S_round_up(_S_heap_size >> 4); + // Try to make use of the left-over piece. + if (__bytes_left > 0) { + _Pthread_alloc_per_thread_state<_Max_size>* __a = + (_Pthread_alloc_per_thread_state<_Max_size>*) + pthread_getspecific(_S_key); + __obj * volatile * __my_free_list = + __a->__free_list + _S_freelist_index(__bytes_left); + + ((__obj *)_S_start_free) -> __free_list_link = *__my_free_list; + *__my_free_list = (__obj *)_S_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); + _S_start_free = (char *)memalign(__cache_line_size, __bytes_to_get); + if (0 == _S_start_free) { + _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get); + } + } +# else /* !SGI_SOURCE */ + _S_start_free = (char *)malloc_alloc::allocate(__bytes_to_get); # endif - heap_size += bytes_to_get; - end_free = start_free + bytes_to_get; + _S_heap_size += __bytes_to_get; + _S_end_free = _S_start_free + __bytes_to_get; } } // lock is released here - return(chunk_alloc(size, nobjs)); + return(_S_chunk_alloc(__size, __nobjs)); } /* Returns an object of size n, and optionally adds to size n free list.*/ -/* We assume that n is properly aligned. */ -/* We hold the allocation lock. */ -template -void *__pthread_alloc_template -::refill(size_t n) +/* We assume that n is properly aligned. */ +/* We hold the allocation lock. */ +template +void *_Pthread_alloc_per_thread_state<_Max_size> +::_M_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); + int __nobjs = 128; + char * __chunk = + _Pthread_alloc_template<_Max_size>::_S_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); + __my_free_list = __free_list + + _Pthread_alloc_template<_Max_size>::_S_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; - } + __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); + return(__result); } -template -void *__pthread_alloc_template -::reallocate(void *p, size_t old_sz, size_t new_sz) +template +void *_Pthread_alloc_template<_Max_size> +::reallocate(void *__p, size_t __old_sz, size_t __new_sz) { - void * result; - size_t copy_sz; + void * __result; + size_t __copy_sz; - if (old_sz > MAX_BYTES && new_sz > MAX_BYTES) { - return(realloc(p, new_sz)); + if (__old_sz > _Max_size + && __new_sz > _Max_size) { + 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); + if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p); + __result = allocate(__new_sz); + __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz; + memcpy(__result, __p, __copy_sz); + deallocate(__p, __old_sz); + return(__result); } -template -__pthread_alloc_template * -__pthread_alloc_template::free_allocators = 0; +template +_Pthread_alloc_per_thread_state<_Max_size> * +_Pthread_alloc_template<_Max_size>::_S_free_per_thread_states = 0; -template -pthread_key_t __pthread_alloc_template::key; +template +pthread_key_t _Pthread_alloc_template<_Max_size>::_S_key; -template -bool __pthread_alloc_template::key_initialized = false; +template +bool _Pthread_alloc_template<_Max_size>::_S_key_initialized = false; -template -pthread_mutex_t __pthread_alloc_template::chunk_allocator_lock +template +pthread_mutex_t _Pthread_alloc_template<_Max_size>::_S_chunk_allocator_lock = PTHREAD_MUTEX_INITIALIZER; -template -char *__pthread_alloc_template -::start_free = 0; +template +char *_Pthread_alloc_template<_Max_size> +::_S_start_free = 0; + +template +char *_Pthread_alloc_template<_Max_size> +::_S_end_free = 0; + +template +size_t _Pthread_alloc_template<_Max_size> +::_S_heap_size = 0; + +#ifdef __STL_USE_STD_ALLOCATORS + +template +class pthread_allocator { + typedef pthread_alloc _S_Alloc; // The underlying allocator. +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template struct rebind { + typedef pthread_allocator<_U> other; + }; + + pthread_allocator() __STL_NOTHROW {} + pthread_allocator(const pthread_allocator& a) __STL_NOTHROW {} + template pthread_allocator(const pthread_allocator<_U>&) + __STL_NOTHROW {} + ~pthread_allocator() __STL_NOTHROW {} + + pointer address(reference __x) const { return &__x; } + const_pointer address(const_reference __x) const { return &__x; } + + // __n is permitted to be 0. The C++ standard says nothing about what + // the return value is when __n == 0. + _Tp* allocate(size_type __n, const void* = 0) { + return __n != 0 ? static_cast<_Tp*>(_S_Alloc::allocate(__n * sizeof(_Tp))) + : 0; + } + + // p is not permitted to be a null pointer. + void deallocate(pointer __p, size_type __n) + { _S_Alloc::deallocate(__p, __n * sizeof(_Tp)); } + + size_type max_size() const __STL_NOTHROW + { return size_t(-1) / sizeof(_Tp); } + + void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } + void destroy(pointer _p) { _p->~_Tp(); } +}; + +template<> +class pthread_allocator { +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template struct rebind { + typedef pthread_allocator<_U> other; + }; +}; + +template +inline bool operator==(const _Pthread_alloc_template<_Max_size>&, + const _Pthread_alloc_template<_Max_size>&) +{ + return true; +} + +template +inline bool operator==(const pthread_allocator<_T1>&, + const pthread_allocator<_T2>& a2) +{ + return true; +} + +template +inline bool operator!=(const pthread_allocator<_T1>&, + const pthread_allocator<_T2>&) +{ + return false; +} + +template +struct _Alloc_traits<_Tp, _Pthread_alloc_template<_Max_size> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max_size> > _Alloc_type; + typedef __allocator<_Tp, _Pthread_alloc_template<_Max_size> > + allocator_type; +}; + +template +struct _Alloc_traits<_Tp, __allocator<_U, _Pthread_alloc_template<_Max> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, _Pthread_alloc_template<_Max> > _Alloc_type; + typedef __allocator<_Tp, _Pthread_alloc_template<_Max> > allocator_type; +}; + +template +struct _Alloc_traits<_Tp, pthread_allocator<_U> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, _Pthread_alloc_template<> > _Alloc_type; + typedef pthread_allocator<_Tp> allocator_type; +}; -template -char *__pthread_alloc_template -::end_free = 0; -template -size_t __pthread_alloc_template -::heap_size = 0; +#endif /* __STL_USE_STD_ALLOCATORS */ __STL_END_NAMESPACE diff --git a/libstdc++/stl/pthread_alloc.h b/libstdc++/stl/pthread_alloc.h index 0a2debb74bd..774ef04edc8 100644 --- a/libstdc++/stl/pthread_alloc.h +++ b/libstdc++/stl/pthread_alloc.h @@ -18,8 +18,8 @@ #ifdef __STL_USE_NAMESPACES -using __STD::__pthread_alloc_template; -using __STL::pthread_alloc; +using __STD::_Pthread_alloc_template; +using __STD::pthread_alloc; #endif /* __STL_USE_NAMESPACES */ diff --git a/libstdc++/stl/rope b/libstdc++/stl/rope index 9ef738241d7..f861500000b 100644 --- a/libstdc++/stl/rope +++ b/libstdc++/stl/rope @@ -15,7 +15,7 @@ #define __SGI_STL_ROPE #include -#include +#include #include #include #include diff --git a/libstdc++/stl/ropeimpl.h b/libstdc++/stl/ropeimpl.h index b4af525c38e..18bb2c9ec9d 100644 --- a/libstdc++/stl/ropeimpl.h +++ b/libstdc++/stl/ropeimpl.h @@ -15,8 +15,8 @@ * You should not attempt to use it directly. */ -# include -# include +# include /* XXX should use */ +# include /* XXX should use */ __STL_BEGIN_NAMESPACE @@ -25,45 +25,46 @@ __STL_BEGIN_NAMESPACE #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. +// if necessary. Assumes _M_path_end[leaf_index] and leaf_pos are correct. // Results in a valid buf_ptr if the iterator can be legitimately // dereferenced. -template -void __rope_iterator_base::setbuf -(__rope_iterator_base &x) +template +void _Rope_iterator_base<_CharT,_Alloc>::_S_setbuf( + _Rope_iterator_base<_CharT,_Alloc>& __x) { - const RopeBase * leaf = x.path_end[x.leaf_index]; - size_t leaf_pos = x.leaf_pos; - size_t pos = x.current_pos; - - switch(leaf -> tag) { - case RopeBase::leaf: - x.buf_start = ((__rope_RopeLeaf *)leaf) -> data; - x.buf_ptr = x.buf_start + (pos - leaf_pos); - x.buf_end = x.buf_start + leaf -> size; + const _RopeRep* __leaf = __x._M_path_end[__x._M_leaf_index]; + size_t __leaf_pos = __x._M_leaf_pos; + size_t __pos = __x._M_current_pos; + + switch(__leaf->_M_tag) { + case _RopeRep::_S_leaf: + __x._M_buf_start = + ((_Rope_RopeLeaf<_CharT,_Alloc>*)__leaf)->_M_data; + __x._M_buf_ptr = __x._M_buf_start + (__pos - __leaf_pos); + __x._M_buf_end = __x._M_buf_start + __leaf->_M_size; break; - case RopeBase::function: - case RopeBase::substringfn: + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: { - size_t len = iterator_buf_len; - size_t buf_start_pos = leaf_pos; - size_t leaf_end = leaf_pos + leaf -> size; - char_producer *fn = - ((__rope_RopeFunction *)leaf) -> fn; - - if (buf_start_pos + len <= pos) { - buf_start_pos = pos - len/4; - if (buf_start_pos + len > leaf_end) { - buf_start_pos = leaf_end - len; + size_t __len = _S_iterator_buf_len; + size_t __buf_start_pos = __leaf_pos; + size_t __leaf_end = __leaf_pos + __leaf->_M_size; + char_producer<_CharT>* __fn = + ((_Rope_RopeFunction<_CharT,_Alloc>*)__leaf)->_M_fn; + + if (__buf_start_pos + __len <= __pos) { + __buf_start_pos = __pos - __len/4; + if (__buf_start_pos + __len > __leaf_end) { + __buf_start_pos = __leaf_end - __len; } } - if (buf_start_pos + len > leaf_end) { - len = leaf_end - buf_start_pos; + if (__buf_start_pos + __len > __leaf_end) { + __len = __leaf_end - __buf_start_pos; } - (*fn)(buf_start_pos - leaf_pos, len, x.tmp_buf); - x.buf_ptr = x.tmp_buf + (pos - buf_start_pos); - x.buf_start = x.tmp_buf; - x.buf_end = x.tmp_buf + len; + (*__fn)(__buf_start_pos - __leaf_pos, __len, __x._M_tmp_buf); + __x._M_buf_ptr = __x._M_tmp_buf + (__pos - __buf_start_pos); + __x._M_buf_start = __x._M_tmp_buf; + __x._M_buf_end = __x._M_tmp_buf + __len; } break; default: @@ -73,339 +74,305 @@ void __rope_iterator_base::setbuf // Set path and buffer inside a rope iterator. We assume that // pos and root are already set. -template -void __rope_iterator_base::setcache -(__rope_iterator_base &x) +template +void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache +(_Rope_iterator_base<_CharT,_Alloc>& __x) { - const RopeBase * path[RopeBase::max_rope_depth+1]; - const RopeBase * curr_rope; - int curr_depth = -1; /* index into path */ - size_t curr_start_pos = 0; - size_t pos = x.current_pos; - unsigned char dirns = 0; // Bit vector indicating right turns in the path - - __stl_assert(pos <= x.root -> size); - if (pos >= x.root -> size) { - x.buf_ptr = 0; + const _RopeRep* __path[_RopeRep::_S_max_rope_depth+1]; + const _RopeRep* __curr_rope; + int __curr_depth = -1; /* index into path */ + size_t __curr_start_pos = 0; + size_t __pos = __x._M_current_pos; + unsigned char __dirns = 0; // Bit vector marking right turns in the path + + __stl_assert(__pos <= __x._M_root->_M_size); + if (__pos >= __x._M_root->_M_size) { + __x._M_buf_ptr = 0; return; } - curr_rope = x.root; - if (0 != curr_rope -> c_string) { + __curr_rope = __x._M_root; + if (0 != __curr_rope->_M_c_string) { /* Treat the root as a leaf. */ - x.buf_start = curr_rope -> c_string; - x.buf_end = curr_rope -> c_string + curr_rope -> size; - x.buf_ptr = curr_rope -> c_string + pos; - x.path_end[0] = curr_rope; - x.leaf_index = 0; - x.leaf_pos = 0; + __x._M_buf_start = __curr_rope->_M_c_string; + __x._M_buf_end = __curr_rope->_M_c_string + __curr_rope->_M_size; + __x._M_buf_ptr = __curr_rope->_M_c_string + __pos; + __x._M_path_end[0] = __curr_rope; + __x._M_leaf_index = 0; + __x._M_leaf_pos = 0; return; } for(;;) { - ++curr_depth; - __stl_assert(curr_depth <= RopeBase::max_rope_depth); - path[curr_depth] = curr_rope; - switch(curr_rope -> tag) { - case RopeBase::leaf: - case RopeBase::function: - case RopeBase::substringfn: - x.leaf_pos = curr_start_pos; + ++__curr_depth; + __stl_assert(__curr_depth <= _RopeRep::_S_max_rope_depth); + __path[__curr_depth] = __curr_rope; + switch(__curr_rope->_M_tag) { + case _RopeRep::_S_leaf: + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: + __x._M_leaf_pos = __curr_start_pos; goto done; - case RopeBase::concat: + case _RopeRep::_S_concat: { - __rope_RopeConcatenation *c = - (__rope_RopeConcatenation *)curr_rope; - RopeBase * left = c -> left; - size_t left_len = left -> size; + _Rope_RopeConcatenation<_CharT,_Alloc>* __c = + (_Rope_RopeConcatenation<_CharT,_Alloc>*)__curr_rope; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; - dirns <<= 1; - if (pos >= curr_start_pos + left_len) { - dirns |= 1; - curr_rope = c -> right; - curr_start_pos += left_len; + __dirns <<= 1; + if (__pos >= __curr_start_pos + __left_len) { + __dirns |= 1; + __curr_rope = __c->_M_right; + __curr_start_pos += __left_len; } else { - curr_rope = left; + __curr_rope = __left; } } break; } } done: - // Copy last section of path into path_end. + // Copy last section of path into _M_path_end. { - int i = -1; - int j = curr_depth + 1 - path_cache_len; + int __i = -1; + int __j = __curr_depth + 1 - _S_path_cache_len; - if (j < 0) j = 0; - while (j <= curr_depth) { - x.path_end[++i] = path[j++]; + if (__j < 0) __j = 0; + while (__j <= __curr_depth) { + __x._M_path_end[++__i] = __path[__j++]; } - x.leaf_index = i; + __x._M_leaf_index = __i; } - x.path_directions = dirns; - setbuf(x); + __x._M_path_directions = __dirns; + _S_setbuf(__x); } // Specialized version of the above. Assumes that // the path cache is valid for the previous position. -template -void __rope_iterator_base::setcache_for_incr -(__rope_iterator_base &x) +template +void _Rope_iterator_base<_CharT,_Alloc>::_S_setcache_for_incr +(_Rope_iterator_base<_CharT,_Alloc>& __x) { - int current_index = x.leaf_index; - const RopeBase * current_node = x.path_end[current_index]; - size_t len = current_node -> size; - size_t node_start_pos = x.leaf_pos; - unsigned char dirns = x.path_directions; - __rope_RopeConcatenation * c; - - __stl_assert(x.current_pos <= x.root -> size); - if (x.current_pos - node_start_pos < len) { + int __current_index = __x._M_leaf_index; + const _RopeRep* __current_node = __x._M_path_end[__current_index]; + size_t __len = __current_node->_M_size; + size_t __node_start_pos = __x._M_leaf_pos; + unsigned char __dirns = __x._M_path_directions; + _Rope_RopeConcatenation<_CharT,_Alloc>* __c; + + __stl_assert(__x._M_current_pos <= __x._M_root->_M_size); + if (__x._M_current_pos - __node_start_pos < __len) { /* More stuff in this leaf, we just didn't cache it. */ - setbuf(x); + _S_setbuf(__x); return; } - __stl_assert(node_start_pos + len == x.current_pos); + __stl_assert(__node_start_pos + __len == __x._M_current_pos); // node_start_pos is starting position of last_node. - while (--current_index >= 0) { - if (!(dirns & 1) /* Path turned left */) break; - current_node = x.path_end[current_index]; - c = (__rope_RopeConcatenation *)current_node; + while (--__current_index >= 0) { + if (!(__dirns & 1) /* Path turned left */) + break; + __current_node = __x._M_path_end[__current_index]; + __c = (_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node; // Otherwise we were in the right child. Thus we should pop // the concatenation node. - node_start_pos -= c -> left -> size; - dirns >>= 1; + __node_start_pos -= __c->_M_left->_M_size; + __dirns >>= 1; } - if (current_index < 0) { + if (__current_index < 0) { // We underflowed the cache. Punt. - setcache(x); + _S_setcache(__x); return; } - current_node = x.path_end[current_index]; - c = (__rope_RopeConcatenation *)current_node; + __current_node = __x._M_path_end[__current_index]; + __c = (_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node; // current_node is a concatenation node. We are positioned on the first // character in its right child. // node_start_pos is starting position of current_node. - node_start_pos += c -> left -> size; - current_node = c -> right; - x.path_end[++current_index] = current_node; - dirns |= 1; - while (RopeBase::concat == current_node -> tag) { - ++current_index; - if (path_cache_len == current_index) { - int i; - for (i = 0; i < path_cache_len-1; i++) { - x.path_end[i] = x.path_end[i+1]; + __node_start_pos += __c->_M_left->_M_size; + __current_node = __c->_M_right; + __x._M_path_end[++__current_index] = __current_node; + __dirns |= 1; + while (_RopeRep::_S_concat == __current_node->_M_tag) { + ++__current_index; + if (_S_path_cache_len == __current_index) { + int __i; + for (__i = 0; __i < _S_path_cache_len-1; __i++) { + __x._M_path_end[__i] = __x._M_path_end[__i+1]; } - --current_index; + --__current_index; } - current_node = - ((__rope_RopeConcatenation *)current_node) -> left; - x.path_end[current_index] = current_node; - dirns <<= 1; + __current_node = + ((_Rope_RopeConcatenation<_CharT,_Alloc>*)__current_node)->_M_left; + __x._M_path_end[__current_index] = __current_node; + __dirns <<= 1; // node_start_pos is unchanged. } - x.leaf_index = current_index; - x.leaf_pos = node_start_pos; - x.path_directions = dirns; - setbuf(x); + __x._M_leaf_index = __current_index; + __x._M_leaf_pos = __node_start_pos; + __x._M_path_directions = __dirns; + _S_setbuf(__x); } -template -void __rope_iterator_base::incr(size_t n) { - current_pos += n; - if (0 != buf_ptr) { - size_t chars_left = buf_end - buf_ptr; - if (chars_left > n) { - buf_ptr += n; - } else if (chars_left == n) { - buf_ptr += n; - setcache_for_incr(*this); +template +void _Rope_iterator_base<_CharT,_Alloc>::_M_incr(size_t __n) { + _M_current_pos += __n; + if (0 != _M_buf_ptr) { + size_t __chars_left = _M_buf_end - _M_buf_ptr; + if (__chars_left > __n) { + _M_buf_ptr += __n; + } else if (__chars_left == __n) { + _M_buf_ptr += __n; + _S_setcache_for_incr(*this); } else { - buf_ptr = 0; + _M_buf_ptr = 0; } } } -template -void __rope_iterator_base::decr(size_t n) { - if (0 != buf_ptr) { - size_t chars_left = buf_ptr - buf_start; - if (chars_left >= n) { - buf_ptr -= n; +template +void _Rope_iterator_base<_CharT,_Alloc>::_M_decr(size_t __n) { + if (0 != _M_buf_ptr) { + size_t __chars_left = _M_buf_ptr - _M_buf_start; + if (__chars_left >= __n) { + _M_buf_ptr -= __n; } else { - buf_ptr = 0; + _M_buf_ptr = 0; } } - current_pos -= n; + _M_current_pos -= __n; } -template -void __rope_iterator::check() { - if (root_rope -> tree_ptr != root) { - // Rope was modified. Get things fixed up. - RopeBase::unref(root); - root = root_rope -> tree_ptr; - RopeBase::ref(root); - buf_ptr = 0; +template +void _Rope_iterator<_CharT,_Alloc>::_M_check() { + if (_M_root_rope->_M_tree_ptr != _M_root) { + // _Rope was modified. Get things fixed up. + _RopeRep::_S_unref(_M_root); + _M_root = _M_root_rope->_M_tree_ptr; + _RopeRep::_S_ref(_M_root); + _M_buf_ptr = 0; } } -template -inline __rope_const_iterator::__rope_const_iterator -(const __rope_iterator & x) -: __rope_iterator_base(x) { } - -template -inline __rope_iterator::__rope_iterator -(rope& r, size_t pos) - : __rope_iterator_base(r.tree_ptr, pos), root_rope(&r) { - RopeBase::ref(root); -} - -template -inline size_t rope::char_ptr_len(const charT *s) +template +inline +_Rope_const_iterator<_CharT, _Alloc>::_Rope_const_iterator( + const _Rope_iterator<_CharT,_Alloc>& __x) +: _Rope_iterator_base<_CharT,_Alloc>(__x) +{ } + +template +inline _Rope_iterator<_CharT,_Alloc>::_Rope_iterator( + rope<_CharT,_Alloc>& __r, size_t __pos) +: _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos), + _M_root_rope(&__r) { - const charT *p = s; - - while (!is0(*p)) { ++p; } - return(p - s); + _RopeRep::_S_ref(_M_root); } -template -rope::RopeLeaf * -rope::RopeLeaf_from_char_ptr(__GC_CONST charT *s, size_t size) +template +inline size_t +rope<_CharT,_Alloc>::_S_char_ptr_len(const _CharT* __s) { - RopeLeaf *t = LAlloc::allocate(); + const _CharT* __p = __s; - t -> tag = RopeBase::leaf; - if (__is_basic_char_type((charT *)0)) { - // already eos terminated. - t -> c_string = s; - } else { - t -> c_string = 0; - } - t -> is_balanced = true; - t -> depth = 0; - t -> size = size; - t -> data = s; -# ifndef __GC - t -> refcount = 1; - t -> init_refcount_lock(); -# endif - return (t); + while (!_S_is0(*__p)) { ++__p; } + return (__p - __s); } -# ifdef __GC -template -void __rope_RopeBase::fn_finalization_proc(void * tree, void *) -{ - delete ((__rope_RopeFunction *)tree) -> fn; -} -# endif - -template -rope::RopeFunction * -rope::RopeFunction_from_fn -(char_producer *fn, size_t size, bool delete_fn) -{ - if (0 == size) return 0; - RopeFunction *t = FAlloc::allocate(); - t -> tag = RopeBase::function; - t -> c_string = 0; - t -> is_balanced = true; - t -> depth = 0; - t -> size = size; - t -> fn = fn; -# ifdef __GC - if (delete_fn) { - GC_REGISTER_FINALIZER(t, RopeBase::fn_finalization_proc, 0, 0, 0); - } -# else - t -> delete_when_done = delete_fn; - t -> refcount = 1; - t -> init_refcount_lock(); -# endif - return (t); -} #ifndef __GC -template -inline void __rope_RopeBase::free_c_string() +template +inline void _Rope_RopeRep<_CharT,_Alloc>::_M_free_c_string() { - charT * cstr = c_string; - if (0 != cstr) { - size_t sz = size + 1; - destroy(cstr, cstr + sz); - DataAlloc::deallocate(cstr, sz); + _CharT* __cstr = _M_c_string; + if (0 != __cstr) { + size_t __size = _M_size + 1; + destroy(__cstr, __cstr + __size); + _Data_deallocate(__cstr, __size); } } -template -inline void __rope_RopeBase::free_string(charT* s, size_t n) + +template +#ifdef __STL_USE_STD_ALLOCATORS + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string(_CharT* __s, + size_t __n, + allocator_type __a) +#else + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string(_CharT* __s, + size_t __n) +#endif { - if (!__is_basic_char_type((charT *)0)) { - destroy(s, s + n); + if (!_S_is_basic_char_type((_CharT*)0)) { + destroy(__s, __s + __n); } - DataAlloc::deallocate(s, rounded_up_size(n)); +// This has to be a static member, so this gets a bit messy +# ifdef __STL_USE_STD_ALLOCATORS + __a.deallocate( + __s, _Rope_RopeLeaf<_CharT,_Alloc>::_S_rounded_up_size(__n)); +# else + _Data_deallocate( + __s, _Rope_RopeLeaf<_CharT,_Alloc>::_S_rounded_up_size(__n)); +# endif } -template -void __rope_RopeBase::free_tree() + +// There are several reasons for not doing this with virtual destructors +// and a class specific delete operator: +// - A class specific delete operator can't easily get access to +// allocator instances if we need them. +// - Any virtual function would need a 4 or byte vtable pointer; +// this only requires a one byte tag per object. +template +void _Rope_RopeRep<_CharT,_Alloc>::_M_free_tree() { - switch(tag) { - case leaf: + switch(_M_tag) { + case _S_leaf: { - __rope_RopeLeaf * l = - (__rope_RopeLeaf *)this; - charT * d = l -> data; - - if (d != c_string) { - free_c_string(); - } - free_string(d, size); - LAlloc::deallocate(l); + _Rope_RopeLeaf<_CharT,_Alloc>* __l + = (_Rope_RopeLeaf<_CharT,_Alloc>*)this; + __l->_Rope_RopeLeaf<_CharT,_Alloc>::~_Rope_RopeLeaf(); + _L_deallocate(__l, 1); + break; } - break; - case concat: + case _S_concat: { - __rope_RopeConcatenation * c = - (__rope_RopeConcatenation *)this; - __rope_RopeBase * left = c -> left; - __rope_RopeBase * right = c -> right; - free_c_string(); - left -> unref_nonnil(); - right -> unref_nonnil(); - CAlloc::deallocate(c); + _Rope_RopeConcatenation<_CharT,_Alloc>* __c + = (_Rope_RopeConcatenation<_CharT,_Alloc>*)this; + __c->_Rope_RopeConcatenation<_CharT,_Alloc>:: + ~_Rope_RopeConcatenation(); + _C_deallocate(__c, 1); + break; } - break; - case function: + case _S_function: { - __rope_RopeFunction * fn = - (__rope_RopeFunction *)this; - free_c_string(); - if ( fn -> delete_when_done) { - delete fn -> fn; - } - FAlloc::deallocate(fn); + _Rope_RopeFunction<_CharT,_Alloc>* __f + = (_Rope_RopeFunction<_CharT,_Alloc>*)this; + __f->_Rope_RopeFunction<_CharT,_Alloc>::~_Rope_RopeFunction(); + _F_deallocate(__f, 1); break; } - case substringfn: + case _S_substringfn: { - __rope_RopeSubstring * ss = - (__rope_RopeSubstring *)this; - __rope_RopeBase *base = ss -> base; - free_c_string(); - base -> unref_nonnil(); - SAlloc::deallocate(ss); + _Rope_RopeSubstring<_CharT,_Alloc>* __ss = + (_Rope_RopeSubstring<_CharT,_Alloc>*)this; + __ss->_Rope_RopeSubstring<_CharT,_Alloc>:: + ~_Rope_RopeSubstring(); + _S_deallocate(__ss, 1); break; } } } #else -template -inline void __rope_RopeBase::free_string(charT* s, size_t n) +template +#ifdef __STL_USE_STD_ALLOCATORS + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string + (const _CharT*, size_t, allocator_type) +#else + inline void _Rope_RopeRep<_CharT,_Alloc>::_S_free_string + (const _CharT*, size_t) +#endif {} #endif @@ -413,55 +380,58 @@ inline void __rope_RopeBase::free_string(charT* s, size_t n) // Concatenate a C string onto a leaf rope by copying the rope data. // Used for short ropes. -template -rope::RopeLeaf * -rope::leaf_concat_char_iter - (RopeLeaf * r, const charT * iter, size_t len) +template +rope<_CharT,_Alloc>::_RopeLeaf* +rope<_CharT,_Alloc>::_S_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __len) { - size_t old_len = r -> size; - charT * new_data = (charT *) - DataAlloc::allocate(rounded_up_size(old_len + len)); - RopeLeaf * result; + size_t __old_len = __r->_M_size; + _CharT* __new_data = (_CharT*) + _Data_allocate(_S_rounded_up_size(__old_len + __len)); + _RopeLeaf* __result; - 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]); + uninitialized_copy_n(__r->_M_data, __old_len, __new_data); + uninitialized_copy_n(__iter, __len, __new_data + __old_len); + _S_cond_store_eos(__new_data[__old_len + __len]); __STL_TRY { - result = RopeLeaf_from_char_ptr(new_data, old_len + len); + __result = _S_new_RopeLeaf(__new_data, __old_len + __len, + __r->get_allocator()); } - __STL_UNWIND(RopeBase::free_string(new_data, old_len + len)); - return result; + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__new_data, __old_len + __len, + __r->get_allocator())); + return __result; } #ifndef __GC // As above, but it's OK to clobber original if refcount is 1 -template -rope::RopeLeaf * -rope::destr_leaf_concat_char_iter - (RopeLeaf * r, const charT * iter, size_t len) +template +rope<_CharT,_Alloc>::_RopeLeaf* +rope<_CharT,_Alloc>::_S_destr_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __len) { - __stl_assert(r -> refcount >= 1); - if (r -> refcount > 1) return leaf_concat_char_iter(r, iter, len); - size_t old_len = r -> size; - if (allocated_capacity(old_len) >= old_len + len) { + __stl_assert(__r->_M_refcount >= 1); + if (__r->_M_refcount > 1) + return _S_leaf_concat_char_iter(__r, __iter, __len); + size_t __old_len = __r->_M_size; + if (_S_allocated_capacity(__old_len) >= __old_len + __len) { // The space has been partially initialized for the standard // character types. But that doesn't matter for those types. - uninitialized_copy_n(iter, len, r -> data + old_len); - if (__is_basic_char_type((charT *)0)) { - __cond_store_eos(r -> data[old_len + len]); - __stl_assert(r -> c_string == r -> data); - } else if (r -> c_string != r -> data && 0 != r -> c_string) { - r -> free_c_string(); - r -> c_string = 0; + uninitialized_copy_n(__iter, __len, __r->_M_data + __old_len); + if (_S_is_basic_char_type((_CharT*)0)) { + _S_cond_store_eos(__r->_M_data[__old_len + __len]); + __stl_assert(__r->_M_c_string == __r->_M_data); + } else if (__r->_M_c_string != __r->_M_data && 0 != __r->_M_c_string) { + __r->_M_free_c_string(); + __r->_M_c_string = 0; } - r -> size = old_len + len; - __stl_assert(r -> refcount == 1); - r -> refcount = 2; - return r; + __r->_M_size = __old_len + __len; + __stl_assert(__r->_M_refcount == 1); + __r->_M_refcount = 2; + return __r; } else { - RopeLeaf * result = leaf_concat_char_iter(r, iter, len); - __stl_assert(result -> refcount == 1); - return result; + _RopeLeaf* __result = _S_leaf_concat_char_iter(__r, __iter, __len); + __stl_assert(__result->_M_refcount == 1); + return __result; } } #endif @@ -469,292 +439,300 @@ rope::destr_leaf_concat_char_iter // Assumes left and right are not 0. // Does not increment (nor decrement on exception) child reference counts. // Result has ref count 1. -template -rope::RopeBase * -rope::tree_concat (RopeBase * left, RopeBase * right) +template +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_tree_concat (_RopeRep* __left, _RopeRep* __right) { - RopeConcatenation * result = CAlloc::allocate(); - unsigned char child_depth = left -> depth; - size_t rsize; - - result -> tag = RopeBase::concat; - result -> c_string = 0; - result -> is_balanced = false; - result -> size = rsize = left -> size + right -> size; - if (right -> depth > child_depth) child_depth = right -> depth; - unsigned char depth = (unsigned char)(child_depth + 1); - result -> depth = depth; - result -> left = left; - result -> right = right; -# ifndef __GC - result -> refcount = 1; - result -> init_refcount_lock(); + _RopeConcatenation* __result = + _S_new_RopeConcatenation(__left, __right, __left->get_allocator()); + size_t __depth = __result->_M_depth; + +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__left->get_allocator() == __right->get_allocator()); # endif - if (depth > 20 && (rsize < 1000 || depth > RopeBase::max_rope_depth)) { - RopeBase * balanced; - + if (__depth > 20 && (__result->_M_size < 1000 || + __depth > _RopeRep::_S_max_rope_depth)) { + _RopeRep* __balanced; + __STL_TRY { - balanced = balance(result); + __balanced = _S_balance(__result); # ifndef __GC - if (result != balanced) { - __stl_assert(1 == result -> refcount - && 1 == balanced -> refcount); + if (__result != __balanced) { + __stl_assert(1 == __result->_M_refcount + && 1 == __balanced->_M_refcount); } # endif - result -> unref_nonnil(); + __result->_M_unref_nonnil(); } - __STL_UNWIND(CAlloc::deallocate(result)); + __STL_UNWIND((_C_deallocate(__result,1))); // In case of exception, we need to deallocate // otherwise dangling result node. But caller // still owns its children. Thus unref is // inappropriate. - return balanced; + return __balanced; } else { - return result; + return __result; } } -template -rope::RopeBase * rope::concat_char_iter - (RopeBase * r, const charT *s, size_t slen) +template +rope<_CharT,_Alloc>::_RopeRep* rope<_CharT,_Alloc>::_S_concat_char_iter + (_RopeRep* __r, const _CharT*__s, size_t __slen) { - RopeBase *result; - if (0 == slen) { - ref(r); - return r; + _RopeRep* __result; + if (0 == __slen) { + _S_ref(__r); + return __r; } - if (0 == r) return RopeLeaf_from_unowned_char_ptr(s, slen); - if (RopeBase::leaf == r -> tag && r -> size + slen <= copy_max) { - result = leaf_concat_char_iter((RopeLeaf *)r, s, slen); + if (0 == __r) + return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, + __r->get_allocator()); + if (_RopeRep::_S_leaf == __r->_M_tag && + __r->_M_size + __slen <= _S_copy_max) { + __result = _S_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); # ifndef __GC - __stl_assert(1 == result -> refcount); + __stl_assert(1 == __result->_M_refcount); # endif - return result; + return __result; } - if (RopeBase::concat == r -> tag - && RopeBase::leaf == ((RopeConcatenation *)r) -> right -> tag) { - RopeLeaf *right = (RopeLeaf *)(((RopeConcatenation *)r) -> right); - if (right -> size + slen <= copy_max) { - RopeBase * left = ((RopeConcatenation *)r) -> left; - RopeBase * nright = leaf_concat_char_iter((RopeLeaf *)right, s, slen); - left -> ref_nonnil(); + if (_RopeRep::_S_concat == __r->_M_tag + && _RopeRep::_S_leaf == ((_RopeConcatenation*)__r)->_M_right->_M_tag) { + _RopeLeaf* __right = + (_RopeLeaf* )(((_RopeConcatenation* )__r)->_M_right); + if (__right->_M_size + __slen <= _S_copy_max) { + _RopeRep* __left = ((_RopeConcatenation*)__r)->_M_left; + _RopeRep* __nright = + _S_leaf_concat_char_iter((_RopeLeaf*)__right, __s, __slen); + __left->_M_ref_nonnil(); __STL_TRY { - result = tree_concat(left, nright); + __result = _S_tree_concat(__left, __nright); } - __STL_UNWIND(unref(left); unref(nright)); + __STL_UNWIND(_S_unref(__left); _S_unref(__nright)); # ifndef __GC - __stl_assert(1 == result -> refcount); + __stl_assert(1 == __result->_M_refcount); # endif - return result; + return __result; } } - RopeBase * nright = RopeLeaf_from_unowned_char_ptr(s, slen); + _RopeRep* __nright = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); __STL_TRY { - r -> ref_nonnil(); - result = tree_concat(r, nright); + __r->_M_ref_nonnil(); + __result = _S_tree_concat(__r, __nright); } - __STL_UNWIND(unref(r); unref(nright)); + __STL_UNWIND(_S_unref(__r); _S_unref(__nright)); # ifndef __GC - __stl_assert(1 == result -> refcount); + __stl_assert(1 == __result->_M_refcount); # endif - return result; + return __result; } #ifndef __GC -template -rope::RopeBase * rope -::destr_concat_char_iter - (RopeBase * r, const charT *s, size_t slen) +template +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_destr_concat_char_iter( + _RopeRep* __r, const _CharT* __s, size_t __slen) { - RopeBase *result; - if (0 == r) return RopeLeaf_from_unowned_char_ptr(s, slen); - size_t count = r -> refcount; - size_t orig_size = r -> size; - __stl_assert(count >= 1); - if (count > 1) return concat_char_iter(r, s, slen); - if (0 == slen) { - r -> refcount = 2; // One more than before - return r; + _RopeRep* __result; + if (0 == __r) + return __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, + __r->get_allocator()); + size_t __count = __r->_M_refcount; + size_t __orig_size = __r->_M_size; + __stl_assert(__count >= 1); + if (__count > 1) return _S_concat_char_iter(__r, __s, __slen); + if (0 == __slen) { + __r->_M_refcount = 2; // One more than before + return __r; } - if (orig_size + slen <= copy_max && RopeBase::leaf == r -> tag) { - result = destr_leaf_concat_char_iter((RopeLeaf *)r, s, slen); - return result; + if (__orig_size + __slen <= _S_copy_max && + _RopeRep::_S_leaf == __r->_M_tag) { + __result = _S_destr_leaf_concat_char_iter((_RopeLeaf*)__r, __s, __slen); + return __result; } - if (RopeBase::concat == r -> tag) { - RopeLeaf *right = (RopeLeaf *)(((RopeConcatenation *)r) -> right); - if (RopeBase::leaf == right -> tag - && right -> size + slen <= copy_max) { - RopeBase * new_right = destr_leaf_concat_char_iter(right, s, slen); - if (right == new_right) { - __stl_assert(new_right -> refcount == 2); - new_right -> refcount = 1; + if (_RopeRep::_S_concat == __r->_M_tag) { + _RopeLeaf* __right = (_RopeLeaf*)(((_RopeConcatenation*)__r)->_M_right); + if (_RopeRep::_S_leaf == __right->_M_tag + && __right->_M_size + __slen <= _S_copy_max) { + _RopeRep* __new_right = + _S_destr_leaf_concat_char_iter(__right, __s, __slen); + if (__right == __new_right) { + __stl_assert(__new_right->_M_refcount == 2); + __new_right->_M_refcount = 1; } else { - __stl_assert(new_right -> refcount >= 1); - right -> unref_nonnil(); + __stl_assert(__new_right->_M_refcount >= 1); + __right->_M_unref_nonnil(); } - __stl_assert(r -> refcount == 1); - r -> refcount = 2; // One more than before. - ((RopeConcatenation *)r) -> right = new_right; - r -> size = orig_size + slen; - if (0 != r -> c_string) { - r -> free_c_string(); - r -> c_string = 0; + __stl_assert(__r->_M_refcount == 1); + __r->_M_refcount = 2; // One more than before. + ((_RopeConcatenation*)__r)->_M_right = __new_right; + __r->_M_size = __orig_size + __slen; + if (0 != __r->_M_c_string) { + __r->_M_free_c_string(); + __r->_M_c_string = 0; } - return r; + return __r; } } - RopeBase *right = RopeLeaf_from_unowned_char_ptr(s, slen); - r -> ref_nonnil(); + _RopeRep* __right = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __slen, __r->get_allocator()); + __r->_M_ref_nonnil(); __STL_TRY { - result = tree_concat(r, right); + __result = _S_tree_concat(__r, __right); } - __STL_UNWIND(unref(r); unref(right)) - __stl_assert(1 == result -> refcount); - return result; + __STL_UNWIND(_S_unref(__r); _S_unref(__right)) + __stl_assert(1 == __result->_M_refcount); + return __result; } #endif /* !__GC */ -template -rope::RopeBase * -rope::concat(RopeBase * left, RopeBase * right) +template +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_concat(_RopeRep* __left, _RopeRep* __right) { - if (0 == left) { - ref(right); - return right; + if (0 == __left) { + _S_ref(__right); + return __right; } - if (0 == right) { - left -> ref_nonnil(); - return left; + if (0 == __right) { + __left->_M_ref_nonnil(); + return __left; } - if (RopeBase::leaf == right -> tag) { - if (RopeBase::leaf == left -> tag) { - if (right -> size + left -> size <= copy_max) { - return leaf_concat_char_iter((RopeLeaf *)left, - ((RopeLeaf *)right) -> data, - right -> size); + if (_RopeRep::_S_leaf == __right->_M_tag) { + if (_RopeRep::_S_leaf == __left->_M_tag) { + if (__right->_M_size + __left->_M_size <= _S_copy_max) { + return _S_leaf_concat_char_iter((_RopeLeaf*)__left, + ((_RopeLeaf*)__right)->_M_data, + __right->_M_size); } - } else if (RopeBase::concat == left -> tag - && RopeBase::leaf == - ((RopeConcatenation *)left) -> right -> tag) { - RopeLeaf * leftright = - (RopeLeaf *)(((RopeConcatenation *)left) -> right); - if (leftright -> size + right -> size <= copy_max) { - RopeBase * leftleft = ((RopeConcatenation *)left) -> left; - RopeBase * rest = leaf_concat_char_iter(leftright, - ((RopeLeaf *)right) -> data, - right -> size); - leftleft -> ref_nonnil(); + } else if (_RopeRep::_S_concat == __left->_M_tag + && _RopeRep::_S_leaf == + ((_RopeConcatenation*)__left)->_M_right->_M_tag) { + _RopeLeaf* __leftright = + (_RopeLeaf*)(((_RopeConcatenation*)__left)->_M_right); + if (__leftright->_M_size + __right->_M_size <= _S_copy_max) { + _RopeRep* __leftleft = ((_RopeConcatenation*)__left)->_M_left; + _RopeRep* __rest = _S_leaf_concat_char_iter(__leftright, + ((_RopeLeaf*)__right)->_M_data, + __right->_M_size); + __leftleft->_M_ref_nonnil(); __STL_TRY { - return(tree_concat(leftleft, rest)); + return(_S_tree_concat(__leftleft, __rest)); } - __STL_UNWIND(unref(leftleft); unref(rest)) + __STL_UNWIND(_S_unref(__leftleft); _S_unref(__rest)) } } } - left -> ref_nonnil(); - right -> ref_nonnil(); + __left->_M_ref_nonnil(); + __right->_M_ref_nonnil(); __STL_TRY { - return(tree_concat(left, right)); + return(_S_tree_concat(__left, __right)); } - __STL_UNWIND(unref(left); unref(right)); + __STL_UNWIND(_S_unref(__left); _S_unref(__right)); } -template -rope::RopeBase * -rope::substring(RopeBase * base, size_t start, size_t endp1) +template +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_substring(_RopeRep* __base, + size_t __start, size_t __endp1) { - if (0 == base) return 0; - size_t len = base -> size; - size_t adj_endp1; - const size_t lazy_threshold = 128; + if (0 == __base) return 0; + size_t __len = __base->_M_size; + size_t __adj_endp1; + const size_t __lazy_threshold = 128; - if (endp1 >= len) { - if (0 == start) { - base -> ref_nonnil(); - return base; + if (__endp1 >= __len) { + if (0 == __start) { + __base->_M_ref_nonnil(); + return __base; } else { - adj_endp1 = len; + __adj_endp1 = __len; } } else { - adj_endp1 = endp1; + __adj_endp1 = __endp1; } - switch(base -> tag) { - case RopeBase::concat: + switch(__base->_M_tag) { + case _RopeRep::_S_concat: { - RopeConcatenation *c = (RopeConcatenation *)base; - RopeBase *left = c -> left; - RopeBase *right = c -> right; - size_t left_len = left -> size; - RopeBase * result; - - if (adj_endp1 <= left_len) { - return substring(left, start, endp1); - } else if (start >= left_len) { - return substring(right, start - left_len, - adj_endp1 - left_len); + _RopeConcatenation* __c = (_RopeConcatenation*)__base; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + size_t __left_len = __left->_M_size; + _RopeRep* __result; + + if (__adj_endp1 <= __left_len) { + return _S_substring(__left, __start, __endp1); + } else if (__start >= __left_len) { + return _S_substring(__right, __start - __left_len, + __adj_endp1 - __left_len); } - self_destruct_ptr left_result(substring(left, start, - left_len)); - self_destruct_ptr right_result( - substring(right, 0, endp1 - left_len)); - result = concat(left_result, right_result); + _Self_destruct_ptr __left_result( + _S_substring(__left, __start, __left_len)); + _Self_destruct_ptr __right_result( + _S_substring(__right, 0, __endp1 - __left_len)); + __result = _S_concat(__left_result, __right_result); # ifndef __GC - __stl_assert(1 == result -> refcount); + __stl_assert(1 == __result->_M_refcount); # endif - return result; + return __result; } - case RopeBase::leaf: + case _RopeRep::_S_leaf: { - RopeLeaf * l = (RopeLeaf *)base; - RopeLeaf * result; - size_t result_len; - if (start >= adj_endp1) return 0; - result_len = adj_endp1 - start; - if (result_len > lazy_threshold) goto lazy; + _RopeLeaf* __l = (_RopeLeaf*)__base; + _RopeLeaf* __result; + size_t __result_len; + if (__start >= __adj_endp1) return 0; + __result_len = __adj_endp1 - __start; + if (__result_len > __lazy_threshold) goto lazy; # ifdef __GC - const charT *section = l -> data + start; - result = RopeLeaf_from_char_ptr(section, result_len); - result -> c_string = 0; // Not eos terminated. + const _CharT* __section = __l->_M_data + __start; + __result = _S_new_RopeLeaf(__section, __result_len, + __base->get_allocator()); + __result->_M_c_string = 0; // Not eos terminated. # else // We should sometimes create substring node instead. - result = RopeLeaf_from_unowned_char_ptr( - l -> data + start, result_len); + __result = __STL_ROPE_FROM_UNOWNED_CHAR_PTR( + __l->_M_data + __start, __result_len, + __base->get_allocator()); # endif - return result; + return __result; } - case RopeBase::substringfn: - // Avoid introducing mutiple layers of substring nodes. + case _RopeRep::_S_substringfn: + // Avoid introducing multiple layers of substring nodes. { - RopeSubstring *old = (RopeSubstring *)base; - size_t result_len; - if (start >= adj_endp1) return 0; - result_len = adj_endp1 - start; - if (result_len > lazy_threshold) { - RopeSubstring * space = SAlloc::allocate(); - RopeSubstring * result = - new(space) RopeSubstring(old -> base, - start + old -> start, - adj_endp1 - start); - return result; - } // else fall through: + _RopeSubstring* __old = (_RopeSubstring*)__base; + size_t __result_len; + if (__start >= __adj_endp1) return 0; + __result_len = __adj_endp1 - __start; + if (__result_len > __lazy_threshold) { + _RopeSubstring* __result = + _S_new_RopeSubstring(__old->_M_base, + __start + __old->_M_start, + __adj_endp1 - __start, + __base->get_allocator()); + return __result; + + } // *** else fall through: *** } - case RopeBase::function: + case _RopeRep::_S_function: { - RopeFunction * f = (RopeFunction *)base; - charT *section; - size_t result_len; - if (start >= adj_endp1) return 0; - result_len = adj_endp1 - start; - - if (result_len > lazy_threshold) goto lazy; - section = (charT *) - DataAlloc::allocate(rounded_up_size(result_len)); + _RopeFunction* __f = (_RopeFunction*)__base; + _CharT* __section; + size_t __result_len; + if (__start >= __adj_endp1) return 0; + __result_len = __adj_endp1 - __start; + + if (__result_len > __lazy_threshold) goto lazy; + __section = (_CharT*) + _Data_allocate(_S_rounded_up_size(__result_len)); __STL_TRY { - (*(f -> fn))(start, result_len, section); + (*(__f->_M_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); + __STL_UNWIND(_RopeRep::__STL_FREE_STRING( + __section, __result_len, __base->get_allocator())); + _S_cond_store_eos(__section[__result_len]); + return _S_new_RopeLeaf(__section, __result_len, + __base->get_allocator()); } } /*NOTREACHED*/ @@ -762,141 +740,146 @@ rope::substring(RopeBase * base, size_t start, size_t endp1) lazy: { // Create substring node. - RopeSubstring * space = SAlloc::allocate(); - RopeSubstring * result = new(space) RopeSubstring(base, start, - adj_endp1 - start); - return result; + return _S_new_RopeSubstring(__base, __start, __adj_endp1 - __start, + __base->get_allocator()); } } -template -class __rope_flatten_char_consumer : public __rope_char_consumer { +template +class _Rope_flatten_char_consumer : public _Rope_char_consumer<_CharT> { private: - charT * buf_ptr; + _CharT* _M_buf_ptr; public: - charT * buffer; - __rope_flatten_char_consumer(charT * buffer) { - buf_ptr = buffer; + // _CharT* _M_buffer; // XXX not used + + _Rope_flatten_char_consumer(_CharT* __buffer) { + _M_buf_ptr = __buffer; }; - ~__rope_flatten_char_consumer() {} - bool operator() (const charT* leaf, size_t n) { - uninitialized_copy_n(leaf, n, buf_ptr); - buf_ptr += n; + ~_Rope_flatten_char_consumer() {} + bool operator() (const _CharT* __leaf, size_t __n) { + uninitialized_copy_n(__leaf, __n, _M_buf_ptr); + _M_buf_ptr += __n; return true; } }; -template -class __rope_find_char_char_consumer : public __rope_char_consumer { +template +class _Rope_find_char_char_consumer : public _Rope_char_consumer<_CharT> { private: - charT pattern; + _CharT _M_pattern; public: - size_t count; // Number of nonmatching characters - __rope_find_char_char_consumer(charT p) : pattern(p), count(0) {} - ~__rope_find_char_char_consumer() {} - bool operator() (const charT* leaf, size_t n) { - size_t i; - for (i = 0; i < n; i++) { - if (leaf[i] == pattern) { - count += i; return false; + size_t _M_count; // Number of nonmatching characters + _Rope_find_char_char_consumer(_CharT __p) + : _M_pattern(__p), _M_count(0) {} + ~_Rope_find_char_char_consumer() {} + bool operator() (const _CharT* __leaf, size_t __n) { + size_t __i; + for (__i = 0; __i < __n; __i++) { + if (__leaf[__i] == _M_pattern) { + _M_count += __i; return false; } } - count += n; return true; + _M_count += __n; return true; } }; -template -class __rope_insert_char_consumer : public __rope_char_consumer { +template +class _Rope_insert_char_consumer : public _Rope_char_consumer<_CharT> { private: - typedef ostream insert_ostream; - insert_ostream & o; + typedef ostream _Insert_ostream; + _Insert_ostream& _M_o; public: - charT * buffer; - __rope_insert_char_consumer(insert_ostream & writer) : o(writer) {}; - ~__rope_insert_char_consumer() { }; + // _CharT* buffer; // XXX not used + _Rope_insert_char_consumer(_Insert_ostream& __writer) + : _M_o(__writer) {}; + ~_Rope_insert_char_consumer() { }; // Caller is presumed to own the ostream - bool operator() (const charT* leaf, size_t n); + bool operator() (const _CharT* __leaf, size_t __n); // Returns true to continue traversal. }; -template -bool __rope_insert_char_consumer::operator() - (const charT * leaf, size_t n) +template +bool _Rope_insert_char_consumer<_CharT>::operator() + (const _CharT* __leaf, size_t __n) { - size_t i; + size_t __i; // We assume that formatting is set up correctly for each element. - for (i = 0; i < n; i++) o << leaf[i]; + for (__i = 0; __i < __n; __i++) _M_o << __leaf[__i]; return true; } -inline bool __rope_insert_char_consumer::operator() - (const char * leaf, size_t n) +inline bool _Rope_insert_char_consumer::operator() + (const char* __leaf, size_t __n) { - size_t i; - for (i = 0; i < n; i++) o.put(leaf[i]); + size_t __i; + for (__i = 0; __i < __n; __i++) _M_o.put(__leaf[__i]); return true; } -#if !defined(_MSC_VER) && !defined(__BORLANDC__) -// I couldn't get this to work with the VC++ version of basic_ostream. -inline bool __rope_insert_char_consumer::operator() - (const wchar_t * leaf, size_t n) +#if 0 +// I couldn't get this to work work with the VC++ version of basic_ostream. +// It also doesn't really do the right thing unless o is a wide stream. +// Given that wchar_t is often 4 bytes, its not clear to me how useful +// this stuff is anyway. +inline bool _Rope_insert_char_consumer::operator() + (const wchar_t* __leaf, size_t __n) { - size_t i; - for (i = 0; i < n; i++) o.put(leaf[i]); + size_t __i; + for (__i = 0; __i < __n; __i++) _M_o.put(__leaf[__i]); return true; } #endif /* !_MSC_VER && !BORLAND */ -template -bool rope::apply_to_pieces( - __rope_char_consumer& c, - const RopeBase * r, - size_t begin, size_t end) +template +bool rope<_CharT, _Alloc>::_S_apply_to_pieces( + _Rope_char_consumer<_CharT>& __c, + const _RopeRep* __r, + size_t __begin, size_t __end) { - if (0 == r) return true; - switch(r -> tag) { - case RopeBase::concat: + if (0 == __r) return true; + switch(__r->_M_tag) { + case _RopeRep::_S_concat: { - RopeConcatenation *conc = (RopeConcatenation *)r; - RopeBase *left = conc -> left; - size_t left_len = left -> size; - if (begin < left_len) { - size_t left_end = min(left_len, end); - if (!apply_to_pieces(c, left, begin, left_end)) { + _RopeConcatenation* __conc = (_RopeConcatenation*)__r; + _RopeRep* __left = __conc->_M_left; + size_t __left_len = __left->_M_size; + if (__begin < __left_len) { + size_t __left_end = min(__left_len, __end); + if (!_S_apply_to_pieces(__c, __left, __begin, __left_end)) return false; - } } - if (end > left_len) { - RopeBase *right = conc -> right; - size_t right_start = max(left_len, begin); - if (!apply_to_pieces(c, right, - right_start - left_len, - end - left_len)) { + if (__end > __left_len) { + _RopeRep* __right = __conc->_M_right; + size_t __right_start = max(__left_len, __begin); + if (!_S_apply_to_pieces(__c, __right, + __right_start - __left_len, + __end - __left_len)) { return false; } } } return true; - case RopeBase::leaf: + case _RopeRep::_S_leaf: { - RopeLeaf * l = (RopeLeaf *)r; - return c(l -> data + begin, end - begin); + _RopeLeaf* __l = (_RopeLeaf*)__r; + return __c(__l->_M_data + __begin, __end - __begin); } - case RopeBase::function: - case RopeBase::substringfn: + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: { - RopeFunction * f = (RopeFunction *)r; - size_t len = end - begin; - bool result; - charT * buffer = DataAlloc::allocate(len); + _RopeFunction* __f = (_RopeFunction*)__r; + size_t __len = __end - __begin; + bool __result; + _CharT* __buffer = + (_CharT*)alloc::allocate(__len * sizeof(_CharT)); __STL_TRY { - (*(f -> fn))(begin, end, buffer); - result = c(buffer, len); - DataAlloc::deallocate(buffer, len); + (*(__f->_M_fn))(__begin, __end, __buffer); + __result = __c(__buffer, __len); + alloc::deallocate(__buffer, __len * sizeof(_CharT)); } - __STL_UNWIND(DataAlloc::deallocate(buffer, len)) - return result; + __STL_UNWIND((alloc::deallocate(__buffer, + __len * sizeof(_CharT)))) + return __result; } default: __stl_assert(false); @@ -905,98 +888,102 @@ bool rope::apply_to_pieces( } } -inline void __rope_fill(ostream& o, size_t n) +inline void _Rope_fill(ostream& __o, size_t __n) { - char f = o.fill(); - size_t i; + char __f = __o.fill(); + size_t __i; - for (i = 0; i < n; i++) o.put(f); + for (__i = 0; __i < __n; __i++) __o.put(__f); } -template inline bool __rope_is_simple(charT *) { return false; } -inline bool __rope_is_simple(char *) { return true; } -inline bool __rope_is_simple(wchar_t *) { return true; } +template inline bool _Rope_is_simple(_CharT*) { return false; } +inline bool _Rope_is_simple(char*) { return true; } +inline bool _Rope_is_simple(wchar_t*) { return true; } -template -ostream& operator<< (ostream& o, const rope& r) +template +ostream& operator<< (ostream& __o, const rope<_CharT, _Alloc>& __r) { - size_t w = o.width(); - bool left = bool(o.flags() & ios::left); - size_t pad_len; - size_t rope_len = r.size(); - __rope_insert_char_consumer c(o); - bool is_simple = __rope_is_simple((charT *)0); + size_t __w = __o.width(); + bool __left = bool(__o.flags() & ios::left); + size_t __pad_len; + size_t __rope_len = __r.size(); + _Rope_insert_char_consumer<_CharT> __c(__o); + bool __is_simple = _Rope_is_simple((_CharT*)0); - if (rope_len < w) { - pad_len = w - rope_len; + if (__rope_len < __w) { + __pad_len = __w - __rope_len; } else { - pad_len = 0; + __pad_len = 0; } - if (!is_simple) o.width(w/rope_len); + if (!__is_simple) __o.width(__w/__rope_len); __STL_TRY { - if (is_simple && !left && pad_len > 0) { - __rope_fill(o, pad_len); + if (__is_simple && !__left && __pad_len > 0) { + _Rope_fill(__o, __pad_len); } - r.apply_to_pieces(0, r.size(), c); - if (is_simple && left && pad_len > 0) { - __rope_fill(o, pad_len); + __r.apply_to_pieces(0, __r.size(), __c); + if (__is_simple && __left && __pad_len > 0) { + _Rope_fill(__o, __pad_len); } - if (!is_simple) - o.width(w); + if (!__is_simple) + __o.width(__w); } - __STL_UNWIND(if (!is_simple) o.width(w)) - return o; + __STL_UNWIND(if (!__is_simple) __o.width(__w)) + return __o; } -template -charT * -rope::flatten(RopeBase * r, - size_t start, size_t len, - charT * buffer) +template +_CharT* +rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, + size_t __start, size_t __len, + _CharT* __buffer) { - __rope_flatten_char_consumer c(buffer); - apply_to_pieces(c, r, start, start + len); - return(buffer + len); + _Rope_flatten_char_consumer<_CharT> __c(__buffer); + _S_apply_to_pieces(__c, __r, __start, __start + __len); + return(__buffer + __len); } -template +template size_t -rope::find(charT pattern, size_t start) const +rope<_CharT,_Alloc>::find(_CharT __pattern, size_t __start) const { - __rope_find_char_char_consumer c(pattern); - apply_to_pieces(c, tree_ptr, start, size()); - return start + c.count; + _Rope_find_char_char_consumer<_CharT> __c(__pattern); + _S_apply_to_pieces(__c, _M_tree_ptr, __start, size()); + size_type __result_pos = __start + __c._M_count; +# ifndef __STL_OLD_ROPE_SEMANTICS + if (__result_pos == size()) __result_pos = npos; +# endif + return __result_pos; } -template -charT * -rope::flatten(RopeBase * r, charT * buffer) +template +_CharT* +rope<_CharT,_Alloc>::_S_flatten(_RopeRep* __r, _CharT* __buffer) { - if (0 == r) return buffer; - switch(r -> tag) { - case RopeBase::concat: + if (0 == __r) return __buffer; + switch(__r->_M_tag) { + case _RopeRep::_S_concat: { - RopeConcatenation *c = (RopeConcatenation *)r; - RopeBase *left = c -> left; - RopeBase *right = c -> right; - charT * rest = flatten(left, buffer); - return flatten(right, rest); + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; + _CharT* __rest = _S_flatten(__left, __buffer); + return _S_flatten(__right, __rest); } - case RopeBase::leaf: + case _RopeRep::_S_leaf: { - RopeLeaf * l = (RopeLeaf *)r; - return copy_n(l -> data, l -> size, buffer).second; + _RopeLeaf* __l = (_RopeLeaf*)__r; + return copy_n(__l->_M_data, __l->_M_size, __buffer).second; } - case RopeBase::function: - case RopeBase::substringfn: + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: // We dont yet do anything with substring nodes. // This needs to be fixed before ropefiles will work well. { - RopeFunction * f = (RopeFunction *)r; - (*(f -> fn))(0, f -> size, buffer); - return buffer + f -> size; + _RopeFunction* __f = (_RopeFunction*)__r; + (*(__f->_M_fn))(0, __f->_M_size, __buffer); + return __buffer + __f->_M_size; } default: __stl_assert(false); @@ -1006,72 +993,75 @@ rope::flatten(RopeBase * r, charT * buffer) } -// This needs work for charT != char -template +// This needs work for _CharT != char +template void -rope::dump(RopeBase * r, int indent) +rope<_CharT,_Alloc>::_S_dump(_RopeRep* __r, int __indent) { - for (int i = 0; i < indent; i++) putchar(' '); - if (0 == r) { + for (int __i = 0; __i < __indent; __i++) putchar(' '); + if (0 == __r) { printf("NULL\n"); return; } - if (RopeBase::concat == r -> tag) { - RopeConcatenation *c = (RopeConcatenation *)r; - RopeBase *left = c -> left; - RopeBase *right = c -> right; + if (_RopeRep::_S_concat == __r->_M_tag) { + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + _RopeRep* __right = __c->_M_right; # ifdef __GC printf("Concatenation %p (depth = %d, len = %ld, %s balanced)\n", - r, r -> depth, r -> size, r -> is_balanced? "" : "not"); + __r, __r->_M_depth, __r->_M_size, __r->_M_is_balanced? "" : "not"); # else - printf("Concatenation %p (rc = %ld, depth = %d, len = %ld, %s balanced)\n", - r, r -> refcount, r -> depth, r -> size, - r -> is_balanced? "" : "not"); + printf("Concatenation %p (rc = %ld, depth = %d, " + "len = %ld, %s balanced)\n", + __r, __r->_M_refcount, __r->_M_depth, __r->_M_size, + __r->_M_is_balanced? "" : "not"); # endif - dump(left, indent + 2); - dump(right, indent + 2); + _S_dump(__left, __indent + 2); + _S_dump(__right, __indent + 2); return; } else { - char * kind; + char* __kind; - switch (r -> tag) { - case RopeBase::leaf: - kind = "Leaf"; + switch (__r->_M_tag) { + case _RopeRep::_S_leaf: + __kind = "Leaf"; break; - case RopeBase::function: - kind = "Function"; + case _RopeRep::_S_function: + __kind = "Function"; break; - case RopeBase::substringfn: - kind = "Function representing substring"; + case _RopeRep::_S_substringfn: + __kind = "Function representing substring"; break; default: - kind = "(corrupted kind field!)"; + __kind = "(corrupted kind field!)"; } # ifdef __GC printf("%s %p (depth = %d, len = %ld) ", - kind, r, r -> depth, r -> size); + __kind, __r, __r->_M_depth, __r->_M_size); # else printf("%s %p (rc = %ld, depth = %d, len = %ld) ", - kind, r, r -> refcount, r -> depth, r -> size); + __kind, __r, __r->_M_refcount, __r->_M_depth, __r->_M_size); # endif - if (__is_one_byte_char_type((charT *)0)) { - const int max_len = 40; - self_destruct_ptr prefix(substring(r, 0, max_len)); - charT buffer[max_len + 1]; - bool too_big = r -> size > prefix-> size; - - flatten(prefix, buffer); - buffer[prefix -> size] = __eos((charT *)0); - printf("%s%s\n", (char *)buffer, too_big? "...\n" : "\n"); + if (_S_is_one_byte_char_type((_CharT*)0)) { + const int __max_len = 40; + _Self_destruct_ptr __prefix(_S_substring(__r, 0, __max_len)); + _CharT __buffer[__max_len + 1]; + bool __too_big = __r->_M_size > __prefix->_M_size; + + _S_flatten(__prefix, __buffer); + __buffer[__prefix->_M_size] = _S_eos((_CharT*)0); + printf("%s%s\n", + (char*)__buffer, __too_big? "...\n" : "\n"); } else { printf("\n"); } } } -template +template const unsigned long -rope::min_len[__rope_RopeBase::max_rope_depth + 1] = { +rope<_CharT,_Alloc>::_S_min_len[ + _Rope_RopeRep<_CharT,_Alloc>::_S_max_rope_depth + 1] = { /* 0 */1, /* 1 */2, /* 2 */3, /* 3 */5, /* 4 */8, /* 5 */13, /* 6 */21, /* 7 */34, /* 8 */55, /* 9 */89, /* 10 */144, /* 11 */233, /* 12 */377, /* 13 */610, /* 14 */987, /* 15 */1597, /* 16 */2584, /* 17 */4181, @@ -1082,148 +1072,150 @@ rope::min_len[__rope_RopeBase::max_rope_depth + 1] = { /* 35 */24157817, /* 36 */39088169, /* 37 */63245986, /* 38 */102334155, /* 39 */165580141, /* 40 */267914296, /* 41 */433494437, /* 42 */701408733, /* 43 */1134903170, /* 44 */1836311903, -/* 45 */2971215073 }; +/* 45 */2971215073u }; // These are Fibonacci numbers < 2**32. -template -rope::RopeBase * -rope::balance(RopeBase *r) +template +rope<_CharT,_Alloc>::_RopeRep* +rope<_CharT,_Alloc>::_S_balance(_RopeRep* __r) { - RopeBase * forest[RopeBase::max_rope_depth + 1]; - RopeBase * result = 0; - int i; - // Inariant: - // The concatenation of forest in descending order is equal to r. - // forest[i].size >= min_len[i] - // forest[i].depth = i + _RopeRep* __forest[_RopeRep::_S_max_rope_depth + 1]; + _RopeRep* __result = 0; + int __i; + // Invariant: + // The concatenation of forest in descending order is equal to __r. + // __forest[__i]._M_size >= _S_min_len[__i] + // __forest[__i]._M_depth = __i // References from forest are included in refcount. - for (i = 0; i <= RopeBase::max_rope_depth; ++i) forest[i] = 0; + for (__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i) + __forest[__i] = 0; __STL_TRY { - add_to_forest(r, forest); - for (i = 0; i <= RopeBase::max_rope_depth; ++i) if (0 != forest[i]) { + _S_add_to_forest(__r, __forest); + for (__i = 0; __i <= _RopeRep::_S_max_rope_depth; ++__i) + if (0 != __forest[__i]) { # ifndef __GC - self_destruct_ptr old(result); + _Self_destruct_ptr __old(__result); # endif - result = concat(forest[i], result); - forest[i] -> unref_nonnil(); + __result = _S_concat(__forest[__i], __result); + __forest[__i]->_M_unref_nonnil(); # if !defined(__GC) && defined(__STL_USE_EXCEPTIONS) - forest[i] = 0; + __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(); - return(result); + __STL_UNWIND(for(__i = 0; __i <= _RopeRep::_S_max_rope_depth; __i++) + _S_unref(__forest[__i])) + if (__result->_M_depth > _RopeRep::_S_max_rope_depth) abort(); + return(__result); } -template +template void -rope::add_to_forest(RopeBase *r, RopeBase **forest) +rope<_CharT,_Alloc>::_S_add_to_forest(_RopeRep* __r, _RopeRep** __forest) { - if (r -> is_balanced) { - add_leaf_to_forest(r, forest); + if (__r->_M_is_balanced) { + _S_add_leaf_to_forest(__r, __forest); return; } - __stl_assert(r -> tag == RopeBase::concat); + __stl_assert(__r->_M_tag == _RopeRep::_S_concat); { - RopeConcatenation *c = (RopeConcatenation *)r; + _RopeConcatenation* __c = (_RopeConcatenation*)__r; - add_to_forest(c -> left, forest); - add_to_forest(c -> right, forest); + _S_add_to_forest(__c->_M_left, __forest); + _S_add_to_forest(__c->_M_right, __forest); } } -template +template void -rope::add_leaf_to_forest(RopeBase *r, RopeBase **forest) +rope<_CharT,_Alloc>::_S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest) { - RopeBase * insertee; // included in refcount - RopeBase * too_tiny = 0; // included in refcount - int i; // forest[0..i-1] is empty - size_t s = r -> size; + _RopeRep* __insertee; // included in refcount + _RopeRep* __too_tiny = 0; // included in refcount + int __i; // forest[0..__i-1] is empty + size_t __s = __r->_M_size; - for (i = 0; s >= min_len[i+1]/* not this bucket */; ++i) { - if (0 != forest[i]) { + for (__i = 0; __s >= _S_min_len[__i+1]/* not this bucket */; ++__i) { + if (0 != __forest[__i]) { # ifndef __GC - self_destruct_ptr old(too_tiny); + _Self_destruct_ptr __old(__too_tiny); # endif - too_tiny = concat_and_set_balanced(forest[i], too_tiny); - forest[i] -> unref_nonnil(); - forest[i] = 0; + __too_tiny = _S_concat_and_set_balanced(__forest[__i], __too_tiny); + __forest[__i]->_M_unref_nonnil(); + __forest[__i] = 0; } } { # ifndef __GC - self_destruct_ptr old(too_tiny); + _Self_destruct_ptr __old(__too_tiny); # endif - insertee = concat_and_set_balanced(too_tiny, r); + __insertee = _S_concat_and_set_balanced(__too_tiny, __r); } // Too_tiny dead, and no longer included in refcount. // Insertee is live and included. - __stl_assert(is_almost_balanced(insertee)); - __stl_assert(insertee -> depth <= r -> depth + 1); - for (;; ++i) { - if (0 != forest[i]) { + __stl_assert(_S_is_almost_balanced(__insertee)); + __stl_assert(__insertee->_M_depth <= __r->_M_depth + 1); + for (;; ++__i) { + if (0 != __forest[__i]) { # ifndef __GC - self_destruct_ptr old(insertee); + _Self_destruct_ptr __old(__insertee); # endif - insertee = concat_and_set_balanced(forest[i], insertee); - forest[i] -> unref_nonnil(); - forest[i] = 0; - __stl_assert(is_almost_balanced(insertee)); + __insertee = _S_concat_and_set_balanced(__forest[__i], __insertee); + __forest[__i]->_M_unref_nonnil(); + __forest[__i] = 0; + __stl_assert(_S_is_almost_balanced(__insertee)); } - __stl_assert(min_len[i] <= insertee -> size); - __stl_assert(forest[i] == 0); - if (i == RopeBase::max_rope_depth - || insertee -> size < min_len[i+1]) { - forest[i] = insertee; - // refcount is OK since insertee is now dead. + __stl_assert(_S_min_len[__i] <= __insertee->_M_size); + __stl_assert(__forest[__i] == 0); + if (__i == _RopeRep::_S_max_rope_depth || + __insertee->_M_size < _S_min_len[__i+1]) { + __forest[__i] = __insertee; + // refcount is OK since __insertee is now dead. return; } } } -template -charT -rope::fetch(RopeBase *r, size_type i) +template +_CharT +rope<_CharT,_Alloc>::_S_fetch(_RopeRep* __r, size_type __i) { - __GC_CONST charT * cstr = r -> c_string; + __GC_CONST _CharT* __cstr = __r->_M_c_string; - __stl_assert(i < r -> size); - if (0 != cstr) return cstr[i]; + __stl_assert(__i < __r->_M_size); + if (0 != __cstr) return __cstr[__i]; for(;;) { - switch(r -> tag) { - case RopeBase::concat: + switch(__r->_M_tag) { + case _RopeRep::_S_concat: { - RopeConcatenation *c = (RopeConcatenation *)r; - RopeBase *left = c -> left; - size_t left_len = left -> size; + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; - if (i >= left_len) { - i -= left_len; - r = c -> right; + if (__i >= __left_len) { + __i -= __left_len; + __r = __c->_M_right; } else { - r = left; + __r = __left; } } break; - case RopeBase::leaf: + case _RopeRep::_S_leaf: { - RopeLeaf * l = (RopeLeaf *)r; - return l -> data[i]; + _RopeLeaf* __l = (_RopeLeaf*)__r; + return __l->_M_data[__i]; } - case RopeBase::function: - case RopeBase::substringfn: + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: { - RopeFunction * f = (RopeFunction *)r; - charT result; + _RopeFunction* __f = (_RopeFunction*)__r; + _CharT __result; - (*(f -> fn))(i, 1, &result); - return result; + (*(__f->_M_fn))(__i, 1, &__result); + return __result; } } } @@ -1232,46 +1224,46 @@ rope::fetch(RopeBase *r, size_type i) # ifndef __GC // Return a uniquely referenced character slot for the given // position, or 0 if that's not possible. -template -charT* -rope::fetch_ptr(RopeBase *r, size_type i) +template +_CharT* +rope<_CharT,_Alloc>::_S_fetch_ptr(_RopeRep* __r, size_type __i) { - RopeBase * clrstack[RopeBase::max_rope_depth]; - size_t csptr = 0; + _RopeRep* __clrstack[_RopeRep::_S_max_rope_depth]; + size_t __csptr = 0; for(;;) { - if (r -> refcount > 1) return 0; - switch(r -> tag) { - case RopeBase::concat: + if (__r->_M_refcount > 1) return 0; + switch(__r->_M_tag) { + case _RopeRep::_S_concat: { - RopeConcatenation *c = (RopeConcatenation *)r; - RopeBase *left = c -> left; - size_t left_len = left -> size; - - if (c -> c_string != 0) clrstack[csptr++] = c; - if (i >= left_len) { - i -= left_len; - r = c -> right; + _RopeConcatenation* __c = (_RopeConcatenation*)__r; + _RopeRep* __left = __c->_M_left; + size_t __left_len = __left->_M_size; + + if (__c->_M_c_string != 0) __clrstack[__csptr++] = __c; + if (__i >= __left_len) { + __i -= __left_len; + __r = __c->_M_right; } else { - r = left; + __r = __left; } } break; - case RopeBase::leaf: + case _RopeRep::_S_leaf: { - RopeLeaf * l = (RopeLeaf *)r; - if (l -> c_string != l -> data && l -> c_string != 0) - clrstack[csptr++] = l; - while (csptr > 0) { - -- csptr; - RopeBase * d = clrstack[csptr]; - d -> free_c_string(); - d -> c_string = 0; + _RopeLeaf* __l = (_RopeLeaf*)__r; + if (__l->_M_c_string != __l->_M_data && __l->_M_c_string != 0) + __clrstack[__csptr++] = __l; + while (__csptr > 0) { + -- __csptr; + _RopeRep* __d = __clrstack[__csptr]; + __d->_M_free_c_string(); + __d->_M_c_string = 0; } - return l -> data + i; + return __l->_M_data + __i; } - case RopeBase::function: - case RopeBase::substringfn: + case _RopeRep::_S_function: + case _RopeRep::_S_substringfn: return 0; } } @@ -1282,233 +1274,253 @@ rope::fetch_ptr(RopeBase *r, size_type i) // lexicographical_compare_3way. // We do a little more work to avoid dealing with rope iterators for // flat strings. -template +template int -rope::compare (const RopeBase *left, const RopeBase *right) +rope<_CharT,_Alloc>::_S_compare (const _RopeRep* __left, + const _RopeRep* __right) { - size_t left_len; - size_t right_len; - - if (0 == right) return 0 != left; - if (0 == left) return -1; - left_len = left -> size; - right_len = right -> size; - if (RopeBase::leaf == left -> tag) { - RopeLeaf *l = (RopeLeaf *) left; - if (RopeBase::leaf == right -> tag) { - RopeLeaf *r = (RopeLeaf *) right; + size_t __left_len; + size_t __right_len; + + if (0 == __right) return 0 != __left; + if (0 == __left) return -1; + __left_len = __left->_M_size; + __right_len = __right->_M_size; + if (_RopeRep::_S_leaf == __left->_M_tag) { + _RopeLeaf* __l = (_RopeLeaf*) __left; + if (_RopeRep::_S_leaf == __right->_M_tag) { + _RopeLeaf* __r = (_RopeLeaf*) __right; return lexicographical_compare_3way( - l -> data, l -> data + left_len, - r -> data, r -> data + right_len); + __l->_M_data, __l->_M_data + __left_len, + __r->_M_data, __r->_M_data + __right_len); } else { - const_iterator rstart(right, 0); - const_iterator rend(right, right_len); + const_iterator __rstart(__right, 0); + const_iterator __rend(__right, __right_len); return lexicographical_compare_3way( - l -> data, l -> data + left_len, - rstart, rend); + __l->_M_data, __l->_M_data + __left_len, + __rstart, __rend); } } else { - const_iterator lstart(left, 0); - const_iterator lend(left, left_len); - if (RopeBase::leaf == right -> tag) { - RopeLeaf *r = (RopeLeaf *) right; + const_iterator __lstart(__left, 0); + const_iterator __lend(__left, __left_len); + if (_RopeRep::_S_leaf == __right->_M_tag) { + _RopeLeaf* __r = (_RopeLeaf*) __right; return lexicographical_compare_3way( - lstart, lend, - r -> data, r -> data + right_len); + __lstart, __lend, + __r->_M_data, __r->_M_data + __right_len); } else { - const_iterator rstart(right, 0); - const_iterator rend(right, right_len); + const_iterator __rstart(__right, 0); + const_iterator __rend(__right, __right_len); return lexicographical_compare_3way( - lstart, lend, - rstart, rend); + __lstart, __lend, + __rstart, __rend); } } } // Assignment to reference proxies. -template -__rope_charT_ref_proxy& -__rope_charT_ref_proxy::operator= (charT c) { - RopeBase * old = root -> tree_ptr; +template +_Rope_char_ref_proxy<_CharT, _Alloc>& +_Rope_char_ref_proxy<_CharT, _Alloc>::operator= (_CharT __c) { + _RopeRep* __old = _M_root->_M_tree_ptr; # ifndef __GC // First check for the case in which everything is uniquely // referenced. In that case we can do this destructively. - charT * charT_ptr = my_rope::fetch_ptr(old, pos); - if (0 != charT_ptr) { - *charT_ptr = c; + _CharT* __ptr = _My_rope::_S_fetch_ptr(__old, _M_pos); + if (0 != __ptr) { + *__ptr = __c; return *this; } # endif - self_destruct_ptr left(my_rope::substring(old, 0, pos)); - self_destruct_ptr right(my_rope::substring(old, pos+1, old -> size)); - self_destruct_ptr result_left(my_rope::destr_concat_char_iter(left, &c, 1)); + _Self_destruct_ptr __left( + _My_rope::_S_substring(__old, 0, _M_pos)); + _Self_destruct_ptr __right( + _My_rope::_S_substring(__old, _M_pos+1, __old->_M_size)); + _Self_destruct_ptr __result_left( + _My_rope::_S_destr_concat_char_iter(__left, &__c, 1)); + # ifndef __GC - __stl_assert(left == result_left || 1 == result_left -> refcount); + __stl_assert(__left == __result_left || 1 == __result_left->_M_refcount); # endif - RopeBase * result = - my_rope::concat(result_left, right); + _RopeRep* __result = + _My_rope::_S_concat(__result_left, __right); # ifndef __GC - __stl_assert(1 <= result -> refcount); - RopeBase::unref(old); + __stl_assert(1 <= __result->_M_refcount); + _RopeRep::_S_unref(__old); # endif - root -> tree_ptr = result; + _M_root->_M_tree_ptr = __result; return *this; } -template -inline __rope_charT_ref_proxy::operator charT () const +template +inline _Rope_char_ref_proxy<_CharT, _Alloc>::operator _CharT () const { - if (current_valid) { - return current; + if (_M_current_valid) { + return _M_current; } else { - return my_rope::fetch(root->tree_ptr, pos); + return _My_rope::_S_fetch(_M_root->_M_tree_ptr, _M_pos); } } -template -__rope_charT_ptr_proxy -__rope_charT_ref_proxy::operator& () const { - return __rope_charT_ptr_proxy(*this); +template +_Rope_char_ptr_proxy<_CharT, _Alloc> +_Rope_char_ref_proxy<_CharT, _Alloc>::operator& () const { + return _Rope_char_ptr_proxy<_CharT, _Alloc>(*this); } -template -rope::rope(size_t n, charT c) +template +rope<_CharT, _Alloc>::rope(size_t __n, _CharT __c, + const allocator_type& __a) +: _Base(__a) { - rope result; - const size_t exponentiate_threshold = 32; - size_t exponent; - size_t rest; - charT *rest_buffer; - RopeBase * remainder; - rope remainder_rope; - - if (0 == n) { tree_ptr = 0; return; } - exponent = n / exponentiate_threshold; - rest = n % exponentiate_threshold; - if (0 == rest) { - remainder = 0; + rope<_CharT,_Alloc> __result; + const size_t __exponentiate_threshold = 32; + size_t __exponent; + size_t __rest; + _CharT* __rest_buffer; + _RopeRep* __remainder; + rope<_CharT,_Alloc> __remainder_rope; + + if (0 == __n) + return; + + __exponent = __n / __exponentiate_threshold; + __rest = __n % __exponentiate_threshold; + if (0 == __rest) { + __remainder = 0; } else { - rest_buffer = DataAlloc::allocate(rounded_up_size(rest)); - uninitialized_fill_n(rest_buffer, rest, c); - __cond_store_eos(rest_buffer[rest]); + __rest_buffer = _Data_allocate(_S_rounded_up_size(__rest)); + uninitialized_fill_n(__rest_buffer, __rest, __c); + _S_cond_store_eos(__rest_buffer[__rest]); __STL_TRY { - remainder = RopeLeaf_from_char_ptr(rest_buffer, rest); + __remainder = _S_new_RopeLeaf(__rest_buffer, __rest, __a); } - __STL_UNWIND(RopeBase::free_string(rest_buffer, rest)) + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__rest_buffer, __rest, __a)) } - remainder_rope.tree_ptr = remainder; - if (exponent != 0) { - charT * base_buffer = - DataAlloc::allocate(rounded_up_size(exponentiate_threshold)); - RopeLeaf * base_leaf; - rope base_rope; - uninitialized_fill_n(base_buffer, exponentiate_threshold, c); - __cond_store_eos(base_buffer[exponentiate_threshold]); + __remainder_rope._M_tree_ptr = __remainder; + if (__exponent != 0) { + _CharT* __base_buffer = + _Data_allocate(_S_rounded_up_size(__exponentiate_threshold)); + _RopeLeaf* __base_leaf; + rope __base_rope; + uninitialized_fill_n(__base_buffer, __exponentiate_threshold, __c); + _S_cond_store_eos(__base_buffer[__exponentiate_threshold]); __STL_TRY { - base_leaf = RopeLeaf_from_char_ptr(base_buffer, - exponentiate_threshold); + __base_leaf = _S_new_RopeLeaf(__base_buffer, + __exponentiate_threshold, __a); } - __STL_UNWIND(RopeBase::free_string(base_buffer, exponentiate_threshold)) - base_rope.tree_ptr = base_leaf; - if (1 == exponent) { - result = base_rope; + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__base_buffer, + __exponentiate_threshold, __a)) + __base_rope._M_tree_ptr = __base_leaf; + if (1 == __exponent) { + __result = __base_rope; # ifndef __GC - __stl_assert(1 == result -> tree_ptr -> refcount); + __stl_assert(2 == __result._M_tree_ptr->_M_refcount); + // One each for base_rope and __result # endif } else { - result = power(base_rope, exponent, concat_fn()); + // XXX what is power()? + __result = power(__base_rope, __exponent, _Concat_fn()); } - if (0 != remainder) { - result += remainder_rope; + if (0 != __remainder) { + __result += __remainder_rope; } } else { - result = remainder_rope; + __result = __remainder_rope; } - tree_ptr = result.tree_ptr; - tree_ptr -> ref_nonnil(); + _M_tree_ptr = __result._M_tree_ptr; + _M_tree_ptr->_M_ref_nonnil(); } -template charT rope::empty_c_str[1]; +template + _CharT rope<_CharT,_Alloc>::_S_empty_c_str[1]; # ifdef __STL_PTHREADS - template - pthread_mutex_t rope::swap_lock = PTHREAD_MUTEX_INITIALIZER; + template + pthread_mutex_t + rope<_CharT,_Alloc>::_S_swap_lock = PTHREAD_MUTEX_INITIALIZER; # endif -template -const charT * rope::c_str() const { - if (0 == tree_ptr) { - empty_c_str[0] = __eos((charT *)0); // Possibly redundant, +template +const _CharT* rope<_CharT,_Alloc>::c_str() const { + if (0 == _M_tree_ptr) { + _S_empty_c_str[0] = _S_eos((_CharT*)0); // Possibly redundant, // but probably fast. - return empty_c_str; + return _S_empty_c_str; } - __GC_CONST charT * old_c_string = tree_ptr -> c_string; - if (0 != old_c_string) return(old_c_string); - size_t s = size(); - charT * result = DataAlloc::allocate(s + 1); - flatten(tree_ptr, result); - result[s] = __eos((charT *)0); + __GC_CONST _CharT* __old_c_string = _M_tree_ptr->_M_c_string; + if (0 != __old_c_string) return(__old_c_string); + size_t __s = size(); + _CharT* __result = _Data_allocate(__s + 1); + _S_flatten(_M_tree_ptr, __result); + __result[__s] = _S_eos((_CharT*)0); # ifdef __GC - tree_ptr -> c_string = result; + _M_tree_ptr->_M_c_string = __result; # else - if ((old_c_string = atomic_swap(&(tree_ptr -> c_string), result)) != 0) { + if ((__old_c_string = + _S_atomic_swap(&(_M_tree_ptr->_M_c_string), __result)) != 0) { // It must have been added in the interim. Hence it had to have been // separately allocated. Deallocate the old copy, since we just // replaced it. - destroy(old_c_string, old_c_string + s + 1); - DataAlloc::deallocate(old_c_string, s + 1); + destroy(__old_c_string, __old_c_string + __s + 1); + _Data_deallocate(__old_c_string, __s + 1); } # endif - return(result); + return(__result); } -template -const charT * rope::replace_with_c_str() { - if (0 == tree_ptr) { - empty_c_str[0] = __eos((charT *)0); - return empty_c_str; +template +const _CharT* rope<_CharT,_Alloc>::replace_with_c_str() { + if (0 == _M_tree_ptr) { + _S_empty_c_str[0] = _S_eos((_CharT*)0); + return _S_empty_c_str; } - __GC_CONST charT * old_c_string = tree_ptr -> c_string; - if (RopeBase::leaf == tree_ptr -> tag && 0 != old_c_string) { - return(old_c_string); + __GC_CONST _CharT* __old_c_string = _M_tree_ptr->_M_c_string; + if (_RopeRep::_S_leaf == _M_tree_ptr->_M_tag && 0 != __old_c_string) { + return(__old_c_string); } - size_t s = size(); - charT * result = DataAlloc::allocate(rounded_up_size(s)); - flatten(tree_ptr, result); - result[s] = __eos((charT *)0); - tree_ptr -> unref_nonnil(); - tree_ptr = RopeLeaf_from_char_ptr(result, s); - return(result); + size_t __s = size(); + _CharT* __result = _Data_allocate(_S_rounded_up_size(__s)); + _S_flatten(_M_tree_ptr, __result); + __result[__s] = _S_eos((_CharT*)0); + _M_tree_ptr->_M_unref_nonnil(); + _M_tree_ptr = _S_new_RopeLeaf(__result, __s, get_allocator()); + return(__result); } // Algorithm specializations. More should be added. #ifndef _MSC_VER // I couldn't get this to work with VC++ -template +template void -__rope_rotate(__rope_iterator first, - __rope_iterator middle, - __rope_iterator last) { - __stl_assert(first.container() == middle.container() - && middle.container() == last.container()); - rope& r(first.container()); - rope prefix = r.substr(0, first.index()); - rope suffix = r.substr(last.index(), r.size() - last.index()); - rope part1 = r.substr(middle.index(), - last.index() - middle.index()); - rope part2 = r.substr(first.index(), - middle.index() - first.index()); - r = prefix; - r += part1; - r += part2; - r += suffix; +_Rope_rotate(_Rope_iterator<_CharT,_Alloc> __first, + _Rope_iterator<_CharT,_Alloc> __middle, + _Rope_iterator<_CharT,_Alloc> __last) +{ + __stl_assert(__first.container() == __middle.container() + && __middle.container() == __last.container()); + rope<_CharT,_Alloc>& __r(__first.container()); + rope<_CharT,_Alloc> __prefix = __r.substr(0, __first.index()); + rope<_CharT,_Alloc> __suffix = + __r.substr(__last.index(), __r.size() - __last.index()); + rope<_CharT,_Alloc> __part1 = + __r.substr(__middle.index(), __last.index() - __middle.index()); + rope<_CharT,_Alloc> __part2 = + __r.substr(__first.index(), __middle.index() - __first.index()); + __r = __prefix; + __r += __part1; + __r += __part2; + __r += __suffix; } -inline void rotate(__rope_iterator first, - __rope_iterator middle, - __rope_iterator last) { - __rope_rotate(first, middle, last); +#if !defined(__GNUC__) +// Appears to confuse g++ +inline void rotate(_Rope_iterator __first, + _Rope_iterator __middle, + _Rope_iterator __last) { + _Rope_rotate(__first, __middle, __last); } +#endif # if 0 // Probably not useful for several reasons: @@ -1518,10 +1530,11 @@ inline void rotate(__rope_iterator first, // - wchar_t is 4 bytes wide on most UNIX platforms, making it unattractive // for unicode strings. Unsigned short may be a better character // type. -inline void rotate(__rope_iterator first, - __rope_iterator middle, - __rope_iterator last) { - __rope_rotate(first, middle, last); +inline void rotate( + _Rope_iterator __first, + _Rope_iterator __middle, + _Rope_iterator __last) { + _Rope_rotate(__first, __middle, __last); } # endif #endif /* _MSC_VER */ diff --git a/libstdc++/stl/stl_algo.h b/libstdc++/stl/stl_algo.h index 5cde42c1cd2..57607ba5d49 100644 --- a/libstdc++/stl/stl_algo.h +++ b/libstdc++/stl/stl_algo.h @@ -39,2453 +39,2685 @@ __STL_BEGIN_NAMESPACE #pragma set woff 1209 #endif -template -inline const T& __median(const T& a, const T& b, const T& c) { - if (a < b) - if (b < c) - return b; - else if (a < c) - return c; +// __median (an extension, not present in the C++ standard). + +template +inline const _Tp& __median(const _Tp& __a, const _Tp& __b, const _Tp& __c) { + if (__a < __b) + if (__b < __c) + return __b; + else if (__a < __c) + return __c; else - return a; - else if (a < c) - return a; - else if (b < c) - return c; + return __a; + else if (__a < __c) + return __a; + else if (__b < __c) + return __c; else - return b; + return __b; } -template -inline const T& __median(const T& a, const T& b, const T& c, Compare comp) { - if (comp(a, b)) - if (comp(b, c)) - return b; - else if (comp(a, c)) - return c; +template +inline const _Tp& +__median(const _Tp& __a, const _Tp& __b, const _Tp& __c, _Compare __comp) { + if (__comp(__a, __b)) + if (__comp(__b, __c)) + return __b; + else if (__comp(__a, __c)) + return __c; else - return a; - else if (comp(a, c)) - return a; - else if (comp(b, c)) - return c; + return __a; + else if (__comp(__a, __c)) + return __a; + else if (__comp(__b, __c)) + return __c; else - return b; + return __b; } -template -Function for_each(InputIterator first, InputIterator last, Function f) { - for ( ; first != last; ++first) - f(*first); - return f; +// for_each. Apply a function to every element of a range. +template +_Function for_each(_InputIter __first, _InputIter __last, _Function __f) { + for ( ; __first != __last; ++__first) + __f(*__first); + return __f; } -template -InputIterator find(InputIterator first, InputIterator last, const T& value) { - while (first != last && *first != value) ++first; - return first; +// find and find_if. + +template +inline _InputIter find(_InputIter __first, _InputIter __last, + const _Tp& __val, + input_iterator_tag) +{ + while (__first != __last && *__first != __val) + ++__first; + return __first; +} + +template +inline _InputIter find_if(_InputIter __first, _InputIter __last, + _Predicate __pred, + input_iterator_tag) +{ + while (__first != __last && !__pred(*__first)) + ++__first; + return __first; +} + +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +_RandomAccessIter find(_RandomAccessIter __first, _RandomAccessIter __last, + const _Tp& __val, + random_access_iterator_tag) +{ + typename iterator_traits<_RandomAccessIter>::difference_type __trip_count + = (__last - __first) >> 2; + + for ( ; __trip_count > 0 ; --__trip_count) { + if (*__first == __val) return __first; + ++__first; + + if (*__first == __val) return __first; + ++__first; + + if (*__first == __val) return __first; + ++__first; + + if (*__first == __val) return __first; + ++__first; + } + + switch(__last - __first) { + case 3: + if (*__first == __val) return __first; + ++__first; + case 2: + if (*__first == __val) return __first; + ++__first; + case 1: + if (*__first == __val) return __first; + ++__first; + case 0: + default: + return __last; + } +} + +template +_RandomAccessIter find_if(_RandomAccessIter __first, _RandomAccessIter __last, + _Predicate __pred, + random_access_iterator_tag) +{ + typename iterator_traits<_RandomAccessIter>::difference_type __trip_count + = (__last - __first) >> 2; + + for ( ; __trip_count > 0 ; --__trip_count) { + if (__pred(*__first)) return __first; + ++__first; + + if (__pred(*__first)) return __first; + ++__first; + + if (__pred(*__first)) return __first; + ++__first; + + if (__pred(*__first)) return __first; + ++__first; + } + + switch(__last - __first) { + case 3: + if (__pred(*__first)) return __first; + ++__first; + case 2: + if (__pred(*__first)) return __first; + ++__first; + case 1: + if (__pred(*__first)) return __first; + ++__first; + case 0: + default: + return __last; + } +} + +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +template +inline _InputIter find(_InputIter __first, _InputIter __last, + const _Tp& __val) +{ + return find(__first, __last, __val, __ITERATOR_CATEGORY(__first)); } -template -InputIterator find_if(InputIterator first, InputIterator last, - Predicate pred) { - while (first != last && !pred(*first)) ++first; - return first; +template +inline _InputIter find_if(_InputIter __first, _InputIter __last, + _Predicate __pred) { + return find_if(__first, __last, __pred, __ITERATOR_CATEGORY(__first)); } -template -ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last) { - if (first == last) return last; - ForwardIterator next = first; - while(++next != last) { - if (*first == *next) return first; - first = next; +// adjacent_find. + +template +_ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last) { + if (__first == __last) + return __last; + _ForwardIter __next = __first; + while(++__next != __last) { + if (*__first == *__next) + return __first; + __first = __next; } - return last; + return __last; } -template -ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last, - BinaryPredicate binary_pred) { - if (first == last) return last; - ForwardIterator next = first; - while(++next != last) { - if (binary_pred(*first, *next)) return first; - first = next; +template +_ForwardIter adjacent_find(_ForwardIter __first, _ForwardIter __last, + _BinaryPredicate __binary_pred) { + if (__first == __last) + return __last; + _ForwardIter __next = __first; + while(++__next != __last) { + if (__binary_pred(*__first, *__next)) + return __first; + __first = __next; } - return last; + return __last; } -template -void count(InputIterator first, InputIterator last, const T& value, - Size& n) { - for ( ; first != last; ++first) - if (*first == value) - ++n; +// count and count_if. There are two version of each, one whose return type +// type is void and one (present only if we have partial specialization) +// whose return type is iterator_traits<_InputIter>::difference_type. The +// C++ standard only has the latter version, but the former, which was present +// in the HP STL, is retained for backward compatibility. + +template +void count(_InputIter __first, _InputIter __last, const _Tp& __value, + _Size& __n) { + for ( ; __first != __last; ++__first) + if (*__first == __value) + ++__n; } -template -void count_if(InputIterator first, InputIterator last, Predicate pred, - Size& n) { - for ( ; first != last; ++first) - if (pred(*first)) - ++n; +template +void count_if(_InputIter __first, _InputIter __last, _Predicate __pred, + _Size& __n) { + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + ++__n; } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION -template -typename iterator_traits::difference_type -count(InputIterator first, InputIterator last, const T& value) { - typename iterator_traits::difference_type n = 0; - for ( ; first != last; ++first) - if (*first == value) - ++n; - return n; +template +typename iterator_traits<_InputIter>::difference_type +count(_InputIter __first, _InputIter __last, const _Tp& __value) { + typename iterator_traits<_InputIter>::difference_type __n = 0; + for ( ; __first != __last; ++__first) + if (*__first == __value) + ++__n; + return __n; } -template -typename iterator_traits::difference_type -count_if(InputIterator first, InputIterator last, Predicate pred) { - typename iterator_traits::difference_type n = 0; - for ( ; first != last; ++first) - if (pred(*first)) - ++n; - return n; +template +typename iterator_traits<_InputIter>::difference_type +count_if(_InputIter __first, _InputIter __last, _Predicate __pred) { + typename iterator_traits<_InputIter>::difference_type __n = 0; + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + ++__n; + return __n; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template -ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - Distance1*, Distance2*) { - Distance1 d1 = 0; - distance(first1, last1, d1); - Distance2 d2 = 0; - distance(first2, last2, d2); +// search. - if (d1 < d2) return last1; +template +_ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2) +{ + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; - ForwardIterator1 current1 = first1; - ForwardIterator2 current2 = first2; + // Test for a pattern of length 1. + _ForwardIter2 __tmp(__first2); + ++__tmp; + if (__tmp == __last2) + return find(__first1, __last1, *__first2); - while (current2 != last2) - if (*current1 == *current2) { - ++current1; - ++current2; - } - else { - if (d1 == d2) - return last1; - else { - current1 = ++first1; - current2 = first2; - --d1; - } + // General case. + + _ForwardIter2 __p1, __p; + + __p1 = __first2; ++__p1; + + _ForwardIter1 __current = __first1; + + while (__first1 != __last1) { + __first1 = find(__first1, __last1, *__first2); + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) + return __last1; + + while (*__current == *__p) { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; } - return first1; + + ++__first1; + } + return __first1; } -template -inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2) +template +_ForwardIter1 search(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2, + _BinaryPred __predicate) { - return __search(first1, last1, first2, last2, distance_type(first1), - distance_type(first2)); -} + // Test for empty ranges + if (__first1 == __last1 || __first2 == __last2) + return __first1; + + // Test for a pattern of length 1. + _ForwardIter2 __tmp(__first2); + ++__tmp; + if (__tmp == __last2) + return find(__first1, __last1, *__first2); -template -ForwardIterator1 __search(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate binary_pred, Distance1*, Distance2*) { - Distance1 d1 = 0; - distance(first1, last1, d1); - Distance2 d2 = 0; - distance(first2, last2, d2); + // General case. - if (d1 < d2) return last1; + _ForwardIter2 __p1, __p; - ForwardIterator1 current1 = first1; - ForwardIterator2 current2 = first2; + __p1 = __first2; ++__p1; - while (current2 != last2) - if (binary_pred(*current1, *current2)) { - ++current1; - ++current2; + _ForwardIter1 __current = __first1; + + while (__first1 != __last1) { + while (__first1 != __last1) { + if (__predicate(*__first1, *__first2)) + break; + ++__first1; } - else { - if (d1 == d2) - return last1; - else { - current1 = ++first1; - current2 = first2; - --d1; - } + while (__first1 != __last1 && !__predicate(*__first1, *__first2)) + ++__first1; + if (__first1 == __last1) + return __last1; + + __p = __p1; + __current = __first1; + if (++__current == __last1) return __last1; + + while (__predicate(*__current, *__p)) { + if (++__p == __last2) + return __first1; + if (++__current == __last1) + return __last1; } - return first1; -} -template -inline ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate binary_pred) { - return __search(first1, last1, first2, last2, binary_pred, - distance_type(first1), distance_type(first2)); + ++__first1; + } + return __first1; } -template -ForwardIterator search_n(ForwardIterator first, ForwardIterator last, - Integer count, const T& value) { - if (count <= 0) - return first; +// search_n. Search for __count consecutive copies of __val. + +template +_ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, + _Integer __count, const _Tp& __val) { + if (__count <= 0) + return __first; else { - first = find(first, last, value); - while (first != last) { - Integer n = count - 1; - ForwardIterator i = first; - ++i; - while (i != last && n != 0 && *i == value) { - ++i; - --n; + __first = find(__first, __last, __val); + while (__first != __last) { + _Integer __n = __count - 1; + _ForwardIter __i = __first; + ++__i; + while (__i != __last && __n != 0 && *__i == __val) { + ++__i; + --__n; } - if (n == 0) - return first; + if (__n == 0) + return __first; else - first = find(i, last, value); + __first = find(__i, __last, __val); } - return last; + return __last; } } -template -ForwardIterator search_n(ForwardIterator first, ForwardIterator last, - Integer count, const T& value, - BinaryPredicate binary_pred) { - if (count <= 0) - return first; +template +_ForwardIter search_n(_ForwardIter __first, _ForwardIter __last, + _Integer __count, const _Tp& __val, + _BinaryPred __binary_pred) { + if (__count <= 0) + return __first; else { - while (first != last) { - if (binary_pred(*first, value)) break; - ++first; - } - while (first != last) { - Integer n = count - 1; - ForwardIterator i = first; - ++i; - while (i != last && n != 0 && binary_pred(*i, value)) { - ++i; - --n; + while (__first != __last) { + if (__binary_pred(*__first, __val)) + break; + ++__first; + } + while (__first != __last) { + _Integer __n = __count - 1; + _ForwardIter __i = __first; + ++__i; + while (__i != __last && __n != 0 && __binary_pred(*__i, __val)) { + ++__i; + --__n; } - if (n == 0) - return first; + if (__n == 0) + return __first; else { - while (i != last) { - if (binary_pred(*i, value)) break; - ++i; + while (__i != __last) { + if (__binary_pred(*__i, __val)) + break; + ++__i; } - first = i; + __first = __i; } } - return last; + return __last; } } -template -ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2) { - for ( ; first1 != last1; ++first1, ++first2) - iter_swap(first1, first2); - return first2; +// swap_ranges + +template +_ForwardIter2 swap_ranges(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2) { + for ( ; __first1 != __last1; ++__first1, ++__first2) + iter_swap(__first1, __first2); + return __first2; } -template -OutputIterator transform(InputIterator first, InputIterator last, - OutputIterator result, UnaryOperation op) { - for ( ; first != last; ++first, ++result) - *result = op(*first); - return result; +// transform + +template +_OutputIter transform(_InputIter __first, _InputIter __last, + _OutputIter __result, _UnaryOperation __opr) { + for ( ; __first != __last; ++__first, ++__result) + *__result = __opr(*__first); + return __result; } -template -OutputIterator transform(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, OutputIterator result, - BinaryOperation binary_op) { - for ( ; first1 != last1; ++first1, ++first2, ++result) - *result = binary_op(*first1, *first2); - return result; +template +_OutputIter transform(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _OutputIter __result, + _BinaryOperation __binary_op) { + for ( ; __first1 != __last1; ++__first1, ++__first2, ++__result) + *__result = __binary_op(*__first1, *__first2); + return __result; } -template -void replace(ForwardIterator first, ForwardIterator last, const T& old_value, - const T& new_value) { - for ( ; first != last; ++first) - if (*first == old_value) *first = new_value; +// replace, replace_if, replace_copy, replace_copy_if + +template +void replace(_ForwardIter __first, _ForwardIter __last, + const _Tp& __old_value, const _Tp& __new_value) { + for ( ; __first != __last; ++__first) + if (*__first == __old_value) + *__first = __new_value; } -template -void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, - const T& new_value) { - for ( ; first != last; ++first) - if (pred(*first)) *first = new_value; +template +void replace_if(_ForwardIter __first, _ForwardIter __last, + _Predicate __pred, const _Tp& __new_value) { + for ( ; __first != __last; ++__first) + if (__pred(*__first)) + *__first = __new_value; } -template -OutputIterator replace_copy(InputIterator first, InputIterator last, - OutputIterator result, const T& old_value, - const T& new_value) { - for ( ; first != last; ++first, ++result) - *result = *first == old_value ? new_value : *first; - return result; +template +_OutputIter replace_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + const _Tp& __old_value, const _Tp& __new_value) { + for ( ; __first != __last; ++__first, ++__result) + *__result = *__first == __old_value ? __new_value : *__first; + return __result; } -template -OutputIterator replace_copy_if(Iterator first, Iterator last, - OutputIterator result, Predicate pred, - const T& new_value) { - for ( ; first != last; ++first, ++result) - *result = pred(*first) ? new_value : *first; - return result; +template +_OutputIter replace_copy_if(Iterator __first, Iterator __last, + _OutputIter __result, + _Predicate __pred, const _Tp& __new_value) { + for ( ; __first != __last; ++__first, ++__result) + *__result = __pred(*__first) ? __new_value : *__first; + return __result; } -template -void generate(ForwardIterator first, ForwardIterator last, Generator gen) { - for ( ; first != last; ++first) - *first = gen(); -} - -template -OutputIterator generate_n(OutputIterator first, Size n, Generator gen) { - for ( ; n > 0; --n, ++first) - *first = gen(); - return first; +// generate and generate_n + +template +void generate(_ForwardIter __first, _ForwardIter __last, _Generator __gen) { + for ( ; __first != __last; ++__first) + *__first = __gen(); } -template -OutputIterator remove_copy(InputIterator first, InputIterator last, - OutputIterator result, const T& value) { - for ( ; first != last; ++first) - if (*first != value) { - *result = *first; - ++result; - } - return result; +template +_OutputIter generate_n(_OutputIter __first, _Size __n, _Generator __gen) { + for ( ; __n > 0; --__n, ++__first) + *__first = __gen(); + return __first; } -template -OutputIterator remove_copy_if(InputIterator first, InputIterator last, - OutputIterator result, Predicate pred) { - for ( ; first != last; ++first) - if (!pred(*first)) { - *result = *first; - ++result; - } - return result; -} +// remove, remove_if, remove_copy, remove_copy_if -template -ForwardIterator remove(ForwardIterator first, ForwardIterator last, - const T& value) { - first = find(first, last, value); - ForwardIterator next = first; - return first == last ? first : remove_copy(++next, last, first, value); +template +_OutputIter remove_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, const _Tp& __value) { + for ( ; __first != __last; ++__first) + if (*__first != __value) { + *__result = *__first; + ++__result; + } + return __result; } -template -ForwardIterator remove_if(ForwardIterator first, ForwardIterator last, - Predicate pred) { - first = find_if(first, last, pred); - ForwardIterator next = first; - return first == last ? first : remove_copy_if(++next, last, first, pred); +template +_OutputIter remove_copy_if(_InputIter __first, _InputIter __last, + _OutputIter __result, _Predicate __pred) { + for ( ; __first != __last; ++__first) + if (!__pred(*__first)) { + *__result = *__first; + ++__result; + } + return __result; +} + +template +_ForwardIter remove(_ForwardIter __first, _ForwardIter __last, + const _Tp& __value) { + __first = find(__first, __last, __value); + _ForwardIter __i = __first; + return __first == __last ? __first + : remove_copy(++__i, __last, __first, __value); } -template -ForwardIterator __unique_copy(InputIterator first, InputIterator last, - ForwardIterator result, forward_iterator_tag) { - *result = *first; - while (++first != last) - if (*result != *first) *++result = *first; - return ++result; +template +_ForwardIter remove_if(_ForwardIter __first, _ForwardIter __last, + _Predicate __pred) { + __first = find_if(__first, __last, __pred); + _ForwardIter __i = __first; + return __first == __last ? __first + : remove_copy_if(++__i, __last, __first, __pred); } +// unique and unique_copy -template -OutputIterator __unique_copy(InputIterator first, InputIterator last, - OutputIterator result, T*) { - T value = *first; - *result = value; - while (++first != last) - if (value != *first) { - value = *first; - *++result = value; +template +_OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, _Tp*) { + _Tp __value = *__first; + *__result = __value; + while (++__first != __last) + if (__value != *__first) { + __value = *__first; + *++__result = __value; } - return ++result; + return ++__result; } -template -inline OutputIterator __unique_copy(InputIterator first, InputIterator last, - OutputIterator result, - output_iterator_tag) { - return __unique_copy(first, last, result, value_type(first)); +template +inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + output_iterator_tag) { + return __unique_copy(__first, __last, __result, __VALUE_TYPE(__first)); } -template -inline OutputIterator unique_copy(InputIterator first, InputIterator last, - OutputIterator result) { - if (first == last) return result; - return __unique_copy(first, last, result, iterator_category(result)); +template +_ForwardIter __unique_copy(_InputIter __first, _InputIter __last, + _ForwardIter __result, forward_iterator_tag) { + *__result = *__first; + while (++__first != __last) + if (*__result != *__first) *++__result = *__first; + return ++__result; } -template -ForwardIterator __unique_copy(InputIterator first, InputIterator last, - ForwardIterator result, - BinaryPredicate binary_pred, - forward_iterator_tag) { - *result = *first; - while (++first != last) - if (!binary_pred(*result, *first)) *++result = *first; - return ++result; + +template +inline _OutputIter unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { + if (__first == __last) return __result; + return __unique_copy(__first, __last, __result, + __ITERATOR_CATEGORY(__result)); } -template -OutputIterator __unique_copy(InputIterator first, InputIterator last, - OutputIterator result, - BinaryPredicate binary_pred, T*) { - T value = *first; - *result = value; - while (++first != last) - if (!binary_pred(value, *first)) { - value = *first; - *++result = value; +template +_OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + _BinaryPredicate __binary_pred, _Tp*) { + _Tp __value = *__first; + *__result = __value; + while (++__first != __last) + if (!__binary_pred(__value, *__first)) { + __value = *__first; + *++__result = __value; } - return ++result; + return ++__result; } -template -inline OutputIterator __unique_copy(InputIterator first, InputIterator last, - OutputIterator result, - BinaryPredicate binary_pred, - output_iterator_tag) { - return __unique_copy(first, last, result, binary_pred, value_type(first)); +template +inline _OutputIter __unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + _BinaryPredicate __binary_pred, + output_iterator_tag) { + return __unique_copy(__first, __last, __result, __binary_pred, + __VALUE_TYPE(__first)); } -template -inline OutputIterator unique_copy(InputIterator first, InputIterator last, - OutputIterator result, - BinaryPredicate binary_pred) { - if (first == last) return result; - return __unique_copy(first, last, result, binary_pred, - iterator_category(result)); -} +template +_ForwardIter __unique_copy(_InputIter __first, _InputIter __last, + _ForwardIter __result, + _BinaryPredicate __binary_pred, + forward_iterator_tag) { + *__result = *__first; + while (++__first != __last) + if (!__binary_pred(*__result, *__first)) *++__result = *__first; + return ++__result; +} -template -ForwardIterator unique(ForwardIterator first, ForwardIterator last) { - first = adjacent_find(first, last); - return unique_copy(first, last, first); +template +inline _OutputIter unique_copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + _BinaryPredicate __binary_pred) { + if (__first == __last) return __result; + return __unique_copy(__first, __last, __result, __binary_pred, + __ITERATOR_CATEGORY(__result)); } - -template -ForwardIterator unique(ForwardIterator first, ForwardIterator last, - BinaryPredicate binary_pred) { - first = adjacent_find(first, last, binary_pred); - return unique_copy(first, last, first, binary_pred); + +template +_ForwardIter unique(_ForwardIter __first, _ForwardIter __last) { + __first = adjacent_find(__first, __last); + return unique_copy(__first, __last, __first); } -template -void __reverse(BidirectionalIterator first, BidirectionalIterator last, +template +_ForwardIter unique(_ForwardIter __first, _ForwardIter __last, + _BinaryPredicate __binary_pred) { + __first = adjacent_find(__first, __last, __binary_pred); + return unique_copy(__first, __last, __first, __binary_pred); +} + +// reverse and reverse_copy, and their auxiliary functions + +template +void __reverse(_BidirectionalIter __first, _BidirectionalIter __last, bidirectional_iterator_tag) { while (true) - if (first == last || first == --last) + if (__first == __last || __first == --__last) return; else - iter_swap(first++, last); + iter_swap(__first++, __last); } -template -void __reverse(RandomAccessIterator first, RandomAccessIterator last, +template +void __reverse(_RandomAccessIter __first, _RandomAccessIter __last, random_access_iterator_tag) { - while (first < last) iter_swap(first++, --last); + while (__first < __last) + iter_swap(__first++, --__last); } -template -inline void reverse(BidirectionalIterator first, BidirectionalIterator last) { - __reverse(first, last, iterator_category(first)); +template +inline void reverse(_BidirectionalIter __first, _BidirectionalIter __last) { + __reverse(__first, __last, __ITERATOR_CATEGORY(__first)); } -template -OutputIterator reverse_copy(BidirectionalIterator first, - BidirectionalIterator last, - OutputIterator result) { - while (first != last) { - --last; - *result = *last; - ++result; +template +_OutputIter reverse_copy(_BidirectionalIter __first, + _BidirectionalIter __last, + _OutputIter __result) { + while (__first != __last) { + --__last; + *__result = *__last; + ++__result; } - return result; + return __result; } -template -void __rotate(ForwardIterator first, ForwardIterator middle, - ForwardIterator last, Distance*, forward_iterator_tag) { - for (ForwardIterator i = middle; ;) { - iter_swap(first, i); - ++first; - ++i; - if (first == middle) { - if (i == last) return; - middle = i; - } - else if (i == last) - i = middle; +// rotate and rotate_copy, and their auxiliary functions + +template +_EuclideanRingElement __gcd(_EuclideanRingElement __m, + _EuclideanRingElement __n) +{ + while (__n != 0) { + _EuclideanRingElement __t = __m % __n; + __m = __n; + __n = __t; } + return __m; } -template -void __rotate(BidirectionalIterator first, BidirectionalIterator middle, - BidirectionalIterator last, Distance*, - bidirectional_iterator_tag) { - reverse(first, middle); - reverse(middle, last); - reverse(first, last); +template +_ForwardIter __rotate(_ForwardIter __first, + _ForwardIter __middle, + _ForwardIter __last, + _Distance*, + forward_iterator_tag) { + if (__first == __middle) + return __last; + if (__last == __middle) + return __first; + + _ForwardIter __first2 = __middle; + do { + swap(*__first++, *__first2++); + if (__first == __middle) + __middle = __first2; + } while (__first2 != __last); + + _ForwardIter __new_middle = __first; + + __first2 = __middle; + + while (__first2 != __last) { + swap (*__first++, *__first2++); + if (__first == __middle) + __middle = __first2; + else if (__first2 == __last) + __first2 = __middle; + } + + return __new_middle; } -template -EuclideanRingElement __gcd(EuclideanRingElement m, EuclideanRingElement n) -{ - while (n != 0) { - EuclideanRingElement t = m % n; - m = n; - n = t; - } - return m; -} - -template -void __rotate_cycle(RandomAccessIterator first, RandomAccessIterator last, - RandomAccessIterator initial, Distance shift, T*) { - T value = *initial; - RandomAccessIterator ptr1 = initial; - RandomAccessIterator ptr2 = ptr1 + shift; - while (ptr2 != initial) { - *ptr1 = *ptr2; - ptr1 = ptr2; - if (last - ptr2 > shift) - ptr2 += shift; - else - ptr2 = first + (shift - (last - ptr2)); + +template +_BidirectionalIter __rotate(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance*, + bidirectional_iterator_tag) { + if (__first == __middle) + return __last; + if (__last == __middle) + return __first; + + __reverse(__first, __middle, bidirectional_iterator_tag()); + __reverse(__middle, __last, bidirectional_iterator_tag()); + + while (__first != __middle && __middle != __last) + swap (*__first++, *--__last); + + if (__first == __middle) { + __reverse(__middle, __last, bidirectional_iterator_tag()); + return __last; + } + else { + __reverse(__first, __middle, bidirectional_iterator_tag()); + return __first; } - *ptr1 = value; } -template -void __rotate(RandomAccessIterator first, RandomAccessIterator middle, - RandomAccessIterator last, Distance*, - random_access_iterator_tag) { - Distance n = __gcd(last - first, middle - first); - while (n--) - __rotate_cycle(first, last, first + n, middle - first, - value_type(first)); +template +_RandomAccessIter __rotate(_RandomAccessIter __first, + _RandomAccessIter __middle, + _RandomAccessIter __last, + _Distance *, _Tp *) { + + _Distance __n = __last - __first; + _Distance __k = __middle - __first; + _Distance __l = __n - __k; + _RandomAccessIter __result = __first + (__last - __middle); + + if (__k == __l) { + swap_ranges(__first, __middle, __middle); + return __result; + } + + _Distance __d = __gcd(__n, __k); + + for (_Distance __i = 0; __i < __d; __i++) { + _Tp __tmp = *__first; + _RandomAccessIter __p = __first; + + if (__k < __l) { + for (_Distance __j = 0; __j < __l/__d; __j++) { + if (__p > __first + __l) { + *__p = *(__p - __l); + __p -= __l; + } + + *__p = *(__p + __k); + __p += __k; + } + } + + else { + for (_Distance __j = 0; __j < __k/__d - 1; __j ++) { + if (__p < __last - __k) { + *__p = *(__p + __k); + __p += __k; + } + + *__p = * (__p - __l); + __p -= __l; + } + } + + *__p = __tmp; + ++__first; + } + + return __result; } -template -inline void rotate(ForwardIterator first, ForwardIterator middle, - ForwardIterator last) { - if (first == middle || middle == last) return; - __rotate(first, middle, last, distance_type(first), - iterator_category(first)); +template +inline _ForwardIter rotate(_ForwardIter __first, _ForwardIter __middle, + _ForwardIter __last) { + return __rotate(__first, __middle, __last, + __DISTANCE_TYPE(__first), + __ITERATOR_CATEGORY(__first)); } -template -OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle, - ForwardIterator last, OutputIterator result) { - return copy(first, middle, copy(middle, last, result)); +template +_OutputIter rotate_copy(_ForwardIter __first, _ForwardIter __middle, + _ForwardIter __last, _OutputIter __result) { + return copy(__first, __middle, copy(__middle, __last, __result)); } -template -void __random_shuffle(RandomAccessIterator first, RandomAccessIterator last, - Distance*) { - if (first == last) return; - for (RandomAccessIterator i = first + 1; i != last; ++i) +// Return a random number in the range [0, __n). This function encapsulates +// whether we're using rand (part of the standard C library) or lrand48 +// (not standard, but a much better choice whenever it's available). + +template +inline _Distance __random_number(_Distance __n) { #ifdef __STL_NO_DRAND48 - iter_swap(i, first + Distance(rand() % ((i - first) + 1))); + return rand() % __n; #else - iter_swap(i, first + Distance(lrand48() % ((i - first) + 1))); + return lrand48() % __n; #endif } -template -inline void random_shuffle(RandomAccessIterator first, - RandomAccessIterator last) { - __random_shuffle(first, last, distance_type(first)); +// random_shuffle + +template +inline void random_shuffle(_RandomAccessIter __first, + _RandomAccessIter __last) { + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + iter_swap(__i, __first + __random_number((__i - __first) + 1)); } -template -void random_shuffle(RandomAccessIterator first, RandomAccessIterator last, - RandomNumberGenerator& rand) { - if (first == last) return; - for (RandomAccessIterator i = first + 1; i != last; ++i) - iter_swap(i, first + rand((i - first) + 1)); +template +void random_shuffle(_RandomAccessIter __first, _RandomAccessIter __last, + _RandomNumberGenerator& __rand) { + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + iter_swap(__i, __first + __rand((__i - __first) + 1)); } -template -OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last, - OutputIterator out, const Distance n) +// random_sample and random_sample_n (extensions, not part of the standard). + +template +_OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, + _OutputIter __out, const _Distance __n) { - Distance remaining = 0; - distance(first, last, remaining); - Distance m = min(n, remaining); + _Distance __remaining = 0; + distance(__first, __last, __remaining); + _Distance __m = min(__n, __remaining); - while (m > 0) { -#ifdef __STL_NO_DRAND48 - if (rand() % remaining < m) { -#else - if (lrand48() % remaining < m) { -#endif - *out = *first; - ++out; - --m; + while (__m > 0) { + if (__random_number(__remaining) < __m) { + *__out = *__first; + ++__out; + --__m; } - --remaining; - ++first; + --__remaining; + ++__first; } - return out; + return __out; } -template -OutputIterator random_sample_n(ForwardIterator first, ForwardIterator last, - OutputIterator out, const Distance n, - RandomNumberGenerator& rand) +template +_OutputIter random_sample_n(_ForwardIter __first, _ForwardIter __last, + _OutputIter __out, const _Distance __n, + _RandomNumberGenerator& __rand) { - Distance remaining = 0; - distance(first, last, remaining); - Distance m = min(n, remaining); + _Distance __remaining = 0; + distance(__first, __last, __remaining); + _Distance __m = min(__n, __remaining); - while (m > 0) { - if (rand(remaining) < m) { - *out = *first; - ++out; - --m; + while (__m > 0) { + if (__rand(__remaining) < __m) { + *__out = *__first; + ++__out; + --__m; } - --remaining; - ++first; + --__remaining; + ++__first; } - return out; + return __out; } -template -RandomAccessIterator __random_sample(InputIterator first, InputIterator last, - RandomAccessIterator out, - const Distance n) +template +_RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out, + const _Distance __n) { - Distance m = 0; - Distance t = n; - for ( ; first != last && m < n; ++m, ++first) - out[m] = *first; + _Distance __m = 0; + _Distance __t = __n; + for ( ; __first != __last && __m < __n; ++__m, ++__first) + __out[__m] = *__first; - while (first != last) { - ++t; -#ifdef __STL_NO_DRAND48 - Distance M = rand() % t; -#else - Distance M = lrand48() % t; -#endif - if (M < n) - out[M] = *first; - ++first; + while (__first != __last) { + ++__t; + _Distance __M = __random_number(__t); + if (__M < __n) + __out[__M] = *__first; + ++__first; } - return out + m; + return __out + __m; } -template -RandomAccessIterator __random_sample(InputIterator first, InputIterator last, - RandomAccessIterator out, - RandomNumberGenerator& rand, - const Distance n) +template +_RandomAccessIter __random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out, + _RandomNumberGenerator& __rand, + const _Distance __n) { - Distance m = 0; - Distance t = n; - for ( ; first != last && m < n; ++m, ++first) - out[m] = *first; + _Distance __m = 0; + _Distance __t = __n; + for ( ; __first != __last && __m < __n; ++__m, ++__first) + __out[__m] = *__first; - while (first != last) { - ++t; - Distance M = rand(t); - if (M < n) - out[M] = *first; - ++first; + while (__first != __last) { + ++__t; + _Distance __M = __rand(__t); + if (__M < __n) + __out[__M] = *__first; + ++__first; } - return out + m; + return __out + __m; } -template -inline RandomAccessIterator -random_sample(InputIterator first, InputIterator last, - RandomAccessIterator out_first, RandomAccessIterator out_last) +template +inline _RandomAccessIter +random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out_first, _RandomAccessIter __out_last) { - return __random_sample(first, last, out_first, out_last - out_first); + return __random_sample(__first, __last, + __out_first, __out_last - __out_first); } -template -inline RandomAccessIterator -random_sample(InputIterator first, InputIterator last, - RandomAccessIterator out_first, RandomAccessIterator out_last, - RandomNumberGenerator& rand) + +template +inline _RandomAccessIter +random_sample(_InputIter __first, _InputIter __last, + _RandomAccessIter __out_first, _RandomAccessIter __out_last, + _RandomNumberGenerator& __rand) { - return __random_sample(first, last, out_first, rand, out_last - out_first); + return __random_sample(__first, __last, + __out_first, __rand, + __out_last - __out_first); } +// partition, stable_partition, and their auxiliary functions + +template +_ForwardIter __partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred, + forward_iterator_tag) { + if (__first == __last) return __first; + + while (__pred(*__first)) + if (++__first == __last) return __first; + + _ForwardIter __next = __first; + while (++__next != __last) + if (__pred(*__next)) { + swap(*__first, *__next); + ++__first; + } + + return __first; +} -template -BidirectionalIterator partition(BidirectionalIterator first, - BidirectionalIterator last, Predicate pred) { +template +_BidirectionalIter __partition(_BidirectionalIter __first, + _BidirectionalIter __last, + _Predicate __pred, + bidirectional_iterator_tag) { while (true) { while (true) - if (first == last) - return first; - else if (pred(*first)) - ++first; + if (__first == __last) + return __first; + else if (__pred(*__first)) + ++__first; else break; - --last; + --__last; while (true) - if (first == last) - return first; - else if (!pred(*last)) - --last; + if (__first == __last) + return __first; + else if (!__pred(*__last)) + --__last; else break; - iter_swap(first, last); - ++first; - } -} - -template -ForwardIterator __inplace_stable_partition(ForwardIterator first, - ForwardIterator last, - Predicate pred, Distance len) { - if (len == 1) return pred(*first) ? last : first; - ForwardIterator middle = first; - advance(middle, len / 2); - ForwardIterator - first_cut = __inplace_stable_partition(first, middle, pred, len / 2); - ForwardIterator - second_cut = __inplace_stable_partition(middle, last, pred, - len - len / 2); - rotate(first_cut, middle, second_cut); - len = 0; - distance(middle, second_cut, len); - advance(first_cut, len); - return first_cut; -} - -template -ForwardIterator __stable_partition_adaptive(ForwardIterator first, - ForwardIterator last, - Predicate pred, Distance len, - Pointer buffer, - Distance buffer_size) { - if (len <= buffer_size) { - ForwardIterator result1 = first; - Pointer result2 = buffer; - for ( ; first != last ; ++first) - if (pred(*first)) { - *result1 = *first; - ++result1; + iter_swap(__first, __last); + ++__first; + } +} + +template +inline _ForwardIter partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred) { + return __partition(__first, __last, __pred, __ITERATOR_CATEGORY(__first)); +} + + +template +_ForwardIter __inplace_stable_partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred, _Distance __len) { + if (__len == 1) + return __pred(*__first) ? __last : __first; + _ForwardIter __middle = __first; + advance(__middle, __len / 2); + return rotate(__inplace_stable_partition(__first, __middle, __pred, + __len / 2), + __middle, + __inplace_stable_partition(__middle, __last, __pred, + __len - __len / 2)); +} + +template +_ForwardIter __stable_partition_adaptive(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred, _Distance __len, + _Pointer __buffer, + _Distance __buffer_size) +{ + if (__len <= __buffer_size) { + _ForwardIter __result1 = __first; + _Pointer __result2 = __buffer; + for ( ; __first != __last ; ++__first) + if (__pred(*__first)) { + *__result1 = *__first; + ++__result1; } else { - *result2 = *first; - ++result2; + *__result2 = *__first; + ++__result2; } - copy(buffer, result2, result1); - return result1; + copy(__buffer, __result2, __result1); + return __result1; } else { - ForwardIterator middle = first; - advance(middle, len / 2); - ForwardIterator first_cut = - __stable_partition_adaptive(first, middle, pred, len / 2, - buffer, buffer_size); - ForwardIterator second_cut = - __stable_partition_adaptive(middle, last, pred, len - len / 2, - buffer, buffer_size); - - rotate(first_cut, middle, second_cut); - len = 0; - distance(middle, second_cut, len); - advance(first_cut, len); - return first_cut; - } -} - -template -inline ForwardIterator __stable_partition_aux(ForwardIterator first, - ForwardIterator last, - Predicate pred, T*, Distance*) { - temporary_buffer buf(first, last); - if (buf.size() > 0) - return __stable_partition_adaptive(first, last, pred, - Distance(buf.requested_size()), - buf.begin(), buf.size()); + _ForwardIter __middle = __first; + advance(__middle, __len / 2); + return rotate(__stable_partition_adaptive( + __first, __middle, __pred, + __len / 2, __buffer, __buffer_size), + __middle, + __stable_partition_adaptive( + __middle, __last, __pred, + __len - __len / 2, __buffer, __buffer_size)); + } +} + +template +inline _ForwardIter +__stable_partition_aux(_ForwardIter __first, _ForwardIter __last, + _Predicate __pred, _Tp*, _Distance*) +{ + _Temporary_buffer<_ForwardIter, _Tp> __buf(__first, __last); + if (__buf.size() > 0) + return __stable_partition_adaptive(__first, __last, __pred, + _Distance(__buf.requested_size()), + __buf.begin(), __buf.size()); else - return __inplace_stable_partition(first, last, pred, - Distance(buf.requested_size())); + return __inplace_stable_partition(__first, __last, __pred, + _Distance(__buf.requested_size())); } -template -inline ForwardIterator stable_partition(ForwardIterator first, - ForwardIterator last, - Predicate pred) { - if (first == last) - return first; +template +inline _ForwardIter stable_partition(_ForwardIter __first, + _ForwardIter __last, + _Predicate __pred) { + if (__first == __last) + return __first; else - return __stable_partition_aux(first, last, pred, - value_type(first), distance_type(first)); + return __stable_partition_aux(__first, __last, __pred, + __VALUE_TYPE(__first), + __DISTANCE_TYPE(__first)); } -template -RandomAccessIterator __unguarded_partition(RandomAccessIterator first, - RandomAccessIterator last, - T pivot) { +template +_RandomAccessIter __unguarded_partition(_RandomAccessIter __first, + _RandomAccessIter __last, + _Tp __pivot) +{ while (true) { - while (*first < pivot) ++first; - --last; - while (pivot < *last) --last; - if (!(first < last)) return first; - iter_swap(first, last); - ++first; + while (*__first < __pivot) + ++__first; + --__last; + while (__pivot < *__last) + --__last; + if (!(__first < __last)) + return __first; + iter_swap(__first, __last); + ++__first; } } -template -RandomAccessIterator __unguarded_partition(RandomAccessIterator first, - RandomAccessIterator last, - T pivot, Compare comp) { - while (1) { - while (comp(*first, pivot)) ++first; - --last; - while (comp(pivot, *last)) --last; - if (!(first < last)) return first; - iter_swap(first, last); - ++first; +template +_RandomAccessIter __unguarded_partition(_RandomAccessIter __first, + _RandomAccessIter __last, + _Tp __pivot, _Compare __comp) +{ + while (true) { + while (__comp(*__first, __pivot)) + ++__first; + --__last; + while (__comp(__pivot, *__last)) + --__last; + if (!(__first < __last)) + return __first; + iter_swap(__first, __last); + ++__first; } } const int __stl_threshold = 16; +// sort() and its auxiliary functions. -template -void __unguarded_linear_insert(RandomAccessIterator last, T value) { - RandomAccessIterator next = last; - --next; - while (value < *next) { - *last = *next; - last = next; - --next; +template +void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val) { + _RandomAccessIter __next = __last; + --__next; + while (__val < *__next) { + *__last = *__next; + __last = __next; + --__next; } - *last = value; + *__last = __val; } -template -void __unguarded_linear_insert(RandomAccessIterator last, T value, - Compare comp) { - RandomAccessIterator next = last; - --next; - while (comp(value , *next)) { - *last = *next; - last = next; - --next; +template +void __unguarded_linear_insert(_RandomAccessIter __last, _Tp __val, + _Compare __comp) { + _RandomAccessIter __next = __last; + --__next; + while (__comp(__val, *__next)) { + *__last = *__next; + __last = __next; + --__next; } - *last = value; + *__last = __val; } -template -inline void __linear_insert(RandomAccessIterator first, - RandomAccessIterator last, T*) { - T value = *last; - if (value < *first) { - copy_backward(first, last, last + 1); - *first = value; +template +inline void __linear_insert(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*) { + _Tp __val = *__last; + if (__val < *__first) { + copy_backward(__first, __last, __last + 1); + *__first = __val; } else - __unguarded_linear_insert(last, value); + __unguarded_linear_insert(__last, __val); } -template -inline void __linear_insert(RandomAccessIterator first, - RandomAccessIterator last, T*, Compare comp) { - T value = *last; - if (comp(value, *first)) { - copy_backward(first, last, last + 1); - *first = value; +template +inline void __linear_insert(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, _Compare __comp) { + _Tp __val = *__last; + if (__comp(__val, *__first)) { + copy_backward(__first, __last, __last + 1); + *__first = __val; } else - __unguarded_linear_insert(last, value, comp); + __unguarded_linear_insert(__last, __val, __comp); } -template -void __insertion_sort(RandomAccessIterator first, RandomAccessIterator last) { - if (first == last) return; - for (RandomAccessIterator i = first + 1; i != last; ++i) - __linear_insert(first, i, value_type(first)); +template +void __insertion_sort(_RandomAccessIter __first, _RandomAccessIter __last) { + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + __linear_insert(__first, __i, __VALUE_TYPE(__first)); } -template -void __insertion_sort(RandomAccessIterator first, - RandomAccessIterator last, Compare comp) { - if (first == last) return; - for (RandomAccessIterator i = first + 1; i != last; ++i) - __linear_insert(first, i, value_type(first), comp); +template +void __insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + if (__first == __last) return; + for (_RandomAccessIter __i = __first + 1; __i != __last; ++__i) + __linear_insert(__first, __i, __VALUE_TYPE(__first), __comp); } -template -void __unguarded_insertion_sort_aux(RandomAccessIterator first, - RandomAccessIterator last, T*) { - for (RandomAccessIterator i = first; i != last; ++i) - __unguarded_linear_insert(i, T(*i)); +template +void __unguarded_insertion_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*) { + for (_RandomAccessIter __i = __first; __i != __last; ++__i) + __unguarded_linear_insert(__i, _Tp(*__i)); } -template -inline void __unguarded_insertion_sort(RandomAccessIterator first, - RandomAccessIterator last) { - __unguarded_insertion_sort_aux(first, last, value_type(first)); +template +inline void __unguarded_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first)); } -template -void __unguarded_insertion_sort_aux(RandomAccessIterator first, - RandomAccessIterator last, - T*, Compare comp) { - for (RandomAccessIterator i = first; i != last; ++i) - __unguarded_linear_insert(i, T(*i), comp); +template +void __unguarded_insertion_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, + _Tp*, _Compare __comp) { + for (_RandomAccessIter __i = __first; __i != __last; ++__i) + __unguarded_linear_insert(__i, _Tp(*__i), __comp); } -template -inline void __unguarded_insertion_sort(RandomAccessIterator first, - RandomAccessIterator last, - Compare comp) { - __unguarded_insertion_sort_aux(first, last, value_type(first), comp); +template +inline void __unguarded_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, + _Compare __comp) { + __unguarded_insertion_sort_aux(__first, __last, __VALUE_TYPE(__first), + __comp); } -template -void __final_insertion_sort(RandomAccessIterator first, - RandomAccessIterator last) { - if (last - first > __stl_threshold) { - __insertion_sort(first, first + __stl_threshold); - __unguarded_insertion_sort(first + __stl_threshold, last); +template +void __final_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + if (__last - __first > __stl_threshold) { + __insertion_sort(__first, __first + __stl_threshold); + __unguarded_insertion_sort(__first + __stl_threshold, __last); } else - __insertion_sort(first, last); + __insertion_sort(__first, __last); } -template -void __final_insertion_sort(RandomAccessIterator first, - RandomAccessIterator last, Compare comp) { - if (last - first > __stl_threshold) { - __insertion_sort(first, first + __stl_threshold, comp); - __unguarded_insertion_sort(first + __stl_threshold, last, comp); +template +void __final_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + if (__last - __first > __stl_threshold) { + __insertion_sort(__first, __first + __stl_threshold, __comp); + __unguarded_insertion_sort(__first + __stl_threshold, __last, __comp); } else - __insertion_sort(first, last, comp); + __insertion_sort(__first, __last, __comp); } -template -inline Size __lg(Size n) { - Size k; - for (k = 0; n > 1; n >>= 1) ++k; - return k; +template +inline _Size __lg(_Size __n) { + _Size __k; + for (__k = 0; __n != 1; __n >>= 1) ++__k; + return __k; } -template -void __introsort_loop(RandomAccessIterator first, - RandomAccessIterator last, T*, - Size depth_limit) { - while (last - first > __stl_threshold) { - if (depth_limit == 0) { - partial_sort(first, last, last); +template +void __introsort_loop(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, + _Size __depth_limit) +{ + while (__last - __first > __stl_threshold) { + if (__depth_limit == 0) { + partial_sort(__first, __last, __last); return; } - --depth_limit; - RandomAccessIterator cut = __unguarded_partition - (first, last, T(__median(*first, *(first + (last - first)/2), - *(last - 1)))); - __introsort_loop(cut, last, value_type(first), depth_limit); - last = cut; + --__depth_limit; + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1)))); + __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit); + __last = __cut; } } -template -void __introsort_loop(RandomAccessIterator first, - RandomAccessIterator last, T*, - Size depth_limit, Compare comp) { - while (last - first > __stl_threshold) { - if (depth_limit == 0) { - partial_sort(first, last, last, comp); +template +void __introsort_loop(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, + _Size __depth_limit, _Compare __comp) +{ + while (__last - __first > __stl_threshold) { + if (__depth_limit == 0) { + partial_sort(__first, __last, __last, __comp); return; } - --depth_limit; - RandomAccessIterator cut = __unguarded_partition - (first, last, T(__median(*first, *(first + (last - first)/2), - *(last - 1), comp)), comp); - __introsort_loop(cut, last, value_type(first), depth_limit, comp); - last = cut; + --__depth_limit; + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1), __comp)), + __comp); + __introsort_loop(__cut, __last, (_Tp*) 0, __depth_limit, __comp); + __last = __cut; } } -template -inline void sort(RandomAccessIterator first, RandomAccessIterator last) { - if (first != last) { - __introsort_loop(first, last, value_type(first), __lg(last - first) * 2); - __final_insertion_sort(first, last); +template +inline void sort(_RandomAccessIter __first, _RandomAccessIter __last) { + if (__first != __last) { + __introsort_loop(__first, __last, + __VALUE_TYPE(__first), + __lg(__last - __first) * 2); + __final_insertion_sort(__first, __last); } } -template -inline void sort(RandomAccessIterator first, RandomAccessIterator last, - Compare comp) { - if (first != last) { - __introsort_loop(first, last, value_type(first), __lg(last - first) * 2, - comp); - __final_insertion_sort(first, last, comp); +template +inline void sort(_RandomAccessIter __first, _RandomAccessIter __last, + _Compare __comp) { + if (__first != __last) { + __introsort_loop(__first, __last, + __VALUE_TYPE(__first), + __lg(__last - __first) * 2, + __comp); + __final_insertion_sort(__first, __last, __comp); } } +// stable_sort() and its auxiliary functions. -template -void __inplace_stable_sort(RandomAccessIterator first, - RandomAccessIterator last) { - if (last - first < 15) { - __insertion_sort(first, last); +template +void __inplace_stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + if (__last - __first < 15) { + __insertion_sort(__first, __last); return; } - RandomAccessIterator middle = first + (last - first) / 2; - __inplace_stable_sort(first, middle); - __inplace_stable_sort(middle, last); - __merge_without_buffer(first, middle, last, middle - first, last - middle); + _RandomAccessIter __middle = __first + (__last - __first) / 2; + __inplace_stable_sort(__first, __middle); + __inplace_stable_sort(__middle, __last); + __merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle); } -template -void __inplace_stable_sort(RandomAccessIterator first, - RandomAccessIterator last, Compare comp) { - if (last - first < 15) { - __insertion_sort(first, last, comp); +template +void __inplace_stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + if (__last - __first < 15) { + __insertion_sort(__first, __last, __comp); return; } - RandomAccessIterator middle = first + (last - first) / 2; - __inplace_stable_sort(first, middle, comp); - __inplace_stable_sort(middle, last, comp); - __merge_without_buffer(first, middle, last, middle - first, - last - middle, comp); + _RandomAccessIter __middle = __first + (__last - __first) / 2; + __inplace_stable_sort(__first, __middle, __comp); + __inplace_stable_sort(__middle, __last, __comp); + __merge_without_buffer(__first, __middle, __last, + __middle - __first, + __last - __middle, + __comp); } -template -void __merge_sort_loop(RandomAccessIterator1 first, - RandomAccessIterator1 last, - RandomAccessIterator2 result, Distance step_size) { - Distance two_step = 2 * step_size; +template +void __merge_sort_loop(_RandomAccessIter1 __first, + _RandomAccessIter1 __last, + _RandomAccessIter2 __result, _Distance __step_size) { + _Distance __two_step = 2 * __step_size; - while (last - first >= two_step) { - result = merge(first, first + step_size, - first + step_size, first + two_step, result); - first += two_step; + while (__last - __first >= __two_step) { + __result = merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result); + __first += __two_step; } - step_size = min(Distance(last - first), step_size); - merge(first, first + step_size, first + step_size, last, result); + __step_size = min(_Distance(__last - __first), __step_size); + merge(__first, __first + __step_size, __first + __step_size, __last, + __result); } -template -void __merge_sort_loop(RandomAccessIterator1 first, - RandomAccessIterator1 last, - RandomAccessIterator2 result, Distance step_size, - Compare comp) { - Distance two_step = 2 * step_size; +template +void __merge_sort_loop(_RandomAccessIter1 __first, + _RandomAccessIter1 __last, + _RandomAccessIter2 __result, _Distance __step_size, + _Compare __comp) { + _Distance __two_step = 2 * __step_size; - while (last - first >= two_step) { - result = merge(first, first + step_size, - first + step_size, first + two_step, result, comp); - first += two_step; + while (__last - __first >= __two_step) { + __result = merge(__first, __first + __step_size, + __first + __step_size, __first + __two_step, + __result, + __comp); + __first += __two_step; } - step_size = min(Distance(last - first), step_size); + __step_size = min(_Distance(__last - __first), __step_size); - merge(first, first + step_size, first + step_size, last, result, comp); + merge(__first, __first + __step_size, + __first + __step_size, __last, + __result, + __comp); } const int __stl_chunk_size = 7; -template -void __chunk_insertion_sort(RandomAccessIterator first, - RandomAccessIterator last, Distance chunk_size) { - while (last - first >= chunk_size) { - __insertion_sort(first, first + chunk_size); - first += chunk_size; - } - __insertion_sort(first, last); -} - -template -void __chunk_insertion_sort(RandomAccessIterator first, - RandomAccessIterator last, - Distance chunk_size, Compare comp) { - while (last - first >= chunk_size) { - __insertion_sort(first, first + chunk_size, comp); - first += chunk_size; - } - __insertion_sort(first, last, comp); -} - -template -void __merge_sort_with_buffer(RandomAccessIterator first, - RandomAccessIterator last, - Pointer buffer, Distance*) { - Distance len = last - first; - Pointer buffer_last = buffer + len; - - Distance step_size = __stl_chunk_size; - __chunk_insertion_sort(first, last, step_size); - - while (step_size < len) { - __merge_sort_loop(first, last, buffer, step_size); - step_size *= 2; - __merge_sort_loop(buffer, buffer_last, first, step_size); - step_size *= 2; - } -} - -template -void __merge_sort_with_buffer(RandomAccessIterator first, - RandomAccessIterator last, Pointer buffer, - Distance*, Compare comp) { - Distance len = last - first; - Pointer buffer_last = buffer + len; - - Distance step_size = __stl_chunk_size; - __chunk_insertion_sort(first, last, step_size, comp); - - while (step_size < len) { - __merge_sort_loop(first, last, buffer, step_size, comp); - step_size *= 2; - __merge_sort_loop(buffer, buffer_last, first, step_size, comp); - step_size *= 2; - } -} - -template -void __stable_sort_adaptive(RandomAccessIterator first, - RandomAccessIterator last, Pointer buffer, - Distance buffer_size) { - Distance len = (last - first + 1) / 2; - RandomAccessIterator middle = first + len; - if (len > buffer_size) { - __stable_sort_adaptive(first, middle, buffer, buffer_size); - __stable_sort_adaptive(middle, last, buffer, buffer_size); - } else { - __merge_sort_with_buffer(first, middle, buffer, (Distance*)0); - __merge_sort_with_buffer(middle, last, buffer, (Distance*)0); - } - __merge_adaptive(first, middle, last, Distance(middle - first), - Distance(last - middle), buffer, buffer_size); -} - -template -void __stable_sort_adaptive(RandomAccessIterator first, - RandomAccessIterator last, Pointer buffer, - Distance buffer_size, Compare comp) { - Distance len = (last - first + 1) / 2; - RandomAccessIterator middle = first + len; - if (len > buffer_size) { - __stable_sort_adaptive(first, middle, buffer, buffer_size, - comp); - __stable_sort_adaptive(middle, last, buffer, buffer_size, - comp); - } else { - __merge_sort_with_buffer(first, middle, buffer, (Distance*)0, comp); - __merge_sort_with_buffer(middle, last, buffer, (Distance*)0, comp); - } - __merge_adaptive(first, middle, last, Distance(middle - first), - Distance(last - middle), buffer, buffer_size, - comp); -} - -template -inline void __stable_sort_aux(RandomAccessIterator first, - RandomAccessIterator last, T*, Distance*) { - temporary_buffer buf(first, last); - if (buf.begin() == 0) - __inplace_stable_sort(first, last); - else - __stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size())); +template +void __chunk_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Distance __chunk_size) +{ + while (__last - __first >= __chunk_size) { + __insertion_sort(__first, __first + __chunk_size); + __first += __chunk_size; + } + __insertion_sort(__first, __last); } -template -inline void __stable_sort_aux(RandomAccessIterator first, - RandomAccessIterator last, T*, Distance*, - Compare comp) { - temporary_buffer buf(first, last); - if (buf.begin() == 0) - __inplace_stable_sort(first, last, comp); - else - __stable_sort_adaptive(first, last, buf.begin(), Distance(buf.size()), - comp); -} - -template -inline void stable_sort(RandomAccessIterator first, - RandomAccessIterator last) { - __stable_sort_aux(first, last, value_type(first), distance_type(first)); -} - -template -inline void stable_sort(RandomAccessIterator first, - RandomAccessIterator last, Compare comp) { - __stable_sort_aux(first, last, value_type(first), distance_type(first), - comp); -} - -template -void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle, - RandomAccessIterator last, T*) { - make_heap(first, middle); - for (RandomAccessIterator i = middle; i < last; ++i) - if (*i < *first) - __pop_heap(first, middle, i, T(*i), distance_type(first)); - sort_heap(first, middle); -} - -template -inline void partial_sort(RandomAccessIterator first, - RandomAccessIterator middle, - RandomAccessIterator last) { - __partial_sort(first, middle, last, value_type(first)); -} - -template -void __partial_sort(RandomAccessIterator first, RandomAccessIterator middle, - RandomAccessIterator last, T*, Compare comp) { - make_heap(first, middle, comp); - for (RandomAccessIterator i = middle; i < last; ++i) - if (comp(*i, *first)) - __pop_heap(first, middle, i, T(*i), comp, distance_type(first)); - sort_heap(first, middle, comp); -} - -template -inline void partial_sort(RandomAccessIterator first, - RandomAccessIterator middle, - RandomAccessIterator last, Compare comp) { - __partial_sort(first, middle, last, value_type(first), comp); -} - -template -RandomAccessIterator __partial_sort_copy(InputIterator first, - InputIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last, - Distance*, T*) { - if (result_first == result_last) return result_last; - RandomAccessIterator result_real_last = result_first; - while(first != last && result_real_last != result_last) { - *result_real_last = *first; - ++result_real_last; - ++first; - } - make_heap(result_first, result_real_last); - while (first != last) { - if (*first < *result_first) - __adjust_heap(result_first, Distance(0), - Distance(result_real_last - result_first), T(*first)); - ++first; - } - sort_heap(result_first, result_real_last); - return result_real_last; -} - -template -inline RandomAccessIterator -partial_sort_copy(InputIterator first, InputIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last) { - return __partial_sort_copy(first, last, result_first, result_last, - distance_type(result_first), value_type(first)); -} - -template -RandomAccessIterator __partial_sort_copy(InputIterator first, - InputIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last, - Compare comp, Distance*, T*) { - if (result_first == result_last) return result_last; - RandomAccessIterator result_real_last = result_first; - while(first != last && result_real_last != result_last) { - *result_real_last = *first; - ++result_real_last; - ++first; - } - make_heap(result_first, result_real_last, comp); - while (first != last) { - if (comp(*first, *result_first)) - __adjust_heap(result_first, Distance(0), - Distance(result_real_last - result_first), T(*first), - comp); - ++first; - } - sort_heap(result_first, result_real_last, comp); - return result_real_last; -} - -template -inline RandomAccessIterator -partial_sort_copy(InputIterator first, InputIterator last, - RandomAccessIterator result_first, - RandomAccessIterator result_last, Compare comp) { - return __partial_sort_copy(first, last, result_first, result_last, comp, - distance_type(result_first), value_type(first)); -} - -template -void __nth_element(RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last, T*) { - while (last - first > 3) { - RandomAccessIterator cut = __unguarded_partition - (first, last, T(__median(*first, *(first + (last - first)/2), - *(last - 1)))); - if (cut <= nth) - first = cut; - else - last = cut; +template +void __chunk_insertion_sort(_RandomAccessIter __first, + _RandomAccessIter __last, + _Distance __chunk_size, _Compare __comp) +{ + while (__last - __first >= __chunk_size) { + __insertion_sort(__first, __first + __chunk_size, __comp); + __first += __chunk_size; } - __insertion_sort(first, last); + __insertion_sort(__first, __last, __comp); } -template -inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last) { - __nth_element(first, nth, last, value_type(first)); -} +template +void __merge_sort_with_buffer(_RandomAccessIter __first, + _RandomAccessIter __last, + _Pointer __buffer, _Distance*) { + _Distance __len = __last - __first; + _Pointer __buffer_last = __buffer + __len; -template -void __nth_element(RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last, T*, Compare comp) { - while (last - first > 3) { - RandomAccessIterator cut = __unguarded_partition - (first, last, T(__median(*first, *(first + (last - first)/2), - *(last - 1), comp)), comp); - if (cut <= nth) - first = cut; - else - last = cut; + _Distance __step_size = __stl_chunk_size; + __chunk_insertion_sort(__first, __last, __step_size); + + while (__step_size < __len) { + __merge_sort_loop(__first, __last, __buffer, __step_size); + __step_size *= 2; + __merge_sort_loop(__buffer, __buffer_last, __first, __step_size); + __step_size *= 2; } - __insertion_sort(first, last, comp); } -template -inline void nth_element(RandomAccessIterator first, RandomAccessIterator nth, - RandomAccessIterator last, Compare comp) { - __nth_element(first, nth, last, value_type(first), comp); -} +template +void __merge_sort_with_buffer(_RandomAccessIter __first, + _RandomAccessIter __last, _Pointer __buffer, + _Distance*, _Compare __comp) { + _Distance __len = __last - __first; + _Pointer __buffer_last = __buffer + __len; -template -ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last, - const T& value, Distance*, - forward_iterator_tag) { - Distance len = 0; - distance(first, last, len); - Distance half; - ForwardIterator middle; + _Distance __step_size = __stl_chunk_size; + __chunk_insertion_sort(__first, __last, __step_size, __comp); - while (len > 0) { - half = len >> 1; - middle = first; - advance(middle, half); - if (*middle < value) { - first = middle; - ++first; - len = len - half - 1; - } - else - len = half; + while (__step_size < __len) { + __merge_sort_loop(__first, __last, __buffer, __step_size, __comp); + __step_size *= 2; + __merge_sort_loop(__buffer, __buffer_last, __first, __step_size, __comp); + __step_size *= 2; } - return first; } -template -RandomAccessIterator __lower_bound(RandomAccessIterator first, - RandomAccessIterator last, const T& value, - Distance*, random_access_iterator_tag) { - Distance len = last - first; - Distance half; - RandomAccessIterator middle; - - while (len > 0) { - half = len >> 1; - middle = first + half; - if (*middle < value) { - first = middle + 1; - len = len - half - 1; - } - else - len = half; +template +void __stable_sort_adaptive(_RandomAccessIter __first, + _RandomAccessIter __last, _Pointer __buffer, + _Distance __buffer_size) { + _Distance __len = (__last - __first + 1) / 2; + _RandomAccessIter __middle = __first + __len; + if (__len > __buffer_size) { + __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size); + __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size); + } + else { + __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0); + __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0); + } + __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), + _Distance(__last - __middle), __buffer, __buffer_size); +} + +template +void __stable_sort_adaptive(_RandomAccessIter __first, + _RandomAccessIter __last, _Pointer __buffer, + _Distance __buffer_size, _Compare __comp) { + _Distance __len = (__last - __first + 1) / 2; + _RandomAccessIter __middle = __first + __len; + if (__len > __buffer_size) { + __stable_sort_adaptive(__first, __middle, __buffer, __buffer_size, + __comp); + __stable_sort_adaptive(__middle, __last, __buffer, __buffer_size, + __comp); } - return first; + else { + __merge_sort_with_buffer(__first, __middle, __buffer, (_Distance*)0, + __comp); + __merge_sort_with_buffer(__middle, __last, __buffer, (_Distance*)0, + __comp); + } + __merge_adaptive(__first, __middle, __last, _Distance(__middle - __first), + _Distance(__last - __middle), __buffer, __buffer_size, + __comp); } -template -inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, - const T& value) { - return __lower_bound(first, last, value, distance_type(first), - iterator_category(first)); +template +inline void __stable_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, _Distance*) { + _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last); + if (buf.begin() == 0) + __inplace_stable_sort(__first, __last); + else + __stable_sort_adaptive(__first, __last, buf.begin(), + _Distance(buf.size())); } -template -ForwardIterator __lower_bound(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp, Distance*, - forward_iterator_tag) { - Distance len = 0; - distance(first, last, len); - Distance half; - ForwardIterator middle; - - while (len > 0) { - half = len >> 1; - middle = first; - advance(middle, half); - if (comp(*middle, value)) { - first = middle; - ++first; - len = len - half - 1; - } - else - len = half; +template +inline void __stable_sort_aux(_RandomAccessIter __first, + _RandomAccessIter __last, _Tp*, _Distance*, + _Compare __comp) { + _Temporary_buffer<_RandomAccessIter, _Tp> buf(__first, __last); + if (buf.begin() == 0) + __inplace_stable_sort(__first, __last, __comp); + else + __stable_sort_adaptive(__first, __last, buf.begin(), + _Distance(buf.size()), + __comp); +} + +template +inline void stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last) { + __stable_sort_aux(__first, __last, + __VALUE_TYPE(__first), + __DISTANCE_TYPE(__first)); +} + +template +inline void stable_sort(_RandomAccessIter __first, + _RandomAccessIter __last, _Compare __comp) { + __stable_sort_aux(__first, __last, + __VALUE_TYPE(__first), + __DISTANCE_TYPE(__first), + __comp); +} + +// partial_sort, partial_sort_copy, and auxiliary functions. + +template +void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, + _RandomAccessIter __last, _Tp*) { + make_heap(__first, __middle); + for (_RandomAccessIter __i = __middle; __i < __last; ++__i) + if (*__i < *__first) + __pop_heap(__first, __middle, __i, _Tp(*__i), + __DISTANCE_TYPE(__first)); + sort_heap(__first, __middle); +} + +template +inline void partial_sort(_RandomAccessIter __first, + _RandomAccessIter __middle, + _RandomAccessIter __last) { + __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first)); +} + +template +void __partial_sort(_RandomAccessIter __first, _RandomAccessIter __middle, + _RandomAccessIter __last, _Tp*, _Compare __comp) { + make_heap(__first, __middle, __comp); + for (_RandomAccessIter __i = __middle; __i < __last; ++__i) + if (__comp(*__i, *__first)) + __pop_heap(__first, __middle, __i, _Tp(*__i), __comp, + __DISTANCE_TYPE(__first)); + sort_heap(__first, __middle, __comp); +} + +template +inline void partial_sort(_RandomAccessIter __first, + _RandomAccessIter __middle, + _RandomAccessIter __last, _Compare __comp) { + __partial_sort(__first, __middle, __last, __VALUE_TYPE(__first), __comp); +} + +template +_RandomAccessIter __partial_sort_copy(_InputIter __first, + _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last, + _Distance*, _Tp*) { + if (__result_first == __result_last) return __result_last; + _RandomAccessIter __result_real_last = __result_first; + while(__first != __last && __result_real_last != __result_last) { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + make_heap(__result_first, __result_real_last); + while (__first != __last) { + if (*__first < *__result_first) + __adjust_heap(__result_first, _Distance(0), + _Distance(__result_real_last - __result_first), + _Tp(*__first)); + ++__first; + } + sort_heap(__result_first, __result_real_last); + return __result_real_last; +} + +template +inline _RandomAccessIter +partial_sort_copy(_InputIter __first, _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last) { + return __partial_sort_copy(__first, __last, __result_first, __result_last, + __DISTANCE_TYPE(__result_first), + __VALUE_TYPE(__first)); +} + +template +_RandomAccessIter __partial_sort_copy(_InputIter __first, + _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last, + _Compare __comp, _Distance*, _Tp*) { + if (__result_first == __result_last) return __result_last; + _RandomAccessIter __result_real_last = __result_first; + while(__first != __last && __result_real_last != __result_last) { + *__result_real_last = *__first; + ++__result_real_last; + ++__first; + } + make_heap(__result_first, __result_real_last, __comp); + while (__first != __last) { + if (__comp(*__first, *__result_first)) + __adjust_heap(__result_first, _Distance(0), + _Distance(__result_real_last - __result_first), + _Tp(*__first), + __comp); + ++__first; + } + sort_heap(__result_first, __result_real_last, __comp); + return __result_real_last; +} + +template +inline _RandomAccessIter +partial_sort_copy(_InputIter __first, _InputIter __last, + _RandomAccessIter __result_first, + _RandomAccessIter __result_last, _Compare __comp) { + return __partial_sort_copy(__first, __last, __result_first, __result_last, + __comp, + __DISTANCE_TYPE(__result_first), + __VALUE_TYPE(__first)); +} + +// nth_element() and its auxiliary functions. + +template +void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last, _Tp*) { + while (__last - __first > 3) { + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1)))); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; + } + __insertion_sort(__first, __last); +} + +template +inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last) { + __nth_element(__first, __nth, __last, __VALUE_TYPE(__first)); +} + +template +void __nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last, _Tp*, _Compare __comp) { + while (__last - __first > 3) { + _RandomAccessIter __cut = + __unguarded_partition(__first, __last, + _Tp(__median(*__first, + *(__first + (__last - __first)/2), + *(__last - 1), + __comp)), + __comp); + if (__cut <= __nth) + __first = __cut; + else + __last = __cut; } - return first; + __insertion_sort(__first, __last, __comp); } -template -RandomAccessIterator __lower_bound(RandomAccessIterator first, - RandomAccessIterator last, - const T& value, Compare comp, Distance*, - random_access_iterator_tag) { - Distance len = last - first; - Distance half; - RandomAccessIterator middle; - - while (len > 0) { - half = len >> 1; - middle = first + half; - if (comp(*middle, value)) { - first = middle + 1; - len = len - half - 1; - } - else - len = half; - } - return first; +template +inline void nth_element(_RandomAccessIter __first, _RandomAccessIter __nth, + _RandomAccessIter __last, _Compare __comp) { + __nth_element(__first, __nth, __last, __VALUE_TYPE(__first), __comp); } -template -inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp) { - return __lower_bound(first, last, value, comp, distance_type(first), - iterator_category(first)); -} -template -ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last, - const T& value, Distance*, - forward_iterator_tag) { - Distance len = 0; - distance(first, last, len); - Distance half; - ForwardIterator middle; +// Binary search (lower_bound, upper_bound, equal_range, binary_search). - while (len > 0) { - half = len >> 1; - middle = first; - advance(middle, half); - if (value < *middle) - len = half; - else { - first = middle; - ++first; - len = len - half - 1; +template +_ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (*__middle < __val) { + __first = __middle; + ++__first; + __len = __len - __half - 1; } + else + __len = __half; } - return first; + return __first; } -template -RandomAccessIterator __upper_bound(RandomAccessIterator first, - RandomAccessIterator last, const T& value, - Distance*, random_access_iterator_tag) { - Distance len = last - first; - Distance half; - RandomAccessIterator middle; +template +inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val) { + return __lower_bound(__first, __last, __val, + __DISTANCE_TYPE(__first)); +} - while (len > 0) { - half = len >> 1; - middle = first + half; - if (value < *middle) - len = half; - else { - first = middle + 1; - len = len - half - 1; +template +_ForwardIter __lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__comp(*__middle, __val)) { + __first = __middle; + ++__first; + __len = __len - __half - 1; } + else + __len = __half; } - return first; + return __first; } -template -inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, - const T& value) { - return __upper_bound(first, last, value, distance_type(first), - iterator_category(first)); +template +inline _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp) { + return __lower_bound(__first, __last, __val, __comp, + __DISTANCE_TYPE(__first)); } -template -ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp, Distance*, - forward_iterator_tag) { - Distance len = 0; - distance(first, last, len); - Distance half; - ForwardIterator middle; - - while (len > 0) { - half = len >> 1; - middle = first; - advance(middle, half); - if (comp(value, *middle)) - len = half; +template +_ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__val < *__middle) + __len = __half; else { - first = middle; - ++first; - len = len - half - 1; + __first = __middle; + ++__first; + __len = __len - __half - 1; } } - return first; + return __first; } -template -RandomAccessIterator __upper_bound(RandomAccessIterator first, - RandomAccessIterator last, - const T& value, Compare comp, Distance*, - random_access_iterator_tag) { - Distance len = last - first; - Distance half; - RandomAccessIterator middle; +template +inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val) { + return __upper_bound(__first, __last, __val, + __DISTANCE_TYPE(__first)); +} - while (len > 0) { - half = len >> 1; - middle = first + half; - if (comp(value, *middle)) - len = half; +template +_ForwardIter __upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__comp(__val, *__middle)) + __len = __half; else { - first = middle + 1; - len = len - half - 1; + __first = __middle; + ++__first; + __len = __len - __half - 1; } } - return first; + return __first; } -template -inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, - const T& value, Compare comp) { - return __upper_bound(first, last, value, comp, distance_type(first), - iterator_category(first)); +template +inline _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, _Compare __comp) { + return __upper_bound(__first, __last, __val, __comp, + __DISTANCE_TYPE(__first)); } -template -pair -__equal_range(ForwardIterator first, ForwardIterator last, const T& value, - Distance*, forward_iterator_tag) { - Distance len = 0; - distance(first, last, len); - Distance half; - ForwardIterator middle, left, right; - - while (len > 0) { - half = len >> 1; - middle = first; - advance(middle, half); - if (*middle < value) { - first = middle; - ++first; - len = len - half - 1; - } - else if (value < *middle) - len = half; +template +pair<_ForwardIter, _ForwardIter> +__equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, + _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle, __left, __right; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (*__middle < __val) { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__val < *__middle) + __len = __half; else { - left = lower_bound(first, middle, value); - advance(first, len); - right = upper_bound(++middle, first, value); - return pair(left, right); + __left = lower_bound(__first, __middle, __val); + advance(__first, __len); + __right = upper_bound(++__middle, __first, __val); + return pair<_ForwardIter, _ForwardIter>(__left, __right); } } - return pair(first, first); + return pair<_ForwardIter, _ForwardIter>(__first, __first); } -template -pair -__equal_range(RandomAccessIterator first, RandomAccessIterator last, - const T& value, Distance*, random_access_iterator_tag) { - Distance len = last - first; - Distance half; - RandomAccessIterator middle, left, right; - - while (len > 0) { - half = len >> 1; - middle = first + half; - if (*middle < value) { - first = middle + 1; - len = len - half - 1; - } - else if (value < *middle) - len = half; - else { - left = lower_bound(first, middle, value); - right = upper_bound(++middle, first + len, value); - return pair(left, - right); - } - } - return pair(first, first); -} - -template -inline pair -equal_range(ForwardIterator first, ForwardIterator last, const T& value) { - return __equal_range(first, last, value, distance_type(first), - iterator_category(first)); -} - -template -pair -__equal_range(ForwardIterator first, ForwardIterator last, const T& value, - Compare comp, Distance*, forward_iterator_tag) { - Distance len = 0; - distance(first, last, len); - Distance half; - ForwardIterator middle, left, right; - - while (len > 0) { - half = len >> 1; - middle = first; - advance(middle, half); - if (comp(*middle, value)) { - first = middle; - ++first; - len = len - half - 1; - } - else if (comp(value, *middle)) - len = half; - else { - left = lower_bound(first, middle, value, comp); - advance(first, len); - right = upper_bound(++middle, first, value, comp); - return pair(left, right); - } - } - return pair(first, first); -} +template +inline pair<_ForwardIter, _ForwardIter> +equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) { + return __equal_range(__first, __last, __val, + __DISTANCE_TYPE(__first)); +} -template -pair -__equal_range(RandomAccessIterator first, RandomAccessIterator last, - const T& value, Compare comp, Distance*, - random_access_iterator_tag) { - Distance len = last - first; - Distance half; - RandomAccessIterator middle, left, right; - - while (len > 0) { - half = len >> 1; - middle = first + half; - if (comp(*middle, value)) { - first = middle + 1; - len = len - half - 1; - } - else if (comp(value, *middle)) - len = half; +template +pair<_ForwardIter, _ForwardIter> +__equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, + _Compare __comp, _Distance*) +{ + _Distance __len = 0; + distance(__first, __last, __len); + _Distance __half; + _ForwardIter __middle, __left, __right; + + while (__len > 0) { + __half = __len >> 1; + __middle = __first; + advance(__middle, __half); + if (__comp(*__middle, __val)) { + __first = __middle; + ++__first; + __len = __len - __half - 1; + } + else if (__comp(__val, *__middle)) + __len = __half; else { - left = lower_bound(first, middle, value, comp); - right = upper_bound(++middle, first + len, value, comp); - return pair(left, - right); + __left = lower_bound(__first, __middle, __val, __comp); + advance(__first, __len); + __right = upper_bound(++__middle, __first, __val, __comp); + return pair<_ForwardIter, _ForwardIter>(__left, __right); } } - return pair(first, first); + return pair<_ForwardIter, _ForwardIter>(__first, __first); } -template -inline pair -equal_range(ForwardIterator first, ForwardIterator last, const T& value, - Compare comp) { - return __equal_range(first, last, value, comp, distance_type(first), - iterator_category(first)); -} +template +inline pair<_ForwardIter, _ForwardIter> +equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, + _Compare __comp) { + return __equal_range(__first, __last, __val, __comp, + __DISTANCE_TYPE(__first)); +} -template -bool binary_search(ForwardIterator first, ForwardIterator last, - const T& value) { - ForwardIterator i = lower_bound(first, last, value); - return i != last && !(value < *i); +template +bool binary_search(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val) { + _ForwardIter __i = lower_bound(__first, __last, __val); + return __i != __last && !(__val < *__i); } -template -bool binary_search(ForwardIterator first, ForwardIterator last, const T& value, - Compare comp) { - ForwardIterator i = lower_bound(first, last, value, comp); - return i != last && !comp(value, *i); +template +bool binary_search(_ForwardIter __first, _ForwardIter __last, + const _Tp& __val, + _Compare __comp) { + _ForwardIter __i = lower_bound(__first, __last, __val, __comp); + return __i != __last && !__comp(__val, *__i); } -template -OutputIterator merge(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result) { - while (first1 != last1 && first2 != last2) { - if (*first2 < *first1) { - *result = *first2; - ++first2; +// merge, with and without an explicitly supplied comparison function. + +template +_OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + while (__first1 != __last1 && __first2 != __last2) { + if (*__first2 < *__first1) { + *__result = *__first2; + ++__first2; } else { - *result = *first1; - ++first1; + *__result = *__first1; + ++__first1; } - ++result; + ++__result; } - return copy(first2, last2, copy(first1, last1, result)); + return copy(__first2, __last2, copy(__first1, __last1, __result)); } -template -OutputIterator merge(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp) { - while (first1 != last1 && first2 != last2) { - if (comp(*first2, *first1)) { - *result = *first2; - ++first2; +template +_OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) { + if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; } else { - *result = *first1; - ++first1; + *__result = *__first1; + ++__first1; } - ++result; + ++__result; } - return copy(first2, last2, copy(first1, last1, result)); + return copy(__first2, __last2, copy(__first1, __last1, __result)); } -template -void __merge_without_buffer(BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last, - Distance len1, Distance len2) { - if (len1 == 0 || len2 == 0) return; - if (len1 + len2 == 2) { - if (*middle < *first) iter_swap(first, middle); +// inplace_merge and its auxiliary functions. + +template +void __merge_without_buffer(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2) { + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) { + if (*__middle < *__first) + iter_swap(__first, __middle); return; } - BidirectionalIterator first_cut = first; - BidirectionalIterator second_cut = middle; - Distance len11 = 0; - Distance len22 = 0; - if (len1 > len2) { - len11 = len1 / 2; - advance(first_cut, len11); - second_cut = lower_bound(middle, last, *first_cut); - distance(middle, second_cut, len22); + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut); + distance(__middle, __second_cut, __len22); } else { - len22 = len2 / 2; - advance(second_cut, len22); - first_cut = upper_bound(first, middle, *second_cut); - distance(first, first_cut, len11); - } - rotate(first_cut, middle, second_cut); - BidirectionalIterator new_middle = first_cut; - advance(new_middle, len22); - __merge_without_buffer(first, first_cut, new_middle, len11, len22); - __merge_without_buffer(new_middle, second_cut, last, len1 - len11, - len2 - len22); -} - -template -void __merge_without_buffer(BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last, - Distance len1, Distance len2, Compare comp) { - if (len1 == 0 || len2 == 0) return; - if (len1 + len2 == 2) { - if (comp(*middle, *first)) iter_swap(first, middle); + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle + = rotate(__first_cut, __middle, __second_cut); + __merge_without_buffer(__first, __first_cut, __new_middle, + __len11, __len22); + __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22); +} + +template +void __merge_without_buffer(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2, + _Compare __comp) { + if (__len1 == 0 || __len2 == 0) + return; + if (__len1 + __len2 == 2) { + if (__comp(*__middle, *__first)) + iter_swap(__first, __middle); return; } - BidirectionalIterator first_cut = first; - BidirectionalIterator second_cut = middle; - Distance len11 = 0; - Distance len22 = 0; - if (len1 > len2) { - len11 = len1 / 2; - advance(first_cut, len11); - second_cut = lower_bound(middle, last, *first_cut, comp); - distance(middle, second_cut, len22); + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); + distance(__middle, __second_cut, __len22); } else { - len22 = len2 / 2; - advance(second_cut, len22); - first_cut = upper_bound(first, middle, *second_cut, comp); - distance(first, first_cut, len11); - } - rotate(first_cut, middle, second_cut); - BidirectionalIterator new_middle = first_cut; - advance(new_middle, len22); - __merge_without_buffer(first, first_cut, new_middle, len11, len22, comp); - __merge_without_buffer(new_middle, second_cut, last, len1 - len11, - len2 - len22, comp); -} - -template -BidirectionalIterator1 __rotate_adaptive(BidirectionalIterator1 first, - BidirectionalIterator1 middle, - BidirectionalIterator1 last, - Distance len1, Distance len2, - BidirectionalIterator2 buffer, - Distance buffer_size) { - BidirectionalIterator2 buffer_end; - if (len1 > len2 && len2 <= buffer_size) { - buffer_end = copy(middle, last, buffer); - copy_backward(first, middle, last); - return copy(buffer, buffer_end, first); - } else if (len1 <= buffer_size) { - buffer_end = copy(first, middle, buffer); - copy(middle, last, first); - return copy_backward(buffer, buffer_end, last); - } else { - rotate(first, middle, last); - advance(first, len2); - return first; - } -} - -template -BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1, - BidirectionalIterator1 last1, - BidirectionalIterator2 first2, - BidirectionalIterator2 last2, - BidirectionalIterator3 result) { - if (first1 == last1) return copy_backward(first2, last2, result); - if (first2 == last2) return copy_backward(first1, last1, result); - --last1; - --last2; + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle + = rotate(__first_cut, __middle, __second_cut); + __merge_without_buffer(__first, __first_cut, __new_middle, __len11, __len22, + __comp); + __merge_without_buffer(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22, __comp); +} + +template +_BidirectionalIter1 __rotate_adaptive(_BidirectionalIter1 __first, + _BidirectionalIter1 __middle, + _BidirectionalIter1 __last, + _Distance __len1, _Distance __len2, + _BidirectionalIter2 __buffer, + _Distance __buffer_size) { + _BidirectionalIter2 __buffer_end; + if (__len1 > __len2 && __len2 <= __buffer_size) { + __buffer_end = copy(__middle, __last, __buffer); + copy_backward(__first, __middle, __last); + return copy(__buffer, __buffer_end, __first); + } + else if (__len1 <= __buffer_size) { + __buffer_end = copy(__first, __middle, __buffer); + copy(__middle, __last, __first); + return copy_backward(__buffer, __buffer_end, __last); + } + else + return rotate(__first, __middle, __last); +} + +template +_BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, + _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, + _BidirectionalIter2 __last2, + _BidirectionalIter3 __result) { + if (__first1 == __last1) + return copy_backward(__first2, __last2, __result); + if (__first2 == __last2) + return copy_backward(__first1, __last1, __result); + --__last1; + --__last2; while (true) { - if (*last2 < *last1) { - *--result = *last1; - if (first1 == last1) return copy_backward(first2, ++last2, result); - --last1; + if (*__last2 < *__last1) { + *--__result = *__last1; + if (__first1 == __last1) + return copy_backward(__first2, ++__last2, __result); + --__last1; } else { - *--result = *last2; - if (first2 == last2) return copy_backward(first1, ++last1, result); - --last2; - } - } -} - -template -BidirectionalIterator3 __merge_backward(BidirectionalIterator1 first1, - BidirectionalIterator1 last1, - BidirectionalIterator2 first2, - BidirectionalIterator2 last2, - BidirectionalIterator3 result, - Compare comp) { - if (first1 == last1) return copy_backward(first2, last2, result); - if (first2 == last2) return copy_backward(first1, last1, result); - --last1; - --last2; + *--__result = *__last2; + if (__first2 == __last2) + return copy_backward(__first1, ++__last1, __result); + --__last2; + } + } +} + +template +_BidirectionalIter3 __merge_backward(_BidirectionalIter1 __first1, + _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, + _BidirectionalIter2 __last2, + _BidirectionalIter3 __result, + _Compare __comp) { + if (__first1 == __last1) + return copy_backward(__first2, __last2, __result); + if (__first2 == __last2) + return copy_backward(__first1, __last1, __result); + --__last1; + --__last2; while (true) { - if (comp(*last2, *last1)) { - *--result = *last1; - if (first1 == last1) return copy_backward(first2, ++last2, result); - --last1; + if (__comp(*__last2, *__last1)) { + *--__result = *__last1; + if (__first1 == __last1) + return copy_backward(__first2, ++__last2, __result); + --__last1; } else { - *--result = *last2; - if (first2 == last2) return copy_backward(first1, ++last1, result); - --last2; + *--__result = *__last2; + if (__first2 == __last2) + return copy_backward(__first1, ++__last1, __result); + --__last2; } } } -template -void __merge_adaptive(BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last, Distance len1, Distance len2, - Pointer buffer, Distance buffer_size) { - if (len1 <= len2 && len1 <= buffer_size) { - Pointer end_buffer = copy(first, middle, buffer); - merge(buffer, end_buffer, middle, last, first); +template +void __merge_adaptive(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size) { + if (__len1 <= __len2 && __len1 <= __buffer_size) { + _Pointer __buffer_end = copy(__first, __middle, __buffer); + merge(__buffer, __buffer_end, __middle, __last, __first); } - else if (len2 <= buffer_size) { - Pointer end_buffer = copy(middle, last, buffer); - __merge_backward(first, middle, buffer, end_buffer, last); + else if (__len2 <= __buffer_size) { + _Pointer __buffer_end = copy(__middle, __last, __buffer); + __merge_backward(__first, __middle, __buffer, __buffer_end, __last); } else { - BidirectionalIterator first_cut = first; - BidirectionalIterator second_cut = middle; - Distance len11 = 0; - Distance len22 = 0; - if (len1 > len2) { - len11 = len1 / 2; - advance(first_cut, len11); - second_cut = lower_bound(middle, last, *first_cut); - distance(middle, second_cut, len22); + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut); + distance(__middle, __second_cut, __len22); } else { - len22 = len2 / 2; - advance(second_cut, len22); - first_cut = upper_bound(first, middle, *second_cut); - distance(first, first_cut, len11); - } - BidirectionalIterator new_middle = - __rotate_adaptive(first_cut, middle, second_cut, len1 - len11, - len22, buffer, buffer_size); - __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer, - buffer_size); - __merge_adaptive(new_middle, second_cut, last, len1 - len11, - len2 - len22, buffer, buffer_size); - } -} - -template -void __merge_adaptive(BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last, Distance len1, Distance len2, - Pointer buffer, Distance buffer_size, Compare comp) { - if (len1 <= len2 && len1 <= buffer_size) { - Pointer end_buffer = copy(first, middle, buffer); - merge(buffer, end_buffer, middle, last, first, comp); - } - else if (len2 <= buffer_size) { - Pointer end_buffer = copy(middle, last, buffer); - __merge_backward(first, middle, buffer, end_buffer, last, comp); + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle = + __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, + __len22, __buffer, __buffer_size); + __merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size); + __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22, __buffer, __buffer_size); + } +} + +template +void __merge_adaptive(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, + _Distance __len1, _Distance __len2, + _Pointer __buffer, _Distance __buffer_size, + _Compare __comp) { + if (__len1 <= __len2 && __len1 <= __buffer_size) { + _Pointer __buffer_end = copy(__first, __middle, __buffer); + merge(__buffer, __buffer_end, __middle, __last, __first, __comp); + } + else if (__len2 <= __buffer_size) { + _Pointer __buffer_end = copy(__middle, __last, __buffer); + __merge_backward(__first, __middle, __buffer, __buffer_end, __last, + __comp); } else { - BidirectionalIterator first_cut = first; - BidirectionalIterator second_cut = middle; - Distance len11 = 0; - Distance len22 = 0; - if (len1 > len2) { - len11 = len1 / 2; - advance(first_cut, len11); - second_cut = lower_bound(middle, last, *first_cut, comp); - distance(middle, second_cut, len22); + _BidirectionalIter __first_cut = __first; + _BidirectionalIter __second_cut = __middle; + _Distance __len11 = 0; + _Distance __len22 = 0; + if (__len1 > __len2) { + __len11 = __len1 / 2; + advance(__first_cut, __len11); + __second_cut = lower_bound(__middle, __last, *__first_cut, __comp); + distance(__middle, __second_cut, __len22); } else { - len22 = len2 / 2; - advance(second_cut, len22); - first_cut = upper_bound(first, middle, *second_cut, comp); - distance(first, first_cut, len11); - } - BidirectionalIterator new_middle = - __rotate_adaptive(first_cut, middle, second_cut, len1 - len11, - len22, buffer, buffer_size); - __merge_adaptive(first, first_cut, new_middle, len11, len22, buffer, - buffer_size, comp); - __merge_adaptive(new_middle, second_cut, last, len1 - len11, - len2 - len22, buffer, buffer_size, comp); - } -} - -template -inline void __inplace_merge_aux(BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last, T*, Distance*) { - Distance len1 = 0; - distance(first, middle, len1); - Distance len2 = 0; - distance(middle, last, len2); - - temporary_buffer buf(first, last); - if (buf.begin() == 0) - __merge_without_buffer(first, middle, last, len1, len2); + __len22 = __len2 / 2; + advance(__second_cut, __len22); + __first_cut = upper_bound(__first, __middle, *__second_cut, __comp); + distance(__first, __first_cut, __len11); + } + _BidirectionalIter __new_middle = + __rotate_adaptive(__first_cut, __middle, __second_cut, __len1 - __len11, + __len22, __buffer, __buffer_size); + __merge_adaptive(__first, __first_cut, __new_middle, __len11, + __len22, __buffer, __buffer_size, __comp); + __merge_adaptive(__new_middle, __second_cut, __last, __len1 - __len11, + __len2 - __len22, __buffer, __buffer_size, __comp); + } +} + +template +inline void __inplace_merge_aux(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, _Tp*, _Distance*) { + _Distance __len1 = 0; + distance(__first, __middle, __len1); + _Distance __len2 = 0; + distance(__middle, __last, __len2); + + _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last); + if (__buf.begin() == 0) + __merge_without_buffer(__first, __middle, __last, __len1, __len2); else - __merge_adaptive(first, middle, last, len1, len2, - buf.begin(), Distance(buf.size())); + __merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _Distance(__buf.size())); +} + +template +inline void __inplace_merge_aux(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, _Tp*, _Distance*, + _Compare __comp) { + _Distance __len1 = 0; + distance(__first, __middle, __len1); + _Distance __len2 = 0; + distance(__middle, __last, __len2); + + _Temporary_buffer<_BidirectionalIter, _Tp> __buf(__first, __last); + if (__buf.begin() == 0) + __merge_without_buffer(__first, __middle, __last, __len1, __len2, __comp); + else + __merge_adaptive(__first, __middle, __last, __len1, __len2, + __buf.begin(), _Distance(__buf.size()), + __comp); } -template -inline void __inplace_merge_aux(BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last, T*, Distance*, - Compare comp) { - Distance len1 = 0; - distance(first, middle, len1); - Distance len2 = 0; - distance(middle, last, len2); +template +inline void inplace_merge(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last) { + if (__first == __middle || __middle == __last) + return; + __inplace_merge_aux(__first, __middle, __last, + __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); +} - temporary_buffer buf(first, last); - if (buf.begin() == 0) - __merge_without_buffer(first, middle, last, len1, len2, comp); - else - __merge_adaptive(first, middle, last, len1, len2, - buf.begin(), Distance(buf.size()), - comp); -} - -template -inline void inplace_merge(BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last) { - if (first == middle || middle == last) return; - __inplace_merge_aux(first, middle, last, value_type(first), - distance_type(first)); -} - -template -inline void inplace_merge(BidirectionalIterator first, - BidirectionalIterator middle, - BidirectionalIterator last, Compare comp) { - if (first == middle || middle == last) return; - __inplace_merge_aux(first, middle, last, value_type(first), - distance_type(first), comp); -} - -template -bool includes(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2) { - while (first1 != last1 && first2 != last2) - if (*first2 < *first1) +template +inline void inplace_merge(_BidirectionalIter __first, + _BidirectionalIter __middle, + _BidirectionalIter __last, _Compare __comp) { + if (__first == __middle || __middle == __last) + return; + __inplace_merge_aux(__first, __middle, __last, + __VALUE_TYPE(__first), __DISTANCE_TYPE(__first), + __comp); +} + +// Set algorithms: includes, set_union, set_intersection, set_difference, +// set_symmetric_difference. All of these algorithms have the precondition +// that their input ranges are sorted and the postcondition that their output +// ranges are sorted. + +template +bool includes(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) { + while (__first1 != __last1 && __first2 != __last2) + if (*__first2 < *__first1) return false; - else if(*first1 < *first2) - ++first1; + else if(*__first1 < *__first2) + ++__first1; else - ++first1, ++first2; + ++__first1, ++__first2; - return first2 == last2; + return __first2 == __last2; } -template -bool includes(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, Compare comp) { - while (first1 != last1 && first2 != last2) - if (comp(*first2, *first1)) +template +bool includes(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first2, *__first1)) return false; - else if(comp(*first1, *first2)) - ++first1; + else if(__comp(*__first1, *__first2)) + ++__first1; else - ++first1, ++first2; + ++__first1, ++__first2; - return first2 == last2; + return __first2 == __last2; } -template -OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result) { - while (first1 != last1 && first2 != last2) { - if (*first1 < *first2) { - *result = *first1; - ++first1; +template +_OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + while (__first1 != __last1 && __first2 != __last2) { + if (*__first1 < *__first2) { + *__result = *__first1; + ++__first1; } - else if (*first2 < *first1) { - *result = *first2; - ++first2; + else if (*__first2 < *__first1) { + *__result = *__first2; + ++__first2; } else { - *result = *first1; - ++first1; - ++first2; + *__result = *__first1; + ++__first1; + ++__first2; } - ++result; + ++__result; } - return copy(first2, last2, copy(first1, last1, result)); + return copy(__first2, __last2, copy(__first1, __last1, __result)); } -template -OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp) { - while (first1 != last1 && first2 != last2) { - if (comp(*first1, *first2)) { - *result = *first1; - ++first1; +template +_OutputIter set_union(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) { + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__first1; } - else if (comp(*first2, *first1)) { - *result = *first2; - ++first2; + else if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; } else { - *result = *first1; - ++first1; - ++first2; + *__result = *__first1; + ++__first1; + ++__first2; } - ++result; + ++__result; } - return copy(first2, last2, copy(first1, last1, result)); + return copy(__first2, __last2, copy(__first1, __last1, __result)); } -template -OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result) { - while (first1 != last1 && first2 != last2) - if (*first1 < *first2) - ++first1; - else if (*first2 < *first1) - ++first2; +template +_OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) + ++__first1; + else if (*__first2 < *__first1) + ++__first2; else { - *result = *first1; - ++first1; - ++first2; - ++result; - } - return result; -} - -template -OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp) { - while (first1 != last1 && first2 != last2) - if (comp(*first1, *first2)) - ++first1; - else if (comp(*first2, *first1)) - ++first2; + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; +} + +template +_OutputIter set_intersection(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) + ++__first1; + else if (__comp(*__first2, *__first1)) + ++__first2; else { - *result = *first1; - ++first1; - ++first2; - ++result; - } - return result; -} - -template -OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result) { - while (first1 != last1 && first2 != last2) - if (*first1 < *first2) { - *result = *first1; - ++first1; - ++result; - } - else if (*first2 < *first1) - ++first2; + *__result = *__first1; + ++__first1; + ++__first2; + ++__result; + } + return __result; +} + +template +_OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (*__first2 < *__first1) + ++__first2; else { - ++first1; - ++first2; + ++__first1; + ++__first2; } - return copy(first1, last1, result); + return copy(__first1, __last1, __result); } -template -OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - OutputIterator result, Compare comp) { - while (first1 != last1 && first2 != last2) - if (comp(*first1, *first2)) { - *result = *first1; - ++first1; - ++result; +template +_OutputIter set_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__first1; + ++__result; } - else if (comp(*first2, *first1)) - ++first2; + else if (__comp(*__first2, *__first1)) + ++__first2; else { - ++first1; - ++first2; + ++__first1; + ++__first2; } - return copy(first1, last1, result); + return copy(__first1, __last1, __result); } -template -OutputIterator set_symmetric_difference(InputIterator1 first1, - InputIterator1 last1, - InputIterator2 first2, - InputIterator2 last2, - OutputIterator result) { - while (first1 != last1 && first2 != last2) - if (*first1 < *first2) { - *result = *first1; - ++first1; - ++result; +template +_OutputIter +set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result) { + while (__first1 != __last1 && __first2 != __last2) + if (*__first1 < *__first2) { + *__result = *__first1; + ++__first1; + ++__result; } - else if (*first2 < *first1) { - *result = *first2; - ++first2; - ++result; + else if (*__first2 < *__first1) { + *__result = *__first2; + ++__first2; + ++__result; } else { - ++first1; - ++first2; - } - return copy(first2, last2, copy(first1, last1, result)); -} - -template -OutputIterator set_symmetric_difference(InputIterator1 first1, - InputIterator1 last1, - InputIterator2 first2, - InputIterator2 last2, - OutputIterator result, Compare comp) { - while (first1 != last1 && first2 != last2) - if (comp(*first1, *first2)) { - *result = *first1; - ++first1; - ++result; - } - else if (comp(*first2, *first1)) { - *result = *first2; - ++first2; - ++result; + ++__first1; + ++__first2; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +template +_OutputIter +set_symmetric_difference(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _OutputIter __result, + _Compare __comp) { + while (__first1 != __last1 && __first2 != __last2) + if (__comp(*__first1, *__first2)) { + *__result = *__first1; + ++__first1; + ++__result; + } + else if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; + ++__result; } else { - ++first1; - ++first2; - } - return copy(first2, last2, copy(first1, last1, result)); -} - -template -ForwardIterator max_element(ForwardIterator first, ForwardIterator last) { - if (first == last) return first; - ForwardIterator result = first; - while (++first != last) - if (*result < *first) result = first; - return result; -} - -template -ForwardIterator max_element(ForwardIterator first, ForwardIterator last, - Compare comp) { - if (first == last) return first; - ForwardIterator result = first; - while (++first != last) - if (comp(*result, *first)) result = first; - return result; -} - -template -ForwardIterator min_element(ForwardIterator first, ForwardIterator last) { - if (first == last) return first; - ForwardIterator result = first; - while (++first != last) - if (*first < *result) result = first; - return result; -} - -template -ForwardIterator min_element(ForwardIterator first, ForwardIterator last, - Compare comp) { - if (first == last) return first; - ForwardIterator result = first; - while (++first != last) - if (comp(*first, *result)) result = first; - return result; -} - -template -bool next_permutation(BidirectionalIterator first, - BidirectionalIterator last) { - if (first == last) return false; - BidirectionalIterator i = first; - ++i; - if (i == last) return false; - i = last; - --i; + ++__first1; + ++__first2; + } + return copy(__first2, __last2, copy(__first1, __last1, __result)); +} + +// min_element and max_element, with and without an explicitly supplied +// comparison function. + +template +_ForwardIter max_element(_ForwardIter __first, _ForwardIter __last) { + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (*__result < *__first) + __result = __first; + return __result; +} + +template +_ForwardIter max_element(_ForwardIter __first, _ForwardIter __last, + _Compare __comp) { + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (__comp(*__result, *__first)) __result = __first; + return __result; +} + +template +_ForwardIter min_element(_ForwardIter __first, _ForwardIter __last) { + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (*__first < *__result) + __result = __first; + return __result; +} + +template +_ForwardIter min_element(_ForwardIter __first, _ForwardIter __last, + _Compare __comp) { + if (__first == __last) return __first; + _ForwardIter __result = __first; + while (++__first != __last) + if (__comp(*__first, *__result)) + __result = __first; + return __result; +} + +// next_permutation and prev_permutation, with and without an explicitly +// supplied comparison function. + +template +bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; for(;;) { - BidirectionalIterator ii = i; - --i; - if (*i < *ii) { - BidirectionalIterator j = last; - while (!(*i < *--j)); - iter_swap(i, j); - reverse(ii, last); + _BidirectionalIter __ii = __i; + --__i; + if (*__i < *__ii) { + _BidirectionalIter __j = __last; + while (!(*__i < *--__j)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); return true; } - if (i == first) { - reverse(first, last); + if (__i == __first) { + reverse(__first, __last); return false; } } } -template -bool next_permutation(BidirectionalIterator first, BidirectionalIterator last, - Compare comp) { - if (first == last) return false; - BidirectionalIterator i = first; - ++i; - if (i == last) return false; - i = last; - --i; +template +bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last, + _Compare __comp) { + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; for(;;) { - BidirectionalIterator ii = i; - --i; - if (comp(*i, *ii)) { - BidirectionalIterator j = last; - while (!comp(*i, *--j)); - iter_swap(i, j); - reverse(ii, last); + _BidirectionalIter __ii = __i; + --__i; + if (__comp(*__i, *__ii)) { + _BidirectionalIter __j = __last; + while (!__comp(*__i, *--__j)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); return true; } - if (i == first) { - reverse(first, last); + if (__i == __first) { + reverse(__first, __last); return false; } } } -template -bool prev_permutation(BidirectionalIterator first, - BidirectionalIterator last) { - if (first == last) return false; - BidirectionalIterator i = first; - ++i; - if (i == last) return false; - i = last; - --i; +template +bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last) { + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; for(;;) { - BidirectionalIterator ii = i; - --i; - if (*ii < *i) { - BidirectionalIterator j = last; - while (!(*--j < *i)); - iter_swap(i, j); - reverse(ii, last); + _BidirectionalIter __ii = __i; + --__i; + if (*__ii < *__i) { + _BidirectionalIter __j = __last; + while (!(*--__j < *__i)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); return true; } - if (i == first) { - reverse(first, last); + if (__i == __first) { + reverse(__first, __last); return false; } } } -template -bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last, - Compare comp) { - if (first == last) return false; - BidirectionalIterator i = first; - ++i; - if (i == last) return false; - i = last; - --i; +template +bool prev_permutation(_BidirectionalIter __first, _BidirectionalIter __last, + _Compare __comp) { + if (__first == __last) + return false; + _BidirectionalIter __i = __first; + ++__i; + if (__i == __last) + return false; + __i = __last; + --__i; for(;;) { - BidirectionalIterator ii = i; - --i; - if (comp(*ii, *i)) { - BidirectionalIterator j = last; - while (!comp(*--j, *i)); - iter_swap(i, j); - reverse(ii, last); + _BidirectionalIter __ii = __i; + --__i; + if (__comp(*__ii, *__i)) { + _BidirectionalIter __j = __last; + while (!__comp(*--__j, *__i)) + {} + iter_swap(__i, __j); + reverse(__ii, __last); return true; } - if (i == first) { - reverse(first, last); + if (__i == __first) { + reverse(__first, __last); return false; } } } -template -InputIterator find_first_of(InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2) +// find_first_of, with and without an explicitly supplied comparison function. + +template +_InputIter find_first_of(_InputIter __first1, _InputIter __last1, + _ForwardIter __first2, _ForwardIter __last2) { - for ( ; first1 != last1; ++first1) - for (ForwardIterator iter = first2; iter != last2; ++iter) - if (*first1 == *iter) - return first1; - return last1; + for ( ; __first1 != __last1; ++__first1) + for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) + if (*__first1 == *__iter) + return __first1; + return __last1; } -template -InputIterator find_first_of(InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2, - BinaryPredicate comp) +template +_InputIter find_first_of(_InputIter __first1, _InputIter __last1, + _ForwardIter __first2, _ForwardIter __last2, + _BinaryPredicate __comp) { - for ( ; first1 != last1; ++first1) - for (ForwardIterator iter = first2; iter != last2; ++iter) - if (comp(*first1, *iter)) - return first1; - return last1; + for ( ; __first1 != __last1; ++__first1) + for (_ForwardIter __iter = __first2; __iter != __last2; ++__iter) + if (__comp(*__first1, *__iter)) + return __first1; + return __last1; } -// Search [first2, last2) as a subsequence in [first1, last1). +// find_end, with and without an explicitly supplied comparison function. +// Search [first2, last2) as a subsequence in [first1, last1), and return +// the *last* possible match. Note that find_end for bidirectional iterators +// is much faster than for forward iterators. // find_end for forward iterators. -template -ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - forward_iterator_tag, forward_iterator_tag) +template +_ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2, + forward_iterator_tag, forward_iterator_tag) { - if (first2 == last2) - return last1; + if (__first2 == __last2) + return __last1; else { - ForwardIterator1 result = last1; + _ForwardIter1 __result = __last1; while (1) { - ForwardIterator1 new_result = search(first1, last1, first2, last2); - if (new_result == last1) - return result; + _ForwardIter1 __new_result + = search(__first1, __last1, __first2, __last2); + if (__new_result == __last1) + return __result; else { - result = new_result; - first1 = new_result; - ++first1; + __result = __new_result; + __first1 = __new_result; + ++__first1; } } } } -template -ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - forward_iterator_tag, forward_iterator_tag, - BinaryPredicate comp) +template +_ForwardIter1 __find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2, + forward_iterator_tag, forward_iterator_tag, + _BinaryPredicate __comp) { - if (first2 == last2) - return last1; + if (__first2 == __last2) + return __last1; else { - ForwardIterator1 result = last1; + _ForwardIter1 __result = __last1; while (1) { - ForwardIterator1 new_result = search(first1, last1, first2, last2, comp); - if (new_result == last1) - return result; + _ForwardIter1 __new_result + = search(__first1, __last1, __first2, __last2, __comp); + if (__new_result == __last1) + return __result; else { - result = new_result; - first1 = new_result; - ++first1; + __result = __new_result; + __first1 = __new_result; + ++__first1; } } } @@ -2494,167 +2726,155 @@ ForwardIterator1 __find_end(ForwardIterator1 first1, ForwardIterator1 last1, // find_end for bidirectional iterators. Requires partial specialization. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION -template -BidirectionalIterator1 -__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1, - BidirectionalIterator2 first2, BidirectionalIterator2 last2, +template +_BidirectionalIter1 +__find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, bidirectional_iterator_tag, bidirectional_iterator_tag) { - typedef reverse_iterator reviter1; - typedef reverse_iterator reviter2; + typedef reverse_iterator<_BidirectionalIter1> _RevIter1; + typedef reverse_iterator<_BidirectionalIter2> _RevIter2; - reviter1 rlast1(first1); - reviter2 rlast2(first2); - reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2); + _RevIter1 __rlast1(__first1); + _RevIter2 __rlast2(__first2); + _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, + _RevIter2(__last2), __rlast2); - if (rresult == rlast1) - return last1; + if (__rresult == __rlast1) + return __last1; else { - BidirectionalIterator1 result = rresult.base(); - advance(result, -distance(first2, last2)); - return result; + _BidirectionalIter1 __result = __rresult.base(); + advance(__result, -distance(__first2, __last2)); + return __result; } } -template -BidirectionalIterator1 -__find_end(BidirectionalIterator1 first1, BidirectionalIterator1 last1, - BidirectionalIterator2 first2, BidirectionalIterator2 last2, +template +_BidirectionalIter1 +__find_end(_BidirectionalIter1 __first1, _BidirectionalIter1 __last1, + _BidirectionalIter2 __first2, _BidirectionalIter2 __last2, bidirectional_iterator_tag, bidirectional_iterator_tag, - BinaryPredicate comp) + _BinaryPredicate __comp) { - typedef reverse_iterator reviter1; - typedef reverse_iterator reviter2; + typedef reverse_iterator<_BidirectionalIter1> _RevIter1; + typedef reverse_iterator<_BidirectionalIter2> _RevIter2; - reviter1 rlast1(first1); - reviter2 rlast2(first2); - reviter1 rresult = search(reviter1(last1), rlast1, reviter2(last2), rlast2, - comp); + _RevIter1 __rlast1(__first1); + _RevIter2 __rlast2(__first2); + _RevIter1 __rresult = search(_RevIter1(__last1), __rlast1, + _RevIter2(__last2), __rlast2, + __comp); - if (rresult == rlast1) - return last1; + if (__rresult == __rlast1) + return __last1; else { - BidirectionalIterator1 result = rresult.base(); - advance(result, -distance(first2, last2)); - return result; + _BidirectionalIter1 __result = __rresult.base(); + advance(__result, -distance(__first2, __last2)); + return __result; } } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -// Dispatching functions. +// Dispatching functions for find_end. -template -inline ForwardIterator1 -find_end(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2) +template +inline _ForwardIter1 +find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2) { -#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION - typedef typename iterator_traits::iterator_category - category1; - typedef typename iterator_traits::iterator_category - category2; - return __find_end(first1, last1, first2, last2, category1(), category2()); -#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - return __find_end(first1, last1, first2, last2, - forward_iterator_tag(), forward_iterator_tag()); -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + return __find_end(__first1, __last1, __first2, __last2, + __ITERATOR_CATEGORY(__first1), + __ITERATOR_CATEGORY(__first2)); } -template -inline ForwardIterator1 -find_end(ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator2 last2, - BinaryPredicate comp) +template +inline _ForwardIter1 +find_end(_ForwardIter1 __first1, _ForwardIter1 __last1, + _ForwardIter2 __first2, _ForwardIter2 __last2, + _BinaryPredicate __comp) { -#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION - typedef typename iterator_traits::iterator_category - category1; - typedef typename iterator_traits::iterator_category - category2; - return __find_end(first1, last1, first2, last2, category1(), category2(), - comp); -#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - return __find_end(first1, last1, first2, last2, - forward_iterator_tag(), forward_iterator_tag(), - comp); -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + return __find_end(__first1, __last1, __first2, __last2, + __ITERATOR_CATEGORY(__first1), + __ITERATOR_CATEGORY(__first2), + __comp); } -template -bool __is_heap(RandomAccessIterator first, RandomAccessIterator last, - Distance*) -{ - const Distance n = last - first; +// is_heap, a predicate testing whether or not a range is +// a heap. This function is an extension, not part of the C++ +// standard. - Distance parent = 0; - for (Distance child = 1; child < n; ++child) { - if (first[parent] < first[child]) +template +bool __is_heap(_RandomAccessIter __first, _Distance __n) +{ + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) { + if (__first[__parent] < __first[__child]) return false; - if ((child & 1) == 0) - ++parent; + if ((__child & 1) == 0) + ++__parent; } return true; } -template -inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last) -{ - return __is_heap(first, last, distance_type(first)); -} - - -template -bool __is_heap(RandomAccessIterator first, RandomAccessIterator last, - StrictWeakOrdering comp, - Distance*) +template +bool __is_heap(_RandomAccessIter __first, _StrictWeakOrdering __comp, + _Distance __n) { - const Distance n = last - first; - - Distance parent = 0; - for (Distance child = 1; child < n; ++child) { - if (comp(first[parent], first[child])) + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) { + if (__comp(__first[__parent], __first[__child])) return false; - if ((child & 1) == 0) - ++parent; + if ((__child & 1) == 0) + ++__parent; } return true; } -template -inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last, - StrictWeakOrdering comp) +template +inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last) +{ + return __is_heap(__first, __last - __first); +} + + +template +inline bool is_heap(_RandomAccessIter __first, _RandomAccessIter __last, + _StrictWeakOrdering __comp) { - return __is_heap(first, last, comp, distance_type(first)); + return __is_heap(__first, __comp, __last - __first); } +// is_sorted, a predicated testing whether a range is sorted in +// nondescending order. This is an extension, not part of the C++ +// standard. -template -bool is_sorted(ForwardIterator first, ForwardIterator last) +template +bool is_sorted(_ForwardIter __first, _ForwardIter __last) { - if (first == last) + if (__first == __last) return true; - ForwardIterator next = first; - for (++next; next != last; first = next, ++next) { - if (*next < *first) + _ForwardIter __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (*__next < *__first) return false; } return true; } -template -bool is_sorted(ForwardIterator first, ForwardIterator last, - StrictWeakOrdering comp) +template +bool is_sorted(_ForwardIter __first, _ForwardIter __last, + _StrictWeakOrdering __comp) { - if (first == last) + if (__first == __last) return true; - ForwardIterator next = first; - for (++next; next != last; first = next, ++next) { - if (comp(*next, *first)) + _ForwardIter __next = __first; + for (++__next; __next != __last; __first = __next, ++__next) { + if (__comp(*__next, *__first)) return false; } diff --git a/libstdc++/stl/stl_algobase.h b/libstdc++/stl/stl_algobase.h index 101fea53af8..15e535f483d 100644 --- a/libstdc++/stl/stl_algobase.h +++ b/libstdc++/stl/stl_algobase.h @@ -12,7 +12,7 @@ * purpose. It is provided "as is" without express or implied warranty. * * - * Copyright (c) 1996 + * Copyright (c) 1996-1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software @@ -58,381 +58,465 @@ __STL_BEGIN_NAMESPACE -template -inline void __iter_swap(ForwardIterator1 a, ForwardIterator2 b, T*) { - T tmp = *a; - *a = *b; - *b = tmp; +// swap and iter_swap + +template +inline void __iter_swap(_ForwardIter1 __a, _ForwardIter2 __b, _Tp*) { + _Tp __tmp = *__a; + *__a = *__b; + *__b = __tmp; } -template -inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) { - __iter_swap(a, b, value_type(a)); +template +inline void iter_swap(_ForwardIter1 __a, _ForwardIter2 __b) { + __iter_swap(__a, __b, __VALUE_TYPE(__a)); } -template -inline void swap(T& a, T& b) { - T tmp = a; - a = b; - b = tmp; +template +inline void swap(_Tp& __a, _Tp& __b) { + _Tp __tmp = __a; + __a = __b; + __b = __tmp; } +//-------------------------------------------------- +// min and max + #ifndef __BORLANDC__ #undef min #undef max -template -inline const T& min(const T& a, const T& b) { - return b < a ? b : a; +template +inline const _Tp& min(const _Tp& __a, const _Tp& __b) { + return __b < __a ? __b : __a; } -template -inline const T& max(const T& a, const T& b) { - return a < b ? b : a; +template +inline const _Tp& max(const _Tp& __a, const _Tp& __b) { + return __a < __b ? __b : __a; } #endif /* __BORLANDC__ */ -template -inline const T& min(const T& a, const T& b, Compare comp) { - return comp(b, a) ? b : a; +template +inline const _Tp& min(const _Tp& __a, const _Tp& __b, _Compare __comp) { + return __comp(__b, __a) ? __b : __a; } -template -inline const T& max(const T& a, const T& b, Compare comp) { - return comp(a, b) ? b : a; +template +inline const _Tp& max(const _Tp& __a, const _Tp& __b, _Compare __comp) { + return __comp(__a, __b) ? __b : __a; } -template -inline OutputIterator __copy(InputIterator first, InputIterator last, - OutputIterator result, input_iterator_tag) -{ - for ( ; first != last; ++result, ++first) - *result = *first; - return result; -} +//-------------------------------------------------- +// copy -template -inline OutputIterator -__copy_d(RandomAccessIterator first, RandomAccessIterator last, - OutputIterator result, Distance*) -{ - for (Distance n = last - first; n > 0; --n, ++result, ++first) - *result = *first; - return result; -} +// All of these auxiliary functions serve two purposes. (1) Replace +// calls to copy with memmove whenever possible. (Memmove, not memcpy, +// because the input and output ranges are permitted to overlap.) +// (2) If we're using random access iterators, then write the loop as +// a for loop with an explicit count. The auxiliary class __copy_dispatch +// is a workaround for compilers that don't support partial ordering of +// function templates. -template -inline OutputIterator -__copy(RandomAccessIterator first, RandomAccessIterator last, - OutputIterator result, random_access_iterator_tag) +template +inline _OutputIter __copy(_InputIter __first, _InputIter __last, + _OutputIter __result, + input_iterator_tag, _Distance*) { - return __copy_d(first, last, result, distance_type(first)); + for ( ; __first != __last; ++__result, ++__first) + *__result = *__first; + return __result; } -template -struct __copy_dispatch +template +inline _OutputIter +__copy(_RandomAccessIter __first, _RandomAccessIter __last, + _OutputIter __result, random_access_iterator_tag, _Distance*) { - OutputIterator operator()(InputIterator first, InputIterator last, - OutputIterator result) { - return __copy(first, last, result, iterator_category(first)); + for (_Distance __n = __last - __first; __n > 0; --__n) { + *__result = *__first; + ++__first; + ++__result; } -}; - -#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION - -template -inline T* __copy_t(const T* first, const T* last, T* result, __true_type) { - memmove(result, first, sizeof(T) * (last - first)); - return result + (last - first); + return __result; } -template -inline T* __copy_t(const T* first, const T* last, T* result, __false_type) { - return __copy_d(first, last, result, (ptrdiff_t*) 0); +template +inline _Tp* +__copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result) { + memmove(__result, __first, sizeof(_Tp) * (__last - __first)); + return __result + (__last - __first); } -template -struct __copy_dispatch +#ifdef __STL_CLASS_PARTIAL_SPECIALIZATION + +template +struct __copy_dispatch { + static _OutputIter copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { + typedef typename iterator_traits<_InputIter>::iterator_category _Category; + typedef typename iterator_traits<_InputIter>::difference_type _Distance; + return __copy(__first, __last, __result, _Category(), (_Distance*) 0); + } +}; + +template +struct __copy_dispatch<_Tp*, _Tp*, __true_type> { - T* operator()(T* first, T* last, T* result) { - typedef typename __type_traits::has_trivial_assignment_operator t; - return __copy_t(first, last, result, t()); + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + return __copy_trivial(__first, __last, __result); } }; -template -struct __copy_dispatch +template +struct __copy_dispatch { - T* operator()(const T* first, const T* last, T* result) { - typedef typename __type_traits::has_trivial_assignment_operator t; - return __copy_t(first, last, result, t()); + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + return __copy_trivial(__first, __last, __result); } }; -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ +template +inline _OutputIter copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { + typedef typename iterator_traits<_InputIter>::value_type _Tp; + typedef typename __type_traits<_Tp>::has_trivial_assignment_operator + _Trivial; + return __copy_dispatch<_InputIter, _OutputIter, _Trivial> + ::copy(__first, __last, __result); +} + +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template -inline OutputIterator copy(InputIterator first, InputIterator last, - OutputIterator result) +template +inline _OutputIter copy(_InputIter __first, _InputIter __last, + _OutputIter __result) { - return __copy_dispatch()(first, last, result); + return __copy(__first, __last, __result, + __ITERATOR_CATEGORY(__first), + __DISTANCE_TYPE(__first)); } -inline char* copy(const char* first, const char* last, char* result) { - memmove(result, first, last - first); - return result + (last - first); +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); +inline wchar_t* copy(const wchar_t* __first, const wchar_t* __last, + wchar_t* __result) { + memmove(__result, __first, sizeof(wchar_t) * (__last - __first)); + return __result + (__last - __first); } -template -inline BidirectionalIterator2 __copy_backward(BidirectionalIterator1 first, - BidirectionalIterator1 last, - BidirectionalIterator2 result) { - while (first != last) *--result = *--last; - return result; -} +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ +//-------------------------------------------------- +// copy_backward -template -struct __copy_backward_dispatch +template +inline _BidirectionalIter2 __copy_backward(_BidirectionalIter1 __first, + _BidirectionalIter1 __last, + _BidirectionalIter2 __result, + bidirectional_iterator_tag, + _Distance*) { - BidirectionalIterator2 operator()(BidirectionalIterator1 first, - BidirectionalIterator1 last, - BidirectionalIterator2 result) { - return __copy_backward(first, last, result); - } -}; + while (__first != __last) + *--__result = *--__last; + return __result; +} + +template +inline _BidirectionalIter __copy_backward(_RandomAccessIter __first, + _RandomAccessIter __last, + _BidirectionalIter __result, + random_access_iterator_tag, + _Distance*) +{ + for (_Distance __n = __last - __first; __n > 0; --__n) + *--__result = *--__last; + return __result; +} #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION -template -inline T* __copy_backward_t(const T* first, const T* last, T* result, - __true_type) { - const ptrdiff_t N = last - first; - memmove(result - N, first, sizeof(T) * N); - return result - N; -} +// This dispatch class is a workaround for compilers that do not +// have partial ordering of function templates. All we're doing is +// creating a specialization so that we can turn a call to copy_backward +// into a memmove whenever possible. -template -inline T* __copy_backward_t(const T* first, const T* last, T* result, - __false_type) { - return __copy_backward(first, last, result); -} +template +struct __copy_backward_dispatch +{ + typedef typename iterator_traits<_BidirectionalIter1>::iterator_category + _Cat; + typedef typename iterator_traits<_BidirectionalIter1>::difference_type + _Distance; + + static _BidirectionalIter2 copy(_BidirectionalIter1 __first, + _BidirectionalIter1 __last, + _BidirectionalIter2 __result) { + return __copy_backward(__first, __last, __result, _Cat(), (_Distance*) 0); + } +}; -template -struct __copy_backward_dispatch +template +struct __copy_backward_dispatch<_Tp*, _Tp*, __true_type> { - T* operator()(T* first, T* last, T* result) { - typedef typename __type_traits::has_trivial_assignment_operator t; - return __copy_backward_t(first, last, result, t()); + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + const ptrdiff_t _Num = __last - __first; + memmove(__result - _Num, __first, sizeof(_Tp) * _Num); + return __result - _Num; } }; -template -struct __copy_backward_dispatch +template +struct __copy_backward_dispatch { - T* operator()(const T* first, const T* last, T* result) { - typedef typename __type_traits::has_trivial_assignment_operator t; - return __copy_backward_t(first, last, result, t()); + static _Tp* copy(const _Tp* __first, const _Tp* __last, _Tp* __result) { + return __copy_backward_dispatch<_Tp*, _Tp*, __true_type> + ::copy(__first, __last, __result); } }; -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ +template +inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) { + typedef typename __type_traits::value_type> + ::has_trivial_assignment_operator + _Trivial; + return __copy_backward_dispatch<_BI1, _BI2, _Trivial> + ::copy(__first, __last, __result); +} + +#else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template -inline BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, - BidirectionalIterator1 last, - BidirectionalIterator2 result) { - return __copy_backward_dispatch()(first, last, - result); +template +inline _BI2 copy_backward(_BI1 __first, _BI1 __last, _BI2 __result) { + return __copy_backward(__first, __last, __result, + __ITERATOR_CATEGORY(__first), + __DISTANCE_TYPE(__first)); } -template -pair __copy_n(InputIterator first, Size count, - OutputIterator result, - input_iterator_tag) { - for ( ; count > 0; --count, ++first, ++result) - *result = *first; - return pair(first, result); +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + +//-------------------------------------------------- +// copy_n (not part of the C++ standard) + +template +pair<_InputIter, _OutputIter> __copy_n(_InputIter __first, _Size __count, + _OutputIter __result, + input_iterator_tag) { + for ( ; __count > 0; --__count) { + *__result = *__first; + ++__first; + ++__result; + } + return pair<_InputIter, _OutputIter>(__first, __result); } -template -inline pair -__copy_n(RandomAccessIterator first, Size count, - OutputIterator result, +template +inline pair<_RAIter, _OutputIter> +__copy_n(_RAIter __first, _Size __count, + _OutputIter __result, random_access_iterator_tag) { - RandomAccessIterator last = first + count; - return pair(last, - copy(first, last, result)); + _RAIter __last = __first + __count; + return pair<_RAIter, _OutputIter>(__last, copy(__first, __last, __result)); +} + +template +inline pair<_InputIter, _OutputIter> +__copy_n(_InputIter __first, _Size __count, _OutputIter __result) { + return __copy_n(__first, __count, __result, + __ITERATOR_CATEGORY(__first)); } -template -inline pair -copy_n(InputIterator first, Size count, - OutputIterator result) { - return __copy_n(first, count, result, iterator_category(first)); +template +inline pair<_InputIter, _OutputIter> +copy_n(_InputIter __first, _Size __count, _OutputIter __result) { + return __copy_n(__first, __count, __result); } -template -void fill(ForwardIterator first, ForwardIterator last, const T& value) { - for ( ; first != last; ++first) - *first = value; +//-------------------------------------------------- +// fill and fill_n + + +template +void fill(_ForwardIter __first, _ForwardIter __last, const _Tp& __value) { + for ( ; __first != __last; ++__first) + *__first = __value; } -template -OutputIterator fill_n(OutputIterator first, Size n, const T& value) { - for ( ; n > 0; --n, ++first) - *first = value; - return first; +template +_OutputIter fill_n(_OutputIter __first, _Size __n, const _Tp& __value) { + for ( ; __n > 0; --__n, ++__first) + *__first = __value; + return __first; } -template -pair mismatch(InputIterator1 first1, - InputIterator1 last1, - InputIterator2 first2) { - while (first1 != last1 && *first1 == *first2) { - ++first1; - ++first2; +//-------------------------------------------------- +// equal and mismatch + +template +pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1, + _InputIter1 __last1, + _InputIter2 __first2) { + while (__first1 != __last1 && *__first1 == *__first2) { + ++__first1; + ++__first2; } - return pair(first1, first2); + return pair<_InputIter1, _InputIter2>(__first1, __first2); } -template -pair mismatch(InputIterator1 first1, - InputIterator1 last1, - InputIterator2 first2, - BinaryPredicate binary_pred) { - while (first1 != last1 && binary_pred(*first1, *first2)) { - ++first1; - ++first2; +template +pair<_InputIter1, _InputIter2> mismatch(_InputIter1 __first1, + _InputIter1 __last1, + _InputIter2 __first2, + _BinaryPredicate __binary_pred) { + while (__first1 != __last1 && __binary_pred(*__first1, *__first2)) { + ++__first1; + ++__first2; } - return pair(first1, first2); + return pair<_InputIter1, _InputIter2>(__first1, __first2); } -template -inline bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2) { - for ( ; first1 != last1; ++first1, ++first2) - if (*first1 != *first2) +template +inline bool equal(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2) { + for ( ; __first1 != __last1; ++__first1, ++__first2) + if (*__first1 != *__first2) return false; return true; } -template -inline bool equal(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, BinaryPredicate binary_pred) { - for ( ; first1 != last1; ++first1, ++first2) - if (!binary_pred(*first1, *first2)) +template +inline bool equal(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _BinaryPredicate __binary_pred) { + for ( ; __first1 != __last1; ++__first1, ++__first2) + if (!__binary_pred(*__first1, *__first2)) return false; return true; } -template -bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2) { - for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) { - if (*first1 < *first2) +//-------------------------------------------------- +// lexicographical_compare and lexicographical_compare_3way. +// (the latter is not part of the C++ standard.) + +template +bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) { + for ( ; __first1 != __last1 && __first2 != __last2 + ; ++__first1, ++__first2) { + if (*__first1 < *__first2) return true; - if (*first2 < *first1) + if (*__first2 < *__first1) return false; } - return first1 == last1 && first2 != last2; + return __first1 == __last1 && __first2 != __last2; } -template -bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - Compare comp) { - for ( ; first1 != last1 && first2 != last2; ++first1, ++first2) { - if (comp(*first1, *first2)) +template +bool lexicographical_compare(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _Compare __comp) { + for ( ; __first1 != __last1 && __first2 != __last2 + ; ++__first1, ++__first2) { + if (__comp(*__first1, *__first2)) return true; - if (comp(*first2, *first1)) + if (__comp(*__first2, *__first1)) return false; } - return first1 == last1 && first2 != last2; + 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) +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; + 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) +inline bool lexicographical_compare(const char* __first1, const char* __last1, + const char* __first2, const char* __last2) { #if CHAR_MAX == SCHAR_MAX - return lexicographical_compare((const signed char*) first1, - (const signed char*) last1, - (const signed char*) first2, - (const signed char*) last2); -#else - return lexicographical_compare((const unsigned char*) first1, - (const unsigned char*) last1, - (const unsigned char*) first2, - (const unsigned char*) last2); -#endif -} - -template -int lexicographical_compare_3way(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2) + return lexicographical_compare((const signed char*) __first1, + (const signed char*) __last1, + (const signed char*) __first2, + (const signed char*) __last2); +#else /* CHAR_MAX == SCHAR_MAX */ + return lexicographical_compare((const unsigned char*) __first1, + (const unsigned char*) __last1, + (const unsigned char*) __first2, + (const unsigned char*) __last2); +#endif /* CHAR_MAX == SCHAR_MAX */ +} + +template +int __lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) { - while (first1 != last1 && first2 != last2) { - if (*first1 < *first2) return -1; - if (*first2 < *first1) return 1; - ++first1; ++first2; + while (__first1 != __last1 && __first2 != __last2) { + if (*__first1 < *__first2) + return -1; + if (*__first2 < *__first1) + return 1; + ++__first1; + ++__first2; + } + if (__first2 == __last2) { + return !(__first1 == __last1); } - if (first2 == last2) { - return !(first1 == last1); - } else { + else { return -1; } } inline int -lexicographical_compare_3way(const unsigned char* first1, - const unsigned char* last1, - const unsigned char* first2, - const unsigned char* last2) +__lexicographical_compare_3way(const unsigned char* __first1, + const unsigned char* __last1, + const unsigned char* __first2, + const unsigned char* __last2) { - const ptrdiff_t len1 = last1 - first1; - const ptrdiff_t len2 = last2 - first2; - const int result = memcmp(first1, first2, min(len1, len2)); - return result != 0 ? result : (len1 == len2 ? 0 : (len1 < len2 ? -1 : 1)); + const ptrdiff_t __len1 = __last1 - __first1; + const ptrdiff_t __len2 = __last2 - __first2; + const int __result = memcmp(__first1, __first2, min(__len1, __len2)); + return __result != 0 ? __result + : (__len1 == __len2 ? 0 : (__len1 < __len2 ? -1 : 1)); } -inline int lexicographical_compare_3way(const char* first1, const char* last1, - const char* first2, const char* last2) +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); + 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); + return __lexicographical_compare_3way((const unsigned char*) __first1, + (const unsigned char*) __last1, + (const unsigned char*) __first2, + (const unsigned char*) __last2); #endif } +template +int lexicographical_compare_3way(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2) +{ + return __lexicographical_compare_3way(__first1, __last1, __first2, __last2); +} + __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_ALGOBASE_H */ diff --git a/libstdc++/stl/stl_alloc.h b/libstdc++/stl/stl_alloc.h index 2c3de40f61b..3a773b4bbc0 100644 --- a/libstdc++/stl/stl_alloc.h +++ b/libstdc++/stl/stl_alloc.h @@ -40,15 +40,12 @@ #if 0 # include -# define __THROW_BAD_ALLOC throw bad_alloc +# define __THROW_BAD_ALLOC throw bad_alloc() #elif !defined(__THROW_BAD_ALLOC) # include # define __THROW_BAD_ALLOC cerr << "out of memory" << endl; exit(1) #endif -#ifndef __ALLOC -# define __ALLOC alloc -#endif #ifdef __STL_WIN32THREADS # include #endif @@ -72,9 +69,9 @@ // lock. Performance may not be adequate. # include # define __NODE_ALLOCATOR_LOCK \ - if (threads) pthread_mutex_lock(&__node_allocator_lock) + if (threads) pthread_mutex_lock(&_S_node_allocator_lock) # define __NODE_ALLOCATOR_UNLOCK \ - if (threads) pthread_mutex_unlock(&__node_allocator_lock) + if (threads) pthread_mutex_unlock(&_S_node_allocator_lock) # define __NODE_ALLOCATOR_THREADS true # define __VOLATILE volatile // Needed at -O3 on SGI # endif @@ -82,9 +79,9 @@ // 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) + EnterCriticalSection(&_S_node_allocator_lock) # define __NODE_ALLOCATOR_UNLOCK \ - LeaveCriticalSection(&__node_allocator_lock) + LeaveCriticalSection(&_S_node_allocator_lock) # define __NODE_ALLOCATOR_THREADS true # define __VOLATILE volatile // may not be needed # endif /* WIN32THREADS */ @@ -100,9 +97,9 @@ // would be cleaner but fails with certain levels of standard // conformance. # define __NODE_ALLOCATOR_LOCK if (threads && __us_rsthread_malloc) \ - { __lock(&__node_allocator_lock); } + { _S_lock(&_S_node_allocator_lock); } # define __NODE_ALLOCATOR_UNLOCK if (threads && __us_rsthread_malloc) \ - { __unlock(&__node_allocator_lock); } + { _S_unlock(&_S_node_allocator_lock); } # define __NODE_ALLOCATOR_THREADS true # define __VOLATILE volatile // Needed at -O3 on SGI # endif @@ -131,100 +128,100 @@ __STL_BEGIN_NAMESPACE # endif #endif -template +template class __malloc_alloc_template { private: -static void *oom_malloc(size_t); - -static void *oom_realloc(void *, size_t); + static void* _S_oom_malloc(size_t); + static void* _S_oom_realloc(void*, size_t); #ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG - static void (* __malloc_alloc_oom_handler)(); + 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* allocate(size_t __n) + { + void* __result = malloc(__n); + if (0 == __result) __result = _S_oom_malloc(__n); + return __result; + } -static void deallocate(void *p, size_t /* n */) -{ - free(p); -} + 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* reallocate(void* __p, size_t /* old_sz */, size_t __new_sz) + { + void* __result = realloc(__p, __new_sz); + if (0 == __result) __result = _S_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); -} + static void (* __set_malloc_handler(void (*__f)()))() + { + void (* __old)() = __malloc_alloc_oom_handler; + __malloc_alloc_oom_handler = __f; + return(__old); + } }; // malloc_alloc out-of-memory handling #ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG -template -void (* __malloc_alloc_template::__malloc_alloc_oom_handler)() = 0; +template +void (* __malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0; #endif -template -void * __malloc_alloc_template::oom_malloc(size_t n) +template +void* +__malloc_alloc_template<__inst>::_S_oom_malloc(size_t __n) { - void (* my_malloc_handler)(); - void *result; + 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); + __my_malloc_handler = __malloc_alloc_oom_handler; + if (0 == __my_malloc_handler) { __THROW_BAD_ALLOC; } + (*__my_malloc_handler)(); + __result = malloc(__n); + if (__result) return(__result); } } -template -void * __malloc_alloc_template::oom_realloc(void *p, size_t n) +template +void* __malloc_alloc_template<__inst>::_S_oom_realloc(void* __p, size_t __n) { - void (* my_malloc_handler)(); - void *result; + 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); + __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 +template class simple_alloc { public: - static T *allocate(size_t n) - { return 0 == n? 0 : (T*) Alloc::allocate(n * sizeof (T)); } - static T *allocate(void) - { return (T*) Alloc::allocate(sizeof (T)); } - static void deallocate(T *p, size_t n) - { if (0 != n) Alloc::deallocate(p, n * sizeof (T)); } - static void deallocate(T *p) - { Alloc::deallocate(p, sizeof (T)); } + static _Tp* allocate(size_t __n) + { return 0 == __n ? 0 : (_Tp*) _Alloc::allocate(__n * sizeof (_Tp)); } + static _Tp* allocate(void) + { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); } + static void deallocate(_Tp* __p, size_t __n) + { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); } + static void deallocate(_Tp* __p) + { _Alloc::deallocate(__p, sizeof (_Tp)); } }; // Allocator adaptor to check size arguments for debugging. @@ -232,41 +229,40 @@ public: // 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 +template class debug_alloc { private: -enum {extra = 8}; // Size of space used to store size. Note + enum {_S_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* allocate(size_t __n) + { + char* __result = (char*)_Alloc::allocate(__n + _S_extra); + *(size_t*)__result = __n; + return __result + _S_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; -} + static void deallocate(void* __p, size_t __n) + { + char* __real_p = (char*)__p - _S_extra; + assert(*(size_t*)__real_p == __n); + _Alloc::deallocate(__real_p, __n + _S_extra); + } + static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz) + { + char* __real_p = (char*)__p - _S_extra; + assert(*(size_t*)__real_p == __old_sz); + char* __result = (char*) + _Alloc::reallocate(__real_p, __old_sz + _S_extra, __new_sz + _S_extra); + *(size_t*)__result = __new_sz; + return __result + _S_extra; + } }; @@ -286,10 +282,10 @@ typedef malloc_alloc single_client_alloc; // 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 +// 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 +// _S_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. // @@ -305,9 +301,9 @@ typedef malloc_alloc single_client_alloc; // 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}; + enum {_ALIGN = 8}; + enum {_MAX_BYTES = 128}; + enum {_NFREELISTS = _MAX_BYTES/_ALIGN}; #endif template @@ -317,123 +313,124 @@ 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}; + 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)); - } + static size_t + _S_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. */ + union _Obj { + union _Obj* _M_free_list_link; + char _M_client_data[1]; /* The client sees this. */ }; private: # ifdef __SUNPRO_CC - static obj * __VOLATILE free_list[]; + static _Obj* __VOLATILE _S_free_list[]; // Specifying a size results in duplicate def for 4.1 # else - static obj * __VOLATILE free_list[__NFREELISTS]; + static _Obj* __VOLATILE _S_free_list[_NFREELISTS]; # endif - static size_t FREELIST_INDEX(size_t bytes) { - return (((bytes) + __ALIGN-1)/__ALIGN - 1); + static size_t _S_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); + // Returns an object of size __n, and optionally adds to size __n free list. + static void* _S_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); + static char* _S_chunk_alloc(size_t __size, int& __nobjs); // Chunk allocation state. - static char *start_free; - static char *end_free; - static size_t heap_size; + static char* _S_start_free; + static char* _S_end_free; + static size_t _S_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 *); + static volatile unsigned long _S_node_allocator_lock; + static void _S_lock(volatile unsigned long*); + static inline void _S_unlock(volatile unsigned long*); # endif # ifdef __STL_PTHREADS - static pthread_mutex_t __node_allocator_lock; + static pthread_mutex_t _S_node_allocator_lock; # endif # ifdef __STL_WIN32THREADS - static CRITICAL_SECTION __node_allocator_lock; - static bool __node_allocator_lock_initialized; + static CRITICAL_SECTION _S_node_allocator_lock; + static bool _S_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; + if (!_S_node_allocator_lock_initialized) { + InitializeCriticalSection(&_S_node_allocator_lock); + _S_node_allocator_lock_initialized = true; } } private: # endif - class lock { + class _Lock { public: - lock() { __NODE_ALLOCATOR_LOCK; } - ~lock() { __NODE_ALLOCATOR_UNLOCK; } + _Lock() { __NODE_ALLOCATOR_LOCK; } + ~_Lock() { __NODE_ALLOCATOR_UNLOCK; } }; - friend class lock; + friend class _Lock; public: - /* n must be > 0 */ - static void * allocate(size_t n) + /* __n must be > 0 */ + static void* allocate(size_t __n) { - obj * __VOLATILE * my_free_list; - obj * __RESTRICT result; + _Obj* __VOLATILE* __my_free_list; + _Obj* __RESTRICT __result; - if (n > (size_t) __MAX_BYTES) { - return(malloc_alloc::allocate(n)); + if (__n > (size_t) _MAX_BYTES) { + return(malloc_alloc::allocate(__n)); } - my_free_list = free_list + FREELIST_INDEX(n); + __my_free_list = _S_free_list + _S_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; + _Lock __lock_instance; # endif - result = *my_free_list; - if (result == 0) { - void *r = refill(ROUND_UP(n)); - return r; + __result = *__my_free_list; + if (__result == 0) { + void* __r = _S_refill(_S_round_up(__n)); + return __r; } - *my_free_list = result -> free_list_link; - return (result); + *__my_free_list = __result -> _M_free_list_link; + return (__result); }; - /* p may not be 0 */ - static void deallocate(void *p, size_t n) + /* __p may not be 0 */ + static void deallocate(void* __p, size_t __n) { - obj *q = (obj *)p; - obj * __VOLATILE * my_free_list; + _Obj* __q = (_Obj*)__p; + _Obj* __VOLATILE* __my_free_list; - if (n > (size_t) __MAX_BYTES) { - malloc_alloc::deallocate(p, n); + if (__n > (size_t) _MAX_BYTES) { + malloc_alloc::deallocate(__p, __n); return; } - my_free_list = free_list + FREELIST_INDEX(n); + __my_free_list = _S_free_list + _S_freelist_index(__n); // acquire lock # ifndef _NOTHREADS /*REFERENCED*/ - lock lock_instance; + _Lock __lock_instance; # endif /* _NOTHREADS */ - q -> free_list_link = *my_free_list; - *my_free_list = q; + __q -> _M_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); + static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz); } ; @@ -446,228 +443,246 @@ typedef __default_alloc_template single_client_alloc; /* the malloc heap too much. */ /* We assume that size is properly aligned. */ /* We hold the allocation lock. */ -template +template char* -__default_alloc_template::chunk_alloc(size_t size, int& nobjs) +__default_alloc_template<__threads, __inst>::_S_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); + char* __result; + size_t __total_bytes = __size * __nobjs; + size_t __bytes_left = _S_end_free - _S_start_free; + + if (__bytes_left >= __total_bytes) { + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); + } else if (__bytes_left >= __size) { + __nobjs = (int)(__bytes_left/__size); + __total_bytes = __size * __nobjs; + __result = _S_start_free; + _S_start_free += __total_bytes; + return(__result); } else { - size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4); + size_t __bytes_to_get = + 2 * __total_bytes + _S_round_up(_S_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); + if (__bytes_left > 0) { + _Obj* __VOLATILE* __my_free_list = + _S_free_list + _S_freelist_index(__bytes_left); - ((obj *)start_free) -> free_list_link = *my_free_list; - *my_free_list = (obj *)start_free; + ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list; + *__my_free_list = (_Obj*)_S_start_free; } - start_free = (char *)malloc(bytes_to_get); - if (0 == start_free) { - int i; - obj * __VOLATILE * my_free_list, *p; + _S_start_free = (char*)malloc(__bytes_to_get); + if (0 == _S_start_free) { + size_t __i; + _Obj* __VOLATILE* __my_free_list; + _Obj* __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)); + for (__i = __size; __i <= _MAX_BYTES; __i += _ALIGN) { + __my_free_list = _S_free_list + _S_freelist_index(__i); + __p = *__my_free_list; + if (0 != __p) { + *__my_free_list = __p -> _M_free_list_link; + _S_start_free = (char*)__p; + _S_end_free = _S_start_free + __i; + return(_S_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); + _S_end_free = 0; // In case of exception. + _S_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)); + _S_heap_size += __bytes_to_get; + _S_end_free = _S_start_free + __bytes_to_get; + return(_S_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. */ +/* Returns an object of size __n, and optionally adds to size __n free list.*/ +/* We assume that __n is properly aligned. */ /* We hold the allocation lock. */ -template -void* __default_alloc_template::refill(size_t n) +template +void* +__default_alloc_template<__threads, __inst>::_S_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; + int __nobjs = 20; + char* __chunk = _S_chunk_alloc(__n, __nobjs); + _Obj* __VOLATILE* __my_free_list; + _Obj* __result; + _Obj* __current_obj; + _Obj* __next_obj; + int __i; - if (1 == nobjs) return(chunk); - my_free_list = free_list + FREELIST_INDEX(n); + if (1 == __nobjs) return(__chunk); + __my_free_list = _S_free_list + _S_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; + __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 -> _M_free_list_link = 0; break; } else { - current_obj -> free_list_link = next_obj; + __current_obj -> _M_free_list_link = __next_obj; } } - return(result); + return(__result); } template void* -__default_alloc_template::reallocate(void *p, - size_t old_sz, - size_t new_sz) +__default_alloc_template::reallocate(void* __p, + size_t __old_sz, + size_t __new_sz) { - void * result; - size_t copy_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 (__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); + if (_S_round_up(__old_sz) == _S_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 __STL_PTHREADS - template + template pthread_mutex_t - __default_alloc_template::__node_allocator_lock + __default_alloc_template<__threads, __inst>::_S_node_allocator_lock = PTHREAD_MUTEX_INITIALIZER; #endif #ifdef __STL_WIN32THREADS - template CRITICAL_SECTION - __default_alloc_template::__node_allocator_lock; - - template bool - __default_alloc_template::__node_allocator_lock_initialized + template + CRITICAL_SECTION + __default_alloc_template<__threads, __inst>:: + _S_node_allocator_lock; + + template + bool + __default_alloc_template<__threads, __inst>:: + _S_node_allocator_lock_initialized = false; #endif #ifdef __STL_SGI_THREADS __STL_END_NAMESPACE #include -#include +#include /* XXX should use */ __STL_BEGIN_NAMESPACE // Somewhat generic lock implementations. We need only test-and-set // and some way to sleep. These should work with both SGI pthreads // and sproc threads. They may be useful on other systems. -template +template volatile unsigned long -__default_alloc_template::__node_allocator_lock = 0; +__default_alloc_template<__threads, __inst>::_S_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 +template void -__default_alloc_template::__lock(volatile unsigned long *lock) +__default_alloc_template<__threads, __inst>:: + _S_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)) { + const unsigned __low_spin_max = 30; // spins if we suspect uniprocessor + const unsigned __high_spin_max = 1000; // spins for multiprocessor + static unsigned __spin_max = __low_spin_max; + unsigned __my_spin_max; + static unsigned __last_spins = 0; + unsigned __my_last_spins; + 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) { + __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)) { + 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; + __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)) { + __spin_max = __low_spin_max; + for (__i = 0 ;; ++__i) { + struct timespec __ts; + int __log_nsec = __i + 6; + + if (!__test_and_set((unsigned long *)__lock, 1)) { return; } - nanosleep(&ts, 0); + if (__log_nsec > 27) __log_nsec = 27; + /* Max sleep is 2**27nsec ~ 60msec */ + __ts.tv_sec = 0; + __ts.tv_nsec = 1 << __log_nsec; + nanosleep(&__ts, 0); } } -template +template inline void -__default_alloc_template::__unlock(volatile unsigned long *lock) +__default_alloc_template<__threads, __inst>::_S_unlock( + volatile unsigned long* __lock) { # if defined(__GNUC__) && __mips >= 3 asm("sync"); - *lock = 0; + *__lock = 0; # elif __mips >= 3 && (defined (_ABIN32) || defined(_ABI64)) - __lock_release(lock); + __lock_release(__lock); # else - *lock = 0; + *__lock = 0; // This is not sufficient on many multiprocessors, since // writes to protected variables and the lock may be reordered. # endif } #endif -template -char *__default_alloc_template::start_free = 0; +template +char* __default_alloc_template<__threads, __inst>::_S_start_free = 0; -template -char *__default_alloc_template::end_free = 0; +template +char* __default_alloc_template<__threads, __inst>::_S_end_free = 0; -template -size_t __default_alloc_template::heap_size = 0; +template +size_t __default_alloc_template<__threads, __inst>::_S_heap_size = 0; -template -__default_alloc_template::obj * __VOLATILE -__default_alloc_template ::free_list[ +template +__default_alloc_template<__threads, __inst>::_Obj* __VOLATILE +__default_alloc_template<__threads, __inst> ::_S_free_list[ # ifdef __SUNPRO_CC - __NFREELISTS + _NFREELISTS # else - __default_alloc_template::__NFREELISTS + __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 @@ -683,6 +698,327 @@ __default_alloc_template ::free_list[ #endif /* ! __USE_MALLOC */ +// This implements allocators as specified in the C++ standard. +// +// Note that standard-conforming allocators use many language features +// that are not yet widely implemented. In particular, they rely on +// member templates, partial specialization, partial ordering of function +// templates, the typename keyword, and the use of the template keyword +// to refer to a template member of a dependent type. + +#ifdef __STL_USE_STD_ALLOCATORS + +template +class allocator { + typedef alloc _Alloc; // The underlying allocator. +public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template struct rebind { + typedef allocator<_Tp1> other; + }; + + allocator() __STL_NOTHROW {} + allocator(const allocator&) __STL_NOTHROW {} + template allocator(const allocator<_Tp1>&) __STL_NOTHROW {} + ~allocator() __STL_NOTHROW {} + + pointer address(reference __x) const { return &__x; } + const_pointer address(const_reference __x) const { return &__x; } + + // __n is permitted to be 0. The C++ standard says nothing about what + // the return value is when __n == 0. + _Tp* allocate(size_type __n, const void* = 0) { + return __n != 0 ? static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))) + : 0; + } + + // __p is not permitted to be a null pointer. + void deallocate(pointer __p, size_type __n) + { _Alloc::deallocate(__p, __n * sizeof(_Tp)); } + + size_type max_size() const __STL_NOTHROW + { return size_t(-1) / sizeof(_Tp); } + + void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } + void destroy(pointer __p) { __p->~_Tp(); } +}; + +template<> +class allocator { + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template struct rebind { + typedef allocator<_Tp1> other; + }; +}; + + +template +inline bool operator==(const allocator<_T1>&, const allocator<_T2>&) +{ + return true; +} + +template +inline bool operator!=(const allocator<_T1>&, const allocator<_T2>&) +{ + return false; +} + +// Allocator adaptor to turn an SGI-style allocator (e.g. alloc, malloc_alloc) +// into a standard-conforming allocator. Note that this adaptor does +// *not* assume that all objects of the underlying alloc class are +// identical, nor does it assume that all of the underlying alloc's +// member functions are static member functions. Note, also, that +// __allocator<_Tp, alloc> is essentially the same thing as allocator<_Tp>. + +template +struct __allocator { + _Alloc __underlying_alloc; + + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef const _Tp* const_pointer; + typedef _Tp& reference; + typedef const _Tp& const_reference; + typedef _Tp value_type; + + template struct rebind { + typedef __allocator<_Tp1, _Alloc> other; + }; + + __allocator() __STL_NOTHROW {} + __allocator(const __allocator& __a) __STL_NOTHROW + : __underlying_alloc(__a.__underlying_alloc) {} + template + __allocator(const __allocator<_Tp1, _Alloc>& __a) __STL_NOTHROW + : __underlying_alloc(__a.__underlying_alloc) {} + ~__allocator() __STL_NOTHROW {} + + pointer address(reference __x) const { return &__x; } + const_pointer address(const_reference __x) const { return &__x; } + + // __n is permitted to be 0. + _Tp* allocate(size_type __n, const void* = 0) { + return __n != 0 + ? static_cast<_Tp*>(__underlying_alloc.allocate(__n * sizeof(_Tp))) + : 0; + } + + // __p is not permitted to be a null pointer. + void deallocate(pointer __p, size_type __n) + { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); } + + size_type max_size() const __STL_NOTHROW + { return size_t(-1) / sizeof(_Tp); } + + void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); } + void destroy(pointer __p) { __p->~_Tp(); } +}; + +template +class __allocator { + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; + typedef void value_type; + + template struct rebind { + typedef __allocator<_Tp1, _Alloc> other; + }; +}; + +template +inline bool operator==(const __allocator<_Tp, _Alloc>& __a1, + const __allocator<_Tp, _Alloc>& __a2) +{ + return __a1.__underlying_alloc == __a2.__underlying_alloc; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template +inline bool operator!=(const __allocator<_Tp, _Alloc>& __a1, + const __allocator<_Tp, _Alloc>& __a2) +{ + return __a1.__underlying_alloc != __a2.__underlying_alloc; +} +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// Comparison operators for all of the predifined SGI-style allocators. +// This ensures that __allocator (for example) will +// work correctly. + +template +inline bool operator==(const __malloc_alloc_template&, + const __malloc_alloc_template&) +{ + return true; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template +inline bool operator!=(const __malloc_alloc_template<__inst>&, + const __malloc_alloc_template<__inst>&) +{ + return false; +} +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template +inline bool operator==(const __default_alloc_template<__threads, __inst>&, + const __default_alloc_template<__threads, __inst>&) +{ + return true; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template +inline bool operator!=(const __default_alloc_template<__threads, __inst>&, + const __default_alloc_template<__threads, __inst>&) +{ + return false; +} +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template +inline bool operator==(const debug_alloc<_Alloc>&, + const debug_alloc<_Alloc>&) { + return true; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER +template +inline bool operator!=(const debug_alloc<_Alloc>&, + const debug_alloc<_Alloc>&) { + return false; +} +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +// Another allocator adaptor: _Alloc_traits. This serves two +// purposes. First, make it possible to write containers that can use +// either SGI-style allocators or standard-conforming allocator. +// Second, provide a mechanism so that containers can query whether or +// not the allocator has distinct instances. If not, the container +// can avoid wasting a word of memory to store an empty object. + +// This adaptor uses partial specialization. The general case of +// _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a +// standard-conforming allocator, possibly with non-equal instances +// and non-static members. (It still behaves correctly even if _Alloc +// has static member and if all instances are equal. Refinements +// affect performance, not correctness.) + +// There are always two members: allocator_type, which is a standard- +// conforming allocator type for allocating objects of type _Tp, and +// _S_instanceless, a static const member of type bool. If +// _S_instanceless is true, this means that there is no difference +// between any two instances of type allocator_type. Furthermore, if +// _S_instanceless is true, then _Alloc_traits has one additional +// member: _Alloc_type. This type encapsulates allocation and +// deallocation of objects of type _Tp through a static interface; it +// has two member functions, whose signatures are +// static _Tp* allocate(size_t) +// static void deallocate(_Tp*, size_t) + +// The fully general version. + +template +struct _Alloc_traits +{ + static const bool _S_instanceless = false; + typedef typename _Allocator::__STL_TEMPLATE rebind<_Tp>::other + allocator_type; +}; + +template +const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless; + +// The version for the default allocator. + +template +struct _Alloc_traits<_Tp, allocator<_Tp1> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, alloc> _Alloc_type; + typedef allocator<_Tp> allocator_type; +}; + +// Versions for the predefined SGI-style allocators. + +template +struct _Alloc_traits<_Tp, __malloc_alloc_template<__inst> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; + typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; +}; + +template +struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __default_alloc_template<__threads, __inst> > + _Alloc_type; + typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> > + allocator_type; +}; + +template +struct _Alloc_traits<_Tp, debug_alloc<_Alloc> > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, debug_alloc<_Alloc> > _Alloc_type; + typedef __allocator<_Tp, debug_alloc<_Alloc> > allocator_type; +}; + +// Versions for the __allocator adaptor used with the predefined +// SGI-style allocators. + +template +struct _Alloc_traits<_Tp, + __allocator<_Tp1, __malloc_alloc_template<__inst> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type; + typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type; +}; + +template +struct _Alloc_traits<_Tp, + __allocator<_Tp1, + __default_alloc_template<__thr, __inst> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, __default_alloc_template<__thr,__inst> > + _Alloc_type; + typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> > + allocator_type; +}; + +template +struct _Alloc_traits<_Tp, __allocator<_Tp1, debug_alloc<_Alloc> > > +{ + static const bool _S_instanceless = true; + typedef simple_alloc<_Tp, debug_alloc<_Alloc> > _Alloc_type; + typedef __allocator<_Tp, debug_alloc<_Alloc> > allocator_type; +}; + + +#endif /* __STL_USE_STD_ALLOCATORS */ + #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 #endif diff --git a/libstdc++/stl/stl_bvector.h b/libstdc++/stl/stl_bvector.h index 00fe500bfdf..0d0cdb6c828 100644 --- a/libstdc++/stl/stl_bvector.h +++ b/libstdc++/stl/stl_bvector.h @@ -37,212 +37,322 @@ static const int __WORD_BIT = int(CHAR_BIT*sizeof(unsigned int)); #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif -struct __bit_reference { - unsigned int* p; - unsigned int mask; - __bit_reference(unsigned int* x, unsigned int y) : p(x), mask(y) {} +struct _Bit_reference { + unsigned int* _M_p; + unsigned int _M_mask; + _Bit_reference(unsigned int* __x, unsigned int __y) + : _M_p(__x), _M_mask(__y) {} public: - __bit_reference() : p(0), mask(0) {} - operator bool() const { return !(!(*p & mask)); } - __bit_reference& operator=(bool x) { - if (x) - *p |= mask; - else - *p &= ~mask; + _Bit_reference() : _M_p(0), _M_mask(0) {} + operator bool() const { return !(!(*_M_p & _M_mask)); } + _Bit_reference& operator=(bool __x) + { + if (__x) *_M_p |= _M_mask; + else *_M_p &= ~_M_mask; return *this; } - __bit_reference& operator=(const __bit_reference& x) { return *this = bool(x); } - bool operator==(const __bit_reference& x) const { - return bool(*this) == bool(x); + _Bit_reference& operator=(const _Bit_reference& __x) + { return *this = bool(__x); } + bool operator==(const _Bit_reference& __x) const + { return bool(*this) == bool(__x); } + bool operator<(const _Bit_reference& __x) const { + return !bool(*this) && bool(__x); } - bool operator<(const __bit_reference& x) const { - return bool(*this) < bool(x); - } - void flip() { *p ^= mask; } + void flip() { *_M_p ^= _M_mask; } }; -inline void swap(__bit_reference x, __bit_reference y) { - bool tmp = x; - x = y; - y = tmp; +inline void swap(_Bit_reference __x, _Bit_reference __y) +{ + bool __tmp = __x; + __x = __y; + __y = __tmp; } -struct __bit_iterator : public random_access_iterator { - typedef __bit_reference reference; - typedef __bit_reference* pointer; - typedef __bit_iterator iterator; +struct _Bit_iterator : public random_access_iterator { + typedef _Bit_reference reference; + typedef _Bit_reference* pointer; + typedef _Bit_iterator iterator; - unsigned int* p; - unsigned int offset; + unsigned int* _M_p; + unsigned int _M_offset; void bump_up() { - if (offset++ == __WORD_BIT - 1) { - offset = 0; - ++p; + if (_M_offset++ == __WORD_BIT - 1) { + _M_offset = 0; + ++_M_p; } } void bump_down() { - if (offset-- == 0) { - offset = __WORD_BIT - 1; - --p; + if (_M_offset-- == 0) { + _M_offset = __WORD_BIT - 1; + --_M_p; } } - __bit_iterator() : p(0), offset(0) {} - __bit_iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {} - reference operator*() const { return reference(p, 1U << offset); } + _Bit_iterator() : _M_p(0), _M_offset(0) {} + _Bit_iterator(unsigned int* __x, unsigned int __y) + : _M_p(__x), _M_offset(__y) {} + reference operator*() const { return reference(_M_p, 1U << _M_offset); } iterator& operator++() { bump_up(); return *this; } iterator operator++(int) { - iterator tmp = *this; + iterator __tmp = *this; bump_up(); - return tmp; + return __tmp; } iterator& operator--() { bump_down(); return *this; } iterator operator--(int) { - iterator tmp = *this; + iterator __tmp = *this; bump_down(); - return tmp; - } - iterator& operator+=(difference_type i) { - difference_type n = i + offset; - p += n / __WORD_BIT; - n = n % __WORD_BIT; - if (n < 0) { - offset = (unsigned int) n + __WORD_BIT; - --p; + return __tmp; + } + iterator& operator+=(difference_type __i) { + difference_type __n = __i + _M_offset; + _M_p += __n / __WORD_BIT; + __n = __n % __WORD_BIT; + if (__n < 0) { + _M_offset = (unsigned int) __n + __WORD_BIT; + --_M_p; } else - offset = (unsigned int) n; + _M_offset = (unsigned int) __n; return *this; } - iterator& operator-=(difference_type i) { - *this += -i; + 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; } - 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; + difference_type operator-(iterator __x) const { + return __WORD_BIT * (_M_p - __x._M_p) + _M_offset - __x._M_offset; } - reference operator[](difference_type i) { return *(*this + i); } - bool operator==(const iterator& x) const { - return p == x.p && offset == x.offset; + reference operator[](difference_type __i) { return *(*this + __i); } + bool operator==(const iterator& __x) const { + return _M_p == __x._M_p && _M_offset == __x._M_offset; } - bool operator!=(const iterator& x) const { - return p != x.p || offset != x.offset; + bool operator!=(const iterator& __x) const { + return _M_p != __x._M_p || _M_offset != __x._M_offset; } - bool operator<(iterator x) const { - return p < x.p || (p == x.p && offset < x.offset); + bool operator<(iterator __x) const { + return _M_p < __x._M_p || (_M_p == __x._M_p && _M_offset < __x._M_offset); } }; -struct __bit_const_iterator +struct _Bit_const_iterator : public random_access_iterator { typedef bool reference; typedef bool const_reference; typedef const bool* pointer; - typedef __bit_const_iterator const_iterator; + typedef _Bit_const_iterator const_iterator; - unsigned int* p; - unsigned int offset; + unsigned int* _M_p; + unsigned int _M_offset; void bump_up() { - if (offset++ == __WORD_BIT - 1) { - offset = 0; - ++p; + if (_M_offset++ == __WORD_BIT - 1) { + _M_offset = 0; + ++_M_p; } } void bump_down() { - if (offset-- == 0) { - offset = __WORD_BIT - 1; - --p; + if (_M_offset-- == 0) { + _M_offset = __WORD_BIT - 1; + --_M_p; } } - __bit_const_iterator() : p(0), offset(0) {} - __bit_const_iterator(unsigned int* x, unsigned int y) : p(x), offset(y) {} - __bit_const_iterator(const __bit_iterator& x) : p(x.p), offset(x.offset) {} + _Bit_const_iterator() : _M_p(0), _M_offset(0) {} + _Bit_const_iterator(unsigned int* __x, unsigned int __y) + : _M_p(__x), _M_offset(__y) {} + _Bit_const_iterator(const _Bit_iterator& __x) + : _M_p(__x._M_p), _M_offset(__x._M_offset) {} const_reference operator*() const { - return __bit_reference(p, 1U << offset); + return _Bit_reference(_M_p, 1U << _M_offset); } const_iterator& operator++() { bump_up(); return *this; } const_iterator operator++(int) { - const_iterator tmp = *this; + const_iterator __tmp = *this; bump_up(); - return tmp; + return __tmp; } const_iterator& operator--() { bump_down(); return *this; } const_iterator operator--(int) { - const_iterator tmp = *this; + const_iterator __tmp = *this; bump_down(); - return tmp; - } - const_iterator& operator+=(difference_type i) { - difference_type n = i + offset; - p += n / __WORD_BIT; - n = n % __WORD_BIT; - if (n < 0) { - offset = (unsigned int) n + __WORD_BIT; - --p; + return __tmp; + } + const_iterator& operator+=(difference_type __i) { + difference_type __n = __i + _M_offset; + _M_p += __n / __WORD_BIT; + __n = __n % __WORD_BIT; + if (__n < 0) { + _M_offset = (unsigned int) __n + __WORD_BIT; + --_M_p; } else - offset = (unsigned int) n; + _M_offset = (unsigned int) __n; return *this; } - const_iterator& operator-=(difference_type i) { - *this += -i; + 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; } - 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; + difference_type operator-(const_iterator __x) const { + return __WORD_BIT * (_M_p - __x._M_p) + _M_offset - __x._M_offset; } - const_reference operator[](difference_type i) { - return *(*this + i); + 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 _M_p == __x._M_p && _M_offset == __x._M_offset; } - bool operator!=(const const_iterator& x) const { - return p != x.p || offset != x.offset; + bool operator!=(const const_iterator& __x) const { + return _M_p != __x._M_p || _M_offset != __x._M_offset; } - bool operator<(const_iterator x) const { - return p < x.p || (p == x.p && offset < x.offset); + bool operator<(const_iterator __x) const { + return _M_p < __x._M_p || (_M_p == __x._M_p && _M_offset < __x._M_offset); } }; +// Bit-vector base class, which encapsulates the difference between +// old SGI-style allocators and standard-conforming allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template +class _Bvector_alloc_base { +public: + typedef typename _Alloc_traits::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + + _Bvector_alloc_base(const allocator_type& __a) + : _M_data_allocator(__a), _M_start(), _M_finish(), _M_end_of_storage(0) {} + +protected: + unsigned int* _M_bit_alloc(size_t __n) + { return _M_data_allocator.allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } + void _M_deallocate() { + if (_M_start._M_p) + _M_data_allocator.deallocate(_M_start._M_p, + _M_end_of_storage - _M_start._M_p); + } + + typename _Alloc_traits::allocator_type + _M_data_allocator; + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + unsigned int* _M_end_of_storage; +}; + +// Specialization for instanceless allocators. +template +class _Bvector_alloc_base<_Allocator, true> { +public: + typedef typename _Alloc_traits::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Bvector_alloc_base(const allocator_type&) + : _M_start(), _M_finish(), _M_end_of_storage(0) {} + +protected: + typedef typename _Alloc_traits::_Alloc_type + _Alloc_type; + + unsigned int* _M_bit_alloc(size_t __n) + { return _Alloc_type::allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } + void _M_deallocate() { + if (_M_start._M_p) + _Alloc_type::deallocate(_M_start._M_p, + _M_end_of_storage - _M_start._M_p); + } + + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + unsigned int* _M_end_of_storage; +}; + +template +class _Bvector_base + : public _Bvector_alloc_base<_Alloc, + _Alloc_traits::_S_instanceless> +{ + typedef _Bvector_alloc_base<_Alloc, + _Alloc_traits::_S_instanceless> + _Base; +public: + typedef typename _Base::allocator_type allocator_type; + + _Bvector_base(const allocator_type& __a) : _Base(__a) {} + ~_Bvector_base() { _Base::_M_deallocate(); } +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +class _Bvector_base +{ +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Bvector_base(const allocator_type&) + : _M_start(), _M_finish(), _M_end_of_storage(0) {} + ~_Bvector_base() { _M_deallocate(); } + +protected: + typedef simple_alloc _Alloc_type; + + unsigned int* _M_bit_alloc(size_t __n) + { return _Alloc_type::allocate((__n + __WORD_BIT - 1)/__WORD_BIT); } + void _M_deallocate() { + if (_M_start._M_p) + _Alloc_type::deallocate(_M_start._M_p, + _M_end_of_storage - _M_start._M_p); + } + + _Bit_iterator _M_start; + _Bit_iterator _M_finish; + unsigned int* _M_end_of_storage; +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + // The next few lines are confusing. What we're doing is declaring a // partial specialization of vector if we have the necessary // compiler support. Otherwise, we define a class bit_vector which uses -// the default allocator. In either case, we typedef "data_allocator" -// appropriately. +// the default allocator. -#if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && !defined(__STL_NEED_BOOL) +#if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && !defined(__STL_NO_BOOL) #define __SGI_STL_VECBOOL_TEMPLATE #define __BVECTOR vector #else @@ -254,27 +364,29 @@ struct __bit_const_iterator __STL_END_NAMESPACE # include __STL_BEGIN_NAMESPACE -template class vector +template class vector + : public _Bvector_base<_Alloc> # else /* __SGI_STL_VECBOOL_TEMPLATE */ class bit_vector + : public _Bvector_base<__STL_DEFAULT_ALLOCATOR(bool) > # endif /* __SGI_STL_VECBOOL_TEMPLATE */ { # ifdef __SGI_STL_VECBOOL_TEMPLATE - typedef simple_alloc data_allocator; + typedef _Bvector_base<_Alloc> _Base; # else /* __SGI_STL_VECBOOL_TEMPLATE */ - typedef simple_alloc data_allocator; + typedef _Bvector_base<__STL_DEFAULT_ALLOCATOR(bool) > _Base; # endif /* __SGI_STL_VECBOOL_TEMPLATE */ public: typedef bool value_type; typedef size_t size_type; typedef ptrdiff_t difference_type; - typedef __bit_reference reference; + typedef _Bit_reference reference; typedef bool const_reference; - typedef __bit_reference* pointer; + typedef _Bit_reference* pointer; typedef const bool* const_pointer; - typedef __bit_iterator iterator; - typedef __bit_const_iterator const_iterator; + typedef _Bit_iterator iterator; + typedef _Bit_const_iterator const_iterator; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; @@ -286,92 +398,94 @@ public: reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + +protected: +#ifdef __STL_USE_NAMESPACES + using _Base::_M_bit_alloc; + using _Base::_M_deallocate; + using _Base::_M_start; + using _Base::_M_finish; + using _Base::_M_end_of_storage; +#endif /* __STL_USE_NAMESPACES */ + protected: - iterator start; - iterator finish; - unsigned int* end_of_storage; - unsigned int* bit_alloc(size_type n) { - return data_allocator::allocate((n + __WORD_BIT - 1)/__WORD_BIT); - } - void deallocate() { - if (start.p) - data_allocator::deallocate(start.p, end_of_storage - start.p); - } - void initialize(size_type n) { - unsigned int* q = bit_alloc(n); - end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT; - start = iterator(q, 0); - finish = start + difference_type(n); - } - void insert_aux(iterator position, bool x) { - if (finish.p != end_of_storage) { - copy_backward(position, finish, finish + 1); - *position = x; - ++finish; + void _M_initialize(size_type __n) { + unsigned int* __q = _M_bit_alloc(__n); + _M_end_of_storage = __q + (__n + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); + _M_finish = _M_start + difference_type(__n); + } + void _M_insert_aux(iterator __position, bool __x) { + if (_M_finish._M_p != _M_end_of_storage) { + copy_backward(__position, _M_finish, _M_finish + 1); + *__position = __x; + ++_M_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); + size_type __len = size() ? 2 * size() : __WORD_BIT; + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + *__i++ = __x; + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); } } #ifdef __STL_MEMBER_TEMPLATES - template - void initialize_range(InputIterator first, InputIterator last, - input_iterator_tag) { - start = iterator(); - finish = iterator(); - end_of_storage = 0; - for ( ; first != last; ++first) - push_back(*first); - } - - template - void initialize_range(ForwardIterator first, ForwardIterator last, - forward_iterator_tag) { - size_type n = 0; - distance(first, last, n); - initialize(n); - copy(first, last, start); - } - - template - void insert_range(iterator pos, - InputIterator first, InputIterator last, - input_iterator_tag) { - for ( ; first != last; ++first) { - pos = insert(pos, *first); - ++pos; + template + void _M_initialize_range(_InputIterator __first, _InputIterator __last, + input_iterator_tag) { + _M_start = iterator(); + _M_finish = iterator(); + _M_end_of_storage = 0; + for ( ; __first != __last; ++__first) + push_back(*__first); + } + + template + void _M_initialize_range(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize(__n); + copy(__first, __last, _M_start); + } + + template + void _M_insert_range(iterator __pos, + _InputIterator __first, _InputIterator __last, + input_iterator_tag) { + for ( ; __first != __last; ++__first) { + __pos = insert(__pos, *__first); + ++__pos; } } - template - void insert_range(iterator position, - ForwardIterator first, ForwardIterator last, - forward_iterator_tag) { - if (first != last) { - size_type n = 0; - distance(first, last, n); - if (capacity() - size() >= n) { - copy_backward(position, end(), finish + difference_type(n)); - copy(first, last, position); - finish += difference_type(n); + template + void _M_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(), _M_finish + difference_type(__n)); + copy(__first, __last, __position); + _M_finish += difference_type(__n); } else { - size_type len = size() + max(size(), n); - unsigned int* q = bit_alloc(len); - iterator i = copy(begin(), position, iterator(q, 0)); - i = copy(first, last, i); - finish = copy(position, end(), i); - deallocate(); - end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; - start = iterator(q, 0); + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + __i = copy(__first, __last, __i); + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); } } } @@ -379,10 +493,10 @@ protected: #endif /* __STL_MEMBER_TEMPLATES */ public: - iterator begin() { return start; } - const_iterator begin() const { return start; } - iterator end() { return finish; } - const_iterator end() const { return finish; } + iterator begin() { return _M_start; } + const_iterator begin() const { return _M_start; } + iterator end() { return _M_finish; } + const_iterator end() const { return _M_finish; } reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { @@ -396,190 +510,291 @@ public: 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()); + return size_type(const_iterator(_M_end_of_storage, 0) - begin()); } bool empty() const { return begin() == end(); } - reference operator[](size_type n) { - return *(begin() + difference_type(n)); - } - const_reference operator[](size_type n) const { - return *(begin() + difference_type(n)); + reference operator[](size_type __n) { + return *(begin() + difference_type(__n)); } - __BVECTOR() : start(iterator()), finish(iterator()), end_of_storage(0) {} - __BVECTOR(size_type n, bool value) { - initialize(n); - fill(start.p, end_of_storage, value ? ~0 : 0); + const_reference operator[](size_type __n) const { + return *(begin() + difference_type(__n)); } - __BVECTOR(int n, bool value) { - initialize(n); - fill(start.p, end_of_storage, value ? ~0 : 0); - } - __BVECTOR(long n, bool value) { - initialize(n); - fill(start.p, end_of_storage, value ? ~0 : 0); + + explicit __BVECTOR(const allocator_type& __a = allocator_type()) + : _Base(__a) {} + + __BVECTOR(size_type __n, bool __value, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _M_initialize(__n); + fill(_M_start._M_p, _M_end_of_storage, __value ? ~0 : 0); } - explicit __BVECTOR(size_type n) { - initialize(n); - fill(start.p, end_of_storage, 0); + + explicit __BVECTOR(size_type __n) + : _Base(allocator_type()) + { + _M_initialize(__n); + fill(_M_start._M_p, _M_end_of_storage, 0); } - __BVECTOR(const __BVECTOR& x) { - initialize(x.size()); - copy(x.begin(), x.end(), start); + + __BVECTOR(const __BVECTOR& __x) : _Base(__x.get_allocator()) { + _M_initialize(__x.size()); + copy(__x.begin(), __x.end(), _M_start); } #ifdef __STL_MEMBER_TEMPLATES - template - __BVECTOR(InputIterator first, InputIterator last) { - initialize_range(first, last, iterator_category(first)); + // Check whether it's an integral type. If so, it's not an iterator. + template + __BVECTOR(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + template + void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { + _M_initialize(__n); + fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0); + } + + template + void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) { + _M_initialize_range(__first, __last, __ITERATOR_CATEGORY(__first)); } #else /* __STL_MEMBER_TEMPLATES */ - __BVECTOR(const_iterator first, const_iterator last) { - size_type n = 0; - distance(first, last, n); - initialize(n); - copy(first, last, start); - } - __BVECTOR(const bool* first, const bool* last) { - size_type n = 0; - distance(first, last, n); - initialize(n); - copy(first, last, start); + __BVECTOR(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize(__n); + copy(__first, __last, _M_start); + } + __BVECTOR(const bool* __first, const bool* __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize(__n); + copy(__first, __last, _M_start); } #endif /* __STL_MEMBER_TEMPLATES */ - ~__BVECTOR() { deallocate(); } - __BVECTOR& operator=(const __BVECTOR& x) { - if (&x == this) return *this; - if (x.size() > capacity()) { - deallocate(); - initialize(x.size()); + ~__BVECTOR() { } + + __BVECTOR& operator=(const __BVECTOR& __x) { + if (&__x == this) return *this; + if (__x.size() > capacity()) { + _M_deallocate(); + _M_initialize(__x.size()); } - copy(x.begin(), x.end(), begin()); - finish = begin() + difference_type(x.size()); + copy(__x.begin(), __x.end(), begin()); + _M_finish = begin() + difference_type(__x.size()); return *this; } - void reserve(size_type n) { - if (capacity() < n) { - unsigned int* q = bit_alloc(n); - finish = copy(begin(), end(), iterator(q, 0)); - deallocate(); - start = iterator(q, 0); - end_of_storage = q + (n + __WORD_BIT - 1)/__WORD_BIT; + + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void assign(size_t __n, bool __x) { + if (__n > size()) { + fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0); + insert(end(), __n - size(), __x); + } + else { + erase(begin() + __n, end()); + fill(_M_start._M_p, _M_end_of_storage, __x ? ~0 : 0); } } + +#ifdef __STL_MEMBER_TEMPLATES + + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { assign((size_t) __n, (bool) __val); } + + template + void _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) + { _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } + + template + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag) { + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); + } + + template + void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + size_type __len = 0; + distance(__first, __last, __len); + if (__len < size()) + erase(copy(__first, __last, begin()), end()); + else { + _ForwardIterator __mid = __first; + advance(__mid, size()); + copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + } + +#endif /* __STL_MEMBER_TEMPLATES */ + + void reserve(size_type __n) { + if (capacity() < __n) { + unsigned int* __q = _M_bit_alloc(__n); + _M_finish = copy(begin(), end(), iterator(__q, 0)); + _M_deallocate(); + _M_start = iterator(__q, 0); + _M_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; + void push_back(bool __x) { + if (_M_finish._M_p != _M_end_of_storage) + *_M_finish++ = __x; else - insert_aux(end(), x); + _M_insert_aux(end(), __x); } - void swap(__BVECTOR& x) { - __STD::swap(start, x.start); - __STD::swap(finish, x.finish); - __STD::swap(end_of_storage, x.end_of_storage); + void swap(__BVECTOR& __x) { + __STD::swap(_M_start, __x._M_start); + __STD::swap(_M_finish, __x._M_finish); + __STD::swap(_M_end_of_storage, __x._M_end_of_storage); } - iterator insert(iterator position, bool x = bool()) { - difference_type n = position - begin(); - if (finish.p != end_of_storage && position == end()) - *finish++ = x; + iterator insert(iterator __position, bool __x = bool()) { + difference_type __n = __position - begin(); + if (_M_finish._M_p != _M_end_of_storage && __position == end()) + *_M_finish++ = __x; else - insert_aux(position, x); - return begin() + n; + _M_insert_aux(__position, __x); + return begin() + __n; } #ifdef __STL_MEMBER_TEMPLATES - template void insert(iterator position, - InputIterator first, - InputIterator last) { - insert_range(position, first, last, iterator_category(first)); + // Check whether it's an integral type. If so, it's not an iterator. + template + void insert(iterator __position, + _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + template + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) { + insert(__pos, (size_type) __n, (bool) __x); + } + + template + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) { + _M_insert_range(__pos, __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; + 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(), _M_finish + __n); + copy(__first, __last, __position); + _M_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); + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + __i = copy(__first, __last, __i); + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_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; + 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(), _M_finish + __n); + copy(__first, __last, __position); + _M_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); + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + __i = copy(__first, __last, __i); + _M_finish = copy(__position, end(), __i); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_start = iterator(__q, 0); } } #endif /* __STL_MEMBER_TEMPLATES */ - void insert(iterator position, size_type n, bool x) { - if (n == 0) return; - if (capacity() - size() >= n) { - copy_backward(position, end(), finish + difference_type(n)); - fill(position, position + difference_type(n), x); - finish += difference_type(n); + void insert(iterator __position, size_type __n, bool __x) { + if (__n == 0) return; + if (capacity() - size() >= __n) { + copy_backward(__position, end(), _M_finish + difference_type(__n)); + fill(__position, __position + difference_type(__n), __x); + _M_finish += difference_type(__n); } else { - size_type len = size() + max(size(), n); - unsigned int* q = bit_alloc(len); - iterator i = copy(begin(), position, iterator(q, 0)); - fill_n(i, n, x); - finish = copy(position, end(), i + difference_type(n)); - deallocate(); - end_of_storage = q + (len + __WORD_BIT - 1)/__WORD_BIT; - start = iterator(q, 0); + size_type __len = size() + max(size(), __n); + unsigned int* __q = _M_bit_alloc(__len); + iterator __i = copy(begin(), __position, iterator(__q, 0)); + fill_n(__i, __n, __x); + _M_finish = copy(__position, end(), __i + difference_type(__n)); + _M_deallocate(); + _M_end_of_storage = __q + (__len + __WORD_BIT - 1)/__WORD_BIT; + _M_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; } - iterator erase(iterator position) { - if (position + 1 != end()) - copy(position + 1, end(), position); - --finish; - return position; + void pop_back() { --_M_finish; } + iterator erase(iterator __position) { + if (__position + 1 != end()) + copy(__position + 1, end(), __position); + --_M_finish; + return __position; } - iterator erase(iterator first, iterator last) { - finish = copy(last, end(), first); - return first; + iterator erase(iterator __first, iterator __last) { + _M_finish = copy(__last, end(), __first); + return __first; } - void resize(size_type new_size, bool x = bool()) { - if (new_size < size()) - erase(begin() + difference_type(new_size), end()); + void resize(size_type __new_size, bool __x = bool()) { + if (__new_size < size()) + erase(begin() + difference_type(__new_size), end()); else - insert(end(), new_size - size(), x); + insert(end(), __new_size - size(), __x); } void clear() { erase(begin(), end()); } }; @@ -590,12 +805,18 @@ typedef vector bit_vector; #else /* __SGI_STL_VECBOOL_TEMPLATE */ -inline bool operator==(const bit_vector& x, const bit_vector& y) { - return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); +inline bool +operator==(const bit_vector& __x, const bit_vector& __y) +{ + return (__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 bool +operator<(const bit_vector& __x, const bit_vector& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } #endif /* __SGI_STL_VECBOOL_TEMPLATE */ @@ -605,6 +826,7 @@ inline bool operator<(const bit_vector& x, const bit_vector& y) { #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/libstdc++/stl/stl_config.h b/libstdc++/stl/stl_config.h index 2a96568ebbd..b1b5738d3a4 100644 --- a/libstdc++/stl/stl_config.h +++ b/libstdc++/stl/stl_config.h @@ -27,49 +27,75 @@ #ifndef __STL_CONFIG_H # 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 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. -// (13) Defines __STL_USE_EXCEPTIONS if the compiler (in the current -// compilation mode) supports exceptions. -// (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. -// (16) Defines __STL_WIN32THREADS if this is being compiled on a -// WIN32 compiler in multithreaded mode. -// (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. +// Flags: +// * __STL_NO_BOOL: defined if the compiler doesn't have bool as a builtin +// type. +// * __STL_HAS_WCHAR_T: defined if the compier has wchar_t as a builtin type. +// * __STL_NO_DRAND48: defined if the compiler doesn't have the drand48 +// function. +// * __STL_STATIC_TEMPLATE_MEMBER_BUG: defined if the compiler can't handle +// static members of template classes. +// * __STL_CLASS_PARTIAL_SPECIALIZATION: defined if the compiler supports +// partial specialization of template classes. +// * __STL_PARTIAL_SPECIALIZATION_SYNTAX: defined if the compiler +// supports partial specialization syntax for full specialization of +// class templates. (Even if it doesn't actually support partial +// specialization itself.) +// * __STL_FUNCTION_TMPL_PARTIAL_ORDER: defined if the compiler supports +// partial ordering of function templates. (a.k.a partial specialization +// of function templates.) +// * __STL_MEMBER_TEMPLATES: defined if the compiler supports template +// member functions of classes. +// * __STL_MEMBER_TEMPLATE_CLASSES: defined if the compiler supports +// nested classes that are member templates of other classes. +// * __STL_EXPLICIT_FUNCTION_TMPL_ARGS: defined if the compiler +// supports calling a function template by providing its template +// arguments explicitly. +// * __STL_LIMITED_DEFAULT_TEMPLATES: defined if the compiler is unable +// to handle default template parameters that depend on previous template +// parameters. +// * __STL_NON_TYPE_TMPL_PARAM_BUG: defined if the compiler has trouble with +// function template argument deduction for non-type template parameters. +// * __SGI_STL_NO_ARROW_OPERATOR: defined if the compiler is unable +// to support the -> operator for iterators. +// * __STL_USE_EXCEPTIONS: defined if the compiler (in the current compilation +// mode) supports exceptions. +// * __STL_USE_NAMESPACES: defined if the compiler has the necessary +// support for namespaces. +// * __STL_NO_EXCEPTION_HEADER: defined if the compiler does not have a +// standard-conforming header . +// * __STL_SGI_THREADS: defined if this is being compiled for an SGI IRIX +// system in multithreaded mode, using native SGI threads instead of +// pthreads. +// * __STL_WIN32THREADS: defined if this is being compiled on a WIN32 +// compiler in multithreaded mode. +// * __STL_LONG_LONG if the compiler has long long and unsigned long long +// types. (They're not in the C++ standard, but they are expected to be +// included in the forthcoming C9X standard.) + + +// User-settable macros that control compilation: +// * __STL_USE_SGI_ALLOCATORS: if defined, then the STL will use older +// SGI-style allocators, instead of standard-conforming allocators, +// even if the compiler supports all of the language features needed +// for standard-conforming allocators. +// * __STL_NO_NAMESPACES: if defined, don't put the library in namespace +// std, even if the compiler supports namespaces. +// * __STL_ASSERTIONS: if defined, then enable runtime checking through the +// __stl_assert macro. +// * _PTHREADS: if defined, use Posix threads for multithreading support. +// * _NOTHREADS: if defined, don't use any multithreading support. + + +// Other macros defined by this file: + +// * bool, true, and false, if __STL_NO_BOOL is defined. +// * typename, as a null macro if it's not already a keyword. +// * explicit, as a null macro if it's not already a keyword. +// * namespace-related macros (__STD, __STL_BEGIN_NAMESPACE, etc.) +// * exception-related macros (__STL_TRY, __STL_UNWIND, etc.) +// * __stl_assert, either as a test or as a null macro, depending on +// whether or not __STL_ASSERTIONS is defined. #ifdef _PTHREADS # define __STL_PTHREADS @@ -77,7 +103,10 @@ # if defined(__sgi) && !defined(__GNUC__) # if !defined(_BOOL) -# define __STL_NEED_BOOL +# define __STL_NO_BOOL +# endif +# if defined(_WCHAR_T_IS_KEYWORD) +# define __STL_HAS_WCHAR_T # endif # if !defined(_TYPENAME_IS_KEYWORD) # define __STL_NEED_TYPENAME @@ -87,6 +116,13 @@ # endif # ifdef _MEMBER_TEMPLATES # define __STL_MEMBER_TEMPLATES +# define __STL_MEMBER_TEMPLATE_CLASSES +# endif +# if defined(_MEMBER_TEMPLATE_KEYWORD) +# define __STL_MEMBER_TEMPLATE_KEYWORD +# endif +# if (_COMPILER_VERSION >= 730) && defined(_MIPS_SIM) && _MIPS_SIM != _ABIO32 +# define __STL_MEMBER_TEMPLATE_KEYWORD # endif # if !defined(_EXPLICIT_IS_KEYWORD) # define __STL_NEED_EXPLICIT @@ -95,11 +131,17 @@ # define __STL_USE_EXCEPTIONS # endif # if (_COMPILER_VERSION >= 721) && defined(_NAMESPACES) -# define __STL_USE_NAMESPACES +# define __STL_HAS_NAMESPACES # endif +# if (_COMPILER_VERSION < 721) +# define __STL_NO_EXCEPTION_HEADER +# endif # if !defined(_NOTHREADS) && !defined(__STL_PTHREADS) # define __STL_SGI_THREADS # endif +# if defined(_LONGLONG) && defined(_SGIAPI) && _SGIAPI +# define __STL_LONG_LONG +# endif # endif # ifdef __GNUC__ @@ -113,6 +155,8 @@ # define __STL_FUNCTION_TMPL_PARTIAL_ORDER # define __STL_EXPLICIT_FUNCTION_TMPL_ARGS # define __STL_MEMBER_TEMPLATES + // g++ 2.8.1 supports member template functions, but not member + // template nested classes. # endif /* glibc pre 2.0 is very buggy. We have to disable thread for it. It should be upgraded to glibc 2.0 or later. */ @@ -129,7 +173,7 @@ # endif # if defined(__SUNPRO_CC) -# define __STL_NEED_BOOL +# define __STL_NO_BOOL # define __STL_NEED_TYPENAME # define __STL_NEED_EXPLICIT # define __STL_USE_EXCEPTIONS @@ -137,21 +181,22 @@ # if defined(__COMO__) # define __STL_MEMBER_TEMPLATES +# define __STL_MEMBER_TEMPLATE_CLASSES # define __STL_CLASS_PARTIAL_SPECIALIZATION # define __STL_USE_EXCEPTIONS -# define __STL_USE_NAMESPACES +# define __STL_HAS_NAMESPACES # endif # if defined(_MSC_VER) -# if _MSC_VER > 1000 -# include -# else -# define __STL_NEED_BOOL -# endif # define __STL_NO_DRAND48 # define __STL_NEED_TYPENAME -# if _MSC_VER < 1100 +# if _MSC_VER < 1100 /* 1000 is version 4.0, 1100 is 5.0, 1200 is 6.0. */ # define __STL_NEED_EXPLICIT +# define __STL_NO_BOOL +# if _MSC_VER > 1000 +# include +# define __STL_DONT_USE_BOOL_TYPEDEF +# endif # endif # define __STL_NON_TYPE_TMPL_PARAM_BUG # define __SGI_STL_NO_ARROW_OPERATOR @@ -161,6 +206,11 @@ # ifdef _MT # define __STL_WIN32THREADS # endif +# if _MSC_VER >= 1200 +# define __STL_PARTIAL_SPECIALIZATION_SYNTAX +# define __STL_HAS_NAMESPACES +# define __STL_NO_NAMESPACES +# endif # endif # if defined(__BORLANDC__) @@ -177,8 +227,7 @@ # endif # endif - -# if defined(__STL_NEED_BOOL) +# if defined(__STL_NO_BOOL) && !defined(__STL_DONT_USE_BOOL_TYPEDEF) typedef int bool; # define true 1 # define false 0 @@ -188,6 +237,12 @@ # define typename # endif +# ifdef __STL_MEMBER_TEMPLATE_KEYWORD +# define __STL_TEMPLATE template +# else +# define __STL_TEMPLATE +# endif + # ifdef __STL_NEED_EXPLICIT # define explicit # endif @@ -198,22 +253,46 @@ # define __STL_NULL_TMPL_ARGS # endif -# ifdef __STL_CLASS_PARTIAL_SPECIALIZATION +# if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) \ + || defined (__STL_PARTIAL_SPECIALIZATION_SYNTAX) # define __STL_TEMPLATE_NULL template<> # else # define __STL_TEMPLATE_NULL # endif +// Use standard-conforming allocators if we have the necessary language +// features. __STL_USE_SGI_ALLOCATORS is a hook so that users can +// disable new-style allocators, and continue to use the same kind of +// allocators as before, without having to edit library headers. +# if defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && \ + defined(__STL_MEMBER_TEMPLATES) && \ + defined(__STL_MEMBER_TEMPLATE_CLASSES) && \ + !defined(__STL_NO_BOOL) && \ + !defined(__STL_NON_TYPE_TMPL_PARAM_BUG) && \ + !defined(__STL_LIMITED_DEFAULT_TEMPLATES) && \ + !defined(__STL_USE_SGI_ALLOCATORS) +# define __STL_USE_STD_ALLOCATORS +# endif + +# ifndef __STL_DEFAULT_ALLOCATOR +# ifdef __STL_USE_STD_ALLOCATORS +# define __STL_DEFAULT_ALLOCATOR(T) allocator +# else +# define __STL_DEFAULT_ALLOCATOR(T) alloc +# endif +# 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) +# if defined(__STL_HAS_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_USE_NAMESPACE_FOR_RELOPS # define __STL_BEGIN_RELOPS_NAMESPACE namespace std { # define __STL_END_RELOPS_NAMESPACE } # define __STD_RELOPS std +# define __STL_USE_NAMESPACES # else # define __STD # define __STL_BEGIN_NAMESPACE @@ -222,17 +301,20 @@ # define __STL_BEGIN_RELOPS_NAMESPACE # define __STL_END_RELOPS_NAMESPACE # define __STD_RELOPS +# undef __STL_USE_NAMESPACES # endif # ifdef __STL_USE_EXCEPTIONS # define __STL_TRY try # define __STL_CATCH_ALL catch(...) +# define __STL_THROW(x) throw x # 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_THROW(x) # define __STL_RETHROW # define __STL_NOTHROW # define __STL_UNWIND(action) diff --git a/libstdc++/stl/stl_construct.h b/libstdc++/stl/stl_construct.h index 46876353da6..0ce544c7eda 100644 --- a/libstdc++/stl/stl_construct.h +++ b/libstdc++/stl/stl_construct.h @@ -35,35 +35,47 @@ __STL_BEGIN_NAMESPACE -template -inline void destroy(T* pointer) { - pointer->~T(); +// construct and destroy. These functions are not part of the C++ standard, +// and are provided for backward compatibility with the HP STL. + +template +inline void destroy(_Tp* __pointer) { + __pointer->~_Tp(); +} + +template +inline void construct(_T1* __p, const _T2& __value) { + new (__p) _T1(__value); } -template -inline void construct(T1* p, const T2& value) { - new (p) T1(value); +template +inline void construct(_T1* __p) { + new (__p) _T1(); } -template +template inline void -__destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) { - for ( ; first < last; ++first) - destroy(&*first); +__destroy_aux(_ForwardIterator __first, _ForwardIterator __last, __false_type) +{ + for ( ; __first < __last; ++__first) + destroy(&*__first); } -template -inline void __destroy_aux(ForwardIterator, ForwardIterator, __true_type) {} +template +inline void __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) {} -template -inline void __destroy(ForwardIterator first, ForwardIterator last, T*) { - typedef typename __type_traits::has_trivial_destructor trivial_destructor; - __destroy_aux(first, last, trivial_destructor()); +template +inline void +__destroy(_ForwardIterator __first, _ForwardIterator __last, _Tp*) +{ + typedef typename __type_traits<_Tp>::has_trivial_destructor + _Trivial_destructor; + __destroy_aux(__first, __last, _Trivial_destructor()); } -template -inline void destroy(ForwardIterator first, ForwardIterator last) { - __destroy(first, last, value_type(first)); +template +inline void destroy(_ForwardIterator __first, _ForwardIterator __last) { + __destroy(__first, __last, __VALUE_TYPE(__first)); } inline void destroy(char*, char*) {} diff --git a/libstdc++/stl/stl_deque.h b/libstdc++/stl/stl_deque.h index 72325d5c61c..48a4c76d55a 100644 --- a/libstdc++/stl/stl_deque.h +++ b/libstdc++/stl/stl_deque.h @@ -53,8 +53,8 @@ * [map, map + map_size) is a valid, non-empty range. * [start.node, finish.node] is a valid range contained within * [map, map + map_size). - * A pointer in the range [map, map + map_size) points to an allocated - * node if and only if the pointer is in the range [start.node, finish.node]. + * A pointer in the range [map, map + map_size) points to an allocated node + * if and only if the pointer is in the range [start.node, finish.node]. */ @@ -83,126 +83,136 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif // Note: this function is simply a kludge to work around several compilers' // bugs in handling constant expressions. -inline size_t __deque_buf_size(size_t n, size_t sz) +inline size_t +__deque_buf_size(size_t __n, size_t __size) { - return n != 0 ? n : (sz < 512 ? size_t(512 / sz) : size_t(1)); + return __n != 0 ? __n : (__size < 512 ? size_t(512 / __size) : size_t(1)); } #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG -template -struct __deque_iterator { - typedef __deque_iterator iterator; - typedef __deque_iterator const_iterator; - static size_t buffer_size() {return __deque_buf_size(BufSiz, sizeof(T)); } +template +struct _Deque_iterator { + typedef _Deque_iterator<_Tp,_Tp&,_Tp*,__bufsiz> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*,__bufsiz> const_iterator; + static size_t + _S_buffer_size() { return __deque_buf_size(__bufsiz, sizeof(_Tp)); } #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ -template -struct __deque_iterator { - typedef __deque_iterator iterator; - typedef __deque_iterator const_iterator; - static size_t buffer_size() {return __deque_buf_size(0, sizeof(T)); } +template +struct _Deque_iterator { + typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + static size_t + _S_buffer_size() { return __deque_buf_size(0, sizeof(_Tp)); } #endif typedef random_access_iterator_tag iterator_category; - typedef T value_type; - typedef Ptr pointer; - typedef Ref reference; + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; typedef size_t size_type; typedef ptrdiff_t difference_type; - typedef T** map_pointer; + typedef _Tp** _Map_pointer; - typedef __deque_iterator self; + typedef _Deque_iterator _Self; - T* cur; - T* first; - T* last; - map_pointer node; + _Tp* _M_cur; + _Tp* _M_first; + _Tp* _M_last; + _Map_pointer _M_node; - __deque_iterator(T* x, map_pointer y) - : cur(x), first(*y), last(*y + buffer_size()), node(y) {} - __deque_iterator() : cur(0), first(0), last(0), node(0) {} - __deque_iterator(const iterator& x) - : cur(x.cur), first(x.first), last(x.last), node(x.node) {} + _Deque_iterator(_Tp* __x, _Map_pointer __y) + : _M_cur(__x), _M_first(*__y), + _M_last(*__y + _S_buffer_size()), _M_node(__y) {} + _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {} + _Deque_iterator(const iterator& __x) + : _M_cur(__x._M_cur), _M_first(__x._M_first), + _M_last(__x._M_last), _M_node(__x._M_node) {} - reference operator*() const { return *cur; } + reference operator*() const { return *_M_cur; } #ifndef __SGI_STL_NO_ARROW_OPERATOR - pointer operator->() const { return &(operator*()); } + pointer operator->() const { return _M_cur; } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ - difference_type operator-(const self& x) const { - return difference_type(buffer_size()) * (node - x.node - 1) + - (cur - first) + (x.last - x.cur); + difference_type operator-(const _Self& __x) const { + return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) + + (_M_cur - _M_first) + (__x._M_last - __x._M_cur); } - self& operator++() { - ++cur; - if (cur == last) { - set_node(node + 1); - cur = first; + _Self& operator++() { + ++_M_cur; + if (_M_cur == _M_last) { + _M_set_node(_M_node + 1); + _M_cur = _M_first; } return *this; } - self operator++(int) { - self tmp = *this; + _Self operator++(int) { + _Self __tmp = *this; ++*this; - return tmp; + return __tmp; } - self& operator--() { - if (cur == first) { - set_node(node - 1); - cur = last; + _Self& operator--() { + if (_M_cur == _M_first) { + _M_set_node(_M_node - 1); + _M_cur = _M_last; } - --cur; + --_M_cur; return *this; } - self operator--(int) { - self tmp = *this; + _Self operator--(int) { + _Self __tmp = *this; --*this; - return tmp; + return __tmp; } - self& operator+=(difference_type n) { - difference_type offset = n + (cur - first); - if (offset >= 0 && offset < difference_type(buffer_size())) - cur += n; + _Self& operator+=(difference_type __n) + { + difference_type __offset = __n + (_M_cur - _M_first); + if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) + _M_cur += __n; else { - difference_type node_offset = - offset > 0 ? offset / difference_type(buffer_size()) - : -difference_type((-offset - 1) / buffer_size()) - 1; - set_node(node + node_offset); - cur = first + (offset - node_offset * difference_type(buffer_size())); + difference_type __node_offset = + __offset > 0 ? __offset / difference_type(_S_buffer_size()) + : -difference_type((-__offset - 1) / _S_buffer_size()) - 1; + _M_set_node(_M_node + __node_offset); + _M_cur = _M_first + + (__offset - __node_offset * difference_type(_S_buffer_size())); } return *this; } - self operator+(difference_type n) const { - self tmp = *this; - return tmp += n; + _Self operator+(difference_type __n) const + { + _Self __tmp = *this; + return __tmp += __n; } - self& operator-=(difference_type n) { return *this += -n; } + _Self& operator-=(difference_type __n) { return *this += -__n; } - self operator-(difference_type n) const { - self tmp = *this; - return tmp -= n; + _Self operator-(difference_type __n) const { + _Self __tmp = *this; + return __tmp -= __n; } - reference operator[](difference_type n) const { return *(*this + n); } + reference operator[](difference_type __n) const { return *(*this + __n); } - bool operator==(const self& x) const { return cur == x.cur; } - bool operator!=(const self& x) const { return !(*this == x); } - bool operator<(const self& x) const { - return (node == x.node) ? (cur < x.cur) : (node < x.node); + bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; } + bool operator!=(const _Self& __x) const { return !(*this == __x); } + bool operator<(const _Self& __x) const { + return (_M_node == __x._M_node) ? + (_M_cur < __x._M_cur) : (_M_node < __x._M_node); } - void set_node(map_pointer new_node) { - node = new_node; - first = *new_node; - last = first + difference_type(buffer_size()); + void _M_set_node(_Map_pointer __new_node) { + _M_node = __new_node; + _M_first = *__new_node; + _M_last = _M_first + difference_type(_S_buffer_size()); } }; @@ -210,35 +220,40 @@ struct __deque_iterator { #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG -template +template inline random_access_iterator_tag -iterator_category(const __deque_iterator&) { +iterator_category(const _Deque_iterator<_Tp,_Ref,_Ptr,__bufsiz>&) { return random_access_iterator_tag(); } -template -inline T* value_type(const __deque_iterator&) { +template +inline _Tp* +value_type(const _Deque_iterator<_Tp,_Ref,_Ptr,__bufsiz>&) { return 0; } -template -inline ptrdiff_t* distance_type(const __deque_iterator&) { +template +inline ptrdiff_t* +distance_type(const _Deque_iterator<_Tp,_Ref,_Ptr,__bufsiz>&) { return 0; } #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ -template +template inline random_access_iterator_tag -iterator_category(const __deque_iterator&) { +iterator_category(const _Deque_iterator<_Tp,_Ref,_Ptr>&) +{ return random_access_iterator_tag(); } -template -inline T* value_type(const __deque_iterator&) { return 0; } +template +inline _Tp* +value_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) { return 0; } -template -inline ptrdiff_t* distance_type(const __deque_iterator&) { +template +inline ptrdiff_t* +distance_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) { return 0; } @@ -246,13 +261,226 @@ inline ptrdiff_t* distance_type(const __deque_iterator&) { #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ +// Deque base class. It has two purposes. First, its constructor +// and destructor allocate (but don't initialize) storage. This makes +// exception safety easier. Second, the base class encapsulates all of +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template +class _Deque_alloc_base { +public: + typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return node_allocator; } + + _Deque_alloc_base(const allocator_type& __a) + : node_allocator(__a), map_allocator(__a), _M_map(0), _M_map_size(0) + {} + +protected: + typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type + map_allocator_type; + + allocator_type node_allocator; + map_allocator_type map_allocator; + + _Tp* _M_allocate_node() { + return node_allocator.allocate(__deque_buf_size(__bufsiz,sizeof(_Tp))); + } + void _M_deallocate_node(_Tp* __p) { + node_allocator.deallocate(__p, __deque_buf_size(__bufsiz,sizeof(_Tp))); + } + _Tp** _M_allocate_map(size_t __n) + { return map_allocator.allocate(__n); } + void _M_deallocate_map(_Tp** __p, size_t __n) + { map_allocator.deallocate(__p, __n); } + + _Tp** _M_map; + size_t _M_map_size; +}; + +// Specialization for instanceless allocators. +template +class _Deque_alloc_base<_Tp, _Alloc, __bufsiz, true> +{ +public: + typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Deque_alloc_base(const allocator_type&) : _M_map(0), _M_map_size(0) {} + +protected: + typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Node_alloc_type; + typedef typename _Alloc_traits<_Tp*, _Alloc>::_Alloc_type _Map_alloc_type; + + _Tp* _M_allocate_node() + { return _Node_alloc_type::allocate(__deque_buf_size(__bufsiz, + sizeof(_Tp))); } + void _M_deallocate_node(_Tp* __p) + { _Node_alloc_type::deallocate(__p, __deque_buf_size(__bufsiz, + sizeof(_Tp))); } + _Tp** _M_allocate_map(size_t __n) + { return _Map_alloc_type::allocate(__n); } + void _M_deallocate_map(_Tp** __p, size_t __n) + { _Map_alloc_type::deallocate(__p, __n); } + + _Tp** _M_map; + size_t _M_map_size; +}; + +template +class _Deque_base + : public _Deque_alloc_base<_Tp,_Alloc,__bufsiz, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ +public: + typedef _Deque_alloc_base<_Tp,_Alloc,__bufsiz, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + typedef _Deque_iterator<_Tp,_Tp&,_Tp*,__bufsiz> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp&, __bufsiz> const_iterator; + + _Deque_base(const allocator_type& __a, size_t __num_elements) + : _Base(__a), _M_start(), _M_finish() + { _M_initialize_map(__num_elements); } + _Deque_base(const allocator_type& __a) + : _Base(__a), _M_start(), _M_finish() {} + ~_Deque_base(); + +protected: + void _M_initialize_map(size_t); + void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); + void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); + enum { _S_initial_map_size = 8 }; + +protected: + iterator _M_start; + iterator _M_finish; +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +class _Deque_base { +public: +#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG + typedef _Deque_iterator<_Tp,_Tp&,_Tp*,__bufsiz> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*, __bufsiz> const_iterator; +#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; +#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Deque_base(const allocator_type&, size_t __num_elements) + : _M_map(0), _M_map_size(0), _M_start(), _M_finish() { + _M_initialize_map(__num_elements); + } + _Deque_base(const allocator_type&) + : _M_map(0), _M_map_size(0), _M_start(), _M_finish() {} + ~_Deque_base(); + +protected: + void _M_initialize_map(size_t); + void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); + void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); + enum { _S_initial_map_size = 8 }; + +protected: + _Tp** _M_map; + size_t _M_map_size; + iterator _M_start; + iterator _M_finish; + + typedef simple_alloc<_Tp, _Alloc> _Node_alloc_type; + typedef simple_alloc<_Tp*, _Alloc> _Map_alloc_type; + + _Tp* _M_allocate_node() + { return _Node_alloc_type::allocate(__deque_buf_size(__bufsiz, + sizeof(_Tp))); } + void _M_deallocate_node(_Tp* __p) + { _Node_alloc_type::deallocate(__p, __deque_buf_size(__bufsiz, + sizeof(_Tp))); } + _Tp** _M_allocate_map(size_t __n) + { return _Map_alloc_type::allocate(__n); } + void _M_deallocate_map(_Tp** __p, size_t __n) + { _Map_alloc_type::deallocate(__p, __n); } +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +// Non-inline member functions from _Deque_base. + +template +_Deque_base<_Tp,_Alloc,__bufsiz>::~_Deque_base() { + if (_M_map) { + _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1); + _M_deallocate_map(_M_map, _M_map_size); + } +} + +template +void +_Deque_base<_Tp,_Alloc,__bufsiz>::_M_initialize_map(size_t __num_elements) +{ + size_t __num_nodes = + __num_elements / __deque_buf_size(__bufsiz, sizeof(_Tp)) + 1; + + _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2); + _M_map = _M_allocate_map(_M_map_size); + + _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2; + _Tp** __nfinish = __nstart + __num_nodes; + + __STL_TRY { + _M_create_nodes(__nstart, __nfinish); + } + __STL_UNWIND((_M_deallocate_map(_M_map, _M_map_size), + _M_map = 0, _M_map_size = 0)); + _M_start._M_set_node(__nstart); + _M_finish._M_set_node(__nfinish - 1); + _M_start._M_cur = _M_start._M_first; + _M_finish._M_cur = _M_finish._M_first + + __num_elements % __deque_buf_size(__bufsiz, sizeof(_Tp)); +} + +template +void +_Deque_base<_Tp,_Alloc,__bufsiz>::_M_create_nodes(_Tp** __nstart, + _Tp** __nfinish) +{ + _Tp** __cur; + __STL_TRY { + for (__cur = __nstart; __cur < __nfinish; ++__cur) + *__cur = _M_allocate_node(); + } + __STL_UNWIND(_M_destroy_nodes(__nstart, __cur)); +} + +template +void +_Deque_base<_Tp,_Alloc,__bufsiz>::_M_destroy_nodes(_Tp** __nstart, + _Tp** __nfinish) +{ + for (_Tp** __n = __nstart; __n < __nfinish; ++__n) + _M_deallocate_node(*__n); +} + // See __deque_buf_size(). The only reason that the default value is 0 // is as a workaround for bugs in the way that some compilers handle // constant expressions. -template -class deque { +template +class deque : protected _Deque_base<_Tp, _Alloc, __bufsiz> { + typedef _Deque_base<_Tp, _Alloc, __bufsiz> _Base; public: // Basic types - typedef T value_type; + typedef _Tp value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; @@ -260,14 +488,12 @@ public: // Basic types typedef size_t size_type; typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + public: // Iterators -#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG - typedef __deque_iterator iterator; - typedef __deque_iterator const_iterator; -#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ - typedef __deque_iterator iterator; - typedef __deque_iterator const_iterator; -#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + typedef typename _Base::iterator iterator; + typedef typename _Base::const_iterator const_iterator; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; @@ -281,1016 +507,1146 @@ public: // Iterators #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ protected: // Internal typedefs - typedef pointer* map_pointer; - typedef simple_alloc data_allocator; - typedef simple_alloc map_allocator; + typedef pointer* _Map_pointer; + static size_t _S_buffer_size() + { return __deque_buf_size(__bufsiz, sizeof(_Tp)); } + +protected: +#ifdef __STL_USE_NAMESPACES + using _Base::_M_initialize_map; + using _Base::_M_create_nodes; + using _Base::_M_destroy_nodes; + using _Base::_M_allocate_node; + using _Base::_M_deallocate_node; + using _Base::_M_allocate_map; + using _Base::_M_deallocate_map; + + using _Base::_M_map; + using _Base::_M_map_size; + using _Base::_M_start; + using _Base::_M_finish; +#endif /* __STL_USE_NAMESPACES */ - static size_type buffer_size() { - return __deque_buf_size(BufSiz, sizeof(value_type)); +public: // Basic accessors + iterator begin() { return _M_start; } + iterator end() { return _M_finish; } + const_iterator begin() const { return _M_start; } + const_iterator end() const { return _M_finish; } + + reverse_iterator rbegin() { return reverse_iterator(_M_finish); } + reverse_iterator rend() { return reverse_iterator(_M_start); } + const_reverse_iterator rbegin() const + { return const_reverse_iterator(_M_finish); } + const_reverse_iterator rend() const + { return const_reverse_iterator(_M_start); } + + reference operator[](size_type __n) + { return _M_start[difference_type(__n)]; } + const_reference operator[](size_type __n) const + { return _M_start[difference_type(__n)]; } + + reference front() { return *_M_start; } + reference back() { + iterator __tmp = _M_finish; + --__tmp; + return *__tmp; + } + const_reference front() const { return *_M_start; } + const_reference back() const { + const_iterator __tmp = _M_finish; + --__tmp; + return *__tmp; } - static size_type initial_map_size() { return 8; } -protected: // Data members - iterator start; - iterator finish; + size_type size() const { return _M_finish - _M_start;; } + size_type max_size() const { return size_type(-1); } + bool empty() const { return _M_finish == _M_start; } - map_pointer map; - size_type map_size; +public: // Constructor, destructor. + explicit deque(const allocator_type& __a = allocator_type()) + : _Base(__a, 0) {} + deque(const deque& __x) : _Base(__x.get_allocator(), __x.size()) + { uninitialized_copy(__x.begin(), __x.end(), _M_start); } + deque(size_type __n, const value_type& __value, + const allocator_type& __a = allocator_type()) : _Base(__a, __n) + { _M_fill_initialize(__value); } + explicit deque(size_type __n) : _Base(allocator_type(), __n) + { _M_fill_initialize(value_type()); } -public: // Basic accessors - iterator begin() { return start; } - iterator end() { return finish; } - const_iterator begin() const { return start; } - const_iterator end() const { return finish; } +#ifdef __STL_MEMBER_TEMPLATES - reverse_iterator rbegin() { return reverse_iterator(finish); } - reverse_iterator rend() { return reverse_iterator(start); } - const_reverse_iterator rbegin() const { - return const_reverse_iterator(finish); - } - const_reverse_iterator rend() const { - return const_reverse_iterator(start); + // Check whether it's an integral type. If so, it's not an iterator. + template + deque(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); } - reference operator[](size_type n) { return start[difference_type(n)]; } - const_reference operator[](size_type n) const { - return start[difference_type(n)]; + template + void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) { + _M_initialize_map(__n); + _M_fill_initialize(__x); } - reference front() { return *start; } - reference back() { - iterator tmp = finish; - --tmp; - return *tmp; - } - const_reference front() const { return *start; } - const_reference back() const { - const_iterator tmp = finish; - --tmp; - return *tmp; + template + void _M_initialize_dispatch(_InputIter __first, _InputIter __last, + __false_type) { + _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first)); } - size_type size() const { return finish - start;; } - size_type max_size() const { return size_type(-1); } - bool empty() const { return finish == start; } +#else /* __STL_MEMBER_TEMPLATES */ -public: // Constructor, destructor. - deque() - : start(), finish(), map(0), map_size(0) - { - create_map_and_nodes(0); - } + deque(const value_type* __first, const value_type* __last, + const allocator_type& __a = allocator_type()) + : _Base(__a, __last - __first) + { uninitialized_copy(__first, __last, _M_start); } + deque(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a, __last - __first) + { uninitialized_copy(__first, __last, _M_start); } - deque(const deque& x) - : start(), finish(), map(0), map_size(0) - { - create_map_and_nodes(x.size()); - __STL_TRY { - uninitialized_copy(x.begin(), x.end(), start); +#endif /* __STL_MEMBER_TEMPLATES */ + + ~deque() { destroy(_M_start, _M_finish); } + + deque& operator= (const deque& __x) { + const size_type __len = size(); + if (&__x != this) { + if (__len >= __x.size()) + erase(copy(__x.begin(), __x.end(), _M_start), _M_finish); + else { + const_iterator __mid = __x.begin() + difference_type(__len); + copy(__x.begin(), __mid, _M_start); + insert(_M_finish, __mid, __x.end()); + } } - __STL_UNWIND(destroy_map_and_nodes()); - } + return *this; + } - deque(size_type n, const value_type& value) - : start(), finish(), map(0), map_size(0) - { - fill_initialize(n, value); + void swap(deque& __x) { + __STD::swap(_M_start, __x._M_start); + __STD::swap(_M_finish, __x._M_finish); + __STD::swap(_M_map, __x._M_map); + __STD::swap(_M_map_size, __x._M_map_size); } - deque(int n, const value_type& value) - : start(), finish(), map(0), map_size(0) - { - fill_initialize(n, value); - } - - deque(long n, const value_type& value) - : start(), finish(), map(0), map_size(0) - { - fill_initialize(n, value); - } +public: + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. - explicit deque(size_type n) - : start(), finish(), map(0), map_size(0) - { - fill_initialize(n, value_type()); + void assign(size_type __n, const _Tp& __val) { + if (__n > size()) { + fill(begin(), end(), __val); + insert(end(), __n - size(), __val); + } + else { + erase(begin() + __n, end()); + fill(begin(), end(), __val); + } } #ifdef __STL_MEMBER_TEMPLATES - template - deque(InputIterator first, InputIterator last) - : start(), finish(), map(0), map_size(0) - { - range_initialize(first, last, iterator_category(first)); + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); } -#else /* __STL_MEMBER_TEMPLATES */ +private: // helper functions for assign() - deque(const value_type* first, const value_type* last) - : start(), finish(), map(0), map_size(0) - { - create_map_and_nodes(last - first); - __STL_TRY { - uninitialized_copy(first, last, start); - } - __STL_UNWIND(destroy_map_and_nodes()); + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { assign((size_type) __n, (_Tp) __val); } + + template + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) { + _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } - deque(const_iterator first, const_iterator last) - : start(), finish(), map(0), map_size(0) - { - create_map_and_nodes(last - first); - __STL_TRY { - uninitialized_copy(first, last, start); + template + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template + void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) { + size_type __len = 0; + distance(__first, __last, __len); + if (__len > size()) { + _ForwardIterator __mid = __first; + advance(__mid, size()); + copy(__first, __mid, begin()); + insert(end(), __mid, __last); } - __STL_UNWIND(destroy_map_and_nodes()); + else + erase(copy(__first, __last, begin()), end()); } #endif /* __STL_MEMBER_TEMPLATES */ - ~deque() { - destroy(start, finish); - destroy_map_and_nodes(); +public: // push_* and pop_* + + void push_back(const value_type& __t) { + if (_M_finish._M_cur != _M_finish._M_last - 1) { + construct(_M_finish._M_cur, __t); + ++_M_finish._M_cur; + } + else + _M_push_back_aux(__t); } - deque& operator= (const deque& x) { - const size_type len = size(); - if (&x != this) { - if (len >= x.size()) - erase(copy(x.begin(), x.end(), start), finish); - else { - const_iterator mid = x.begin() + difference_type(len); - copy(x.begin(), mid, start); - insert(finish, mid, x.end()); - } + void push_back() { + if (_M_finish._M_cur != _M_finish._M_last - 1) { + construct(_M_finish._M_cur); + ++_M_finish._M_cur; } - return *this; - } - - void swap(deque& x) { - __STD::swap(start, x.start); - __STD::swap(finish, x.finish); - __STD::swap(map, x.map); - __STD::swap(map_size, x.map_size); + else + _M_push_back_aux(); } -public: // push_* and pop_* - - void push_back(const value_type& t) { - if (finish.cur != finish.last - 1) { - construct(finish.cur, t); - ++finish.cur; + void push_front(const value_type& __t) { + if (_M_start._M_cur != _M_start._M_first) { + construct(_M_start._M_cur - 1, __t); + --_M_start._M_cur; } else - push_back_aux(t); + _M_push_front_aux(__t); } - void push_front(const value_type& t) { - if (start.cur != start.first) { - construct(start.cur - 1, t); - --start.cur; + void push_front() { + if (_M_start._M_cur != _M_start._M_first) { + construct(_M_start._M_cur - 1); + --_M_start._M_cur; } else - push_front_aux(t); + _M_push_front_aux(); } + void pop_back() { - if (finish.cur != finish.first) { - --finish.cur; - destroy(finish.cur); + if (_M_finish._M_cur != _M_finish._M_first) { + --_M_finish._M_cur; + destroy(_M_finish._M_cur); } else - pop_back_aux(); + _M_pop_back_aux(); } void pop_front() { - if (start.cur != start.last - 1) { - destroy(start.cur); - ++start.cur; + if (_M_start._M_cur != _M_start._M_last - 1) { + destroy(_M_start._M_cur); + ++_M_start._M_cur; } else - pop_front_aux(); + _M_pop_front_aux(); } public: // Insert - iterator insert(iterator position, const value_type& x) { - if (position.cur == start.cur) { - push_front(x); - return start; + iterator insert(iterator position, const value_type& __x) { + if (position._M_cur == _M_start._M_cur) { + push_front(__x); + return _M_start; } - else if (position.cur == finish.cur) { - push_back(x); - iterator tmp = finish; - --tmp; - return tmp; + else if (position._M_cur == _M_finish._M_cur) { + push_back(__x); + iterator __tmp = _M_finish; + --__tmp; + return __tmp; } else { - return insert_aux(position, x); + return _M_insert_aux(position, __x); } } - iterator insert(iterator position) { return insert(position, value_type()); } + iterator insert(iterator __position) + { return insert(__position, value_type()); } - void insert(iterator pos, size_type n, const value_type& x); + void insert(iterator __pos, size_type __n, const value_type& __x); - void insert(iterator pos, int n, const value_type& x) { - insert(pos, (size_type) n, x); - } - void insert(iterator pos, long n, const value_type& x) { - insert(pos, (size_type) n, x); +#ifdef __STL_MEMBER_TEMPLATES + + // Check whether it's an integral type. If so, it's not an iterator. + template + void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__pos, __first, __last, _Integral()); } -#ifdef __STL_MEMBER_TEMPLATES + template + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) { + insert(__pos, (size_type) __n, (value_type) __x); + } - template - void insert(iterator pos, InputIterator first, InputIterator last) { - insert(pos, first, last, iterator_category(first)); + template + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) { + insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first)); } #else /* __STL_MEMBER_TEMPLATES */ - void insert(iterator pos, const value_type* first, const value_type* last); - void insert(iterator pos, const_iterator first, const_iterator last); + void insert(iterator __pos, + const value_type* __first, const value_type* __last); + void insert(iterator __pos, + const_iterator __first, const_iterator __last); #endif /* __STL_MEMBER_TEMPLATES */ - void resize(size_type new_size, const value_type& x) { - const size_type len = size(); - if (new_size < len) - erase(start + new_size, finish); + void resize(size_type __new_size, const value_type& __x) { + const size_type __len = size(); + if (__new_size < __len) + erase(_M_start + __new_size, _M_finish); else - insert(finish, new_size - len, x); + insert(_M_finish, __new_size - __len, __x); } void resize(size_type new_size) { resize(new_size, value_type()); } public: // Erase - iterator erase(iterator pos) { - iterator next = pos; - ++next; - difference_type index = pos - start; - if (index < (size() >> 1)) { - copy_backward(start, pos, next); + iterator erase(iterator __pos) { + iterator __next = __pos; + ++__next; + difference_type __index = __pos - _M_start; + if (__index < (size() >> 1)) { + copy_backward(_M_start, __pos, __next); pop_front(); } else { - copy(next, finish, pos); + copy(__next, _M_finish, __pos); pop_back(); } - return start + index; + return _M_start + __index; } - iterator erase(iterator first, iterator last); + iterator erase(iterator __first, iterator __last); void clear(); protected: // Internal construction/destruction - void create_map_and_nodes(size_type num_elements); - void destroy_map_and_nodes(); - void fill_initialize(size_type n, const value_type& value); + void _M_fill_initialize(const value_type& __value); #ifdef __STL_MEMBER_TEMPLATES - template - void range_initialize(InputIterator first, InputIterator last, + template + void _M_range_initialize(_InputIterator __first, _InputIterator __last, input_iterator_tag); - template - void range_initialize(ForwardIterator first, ForwardIterator last, + template + void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag); #endif /* __STL_MEMBER_TEMPLATES */ protected: // Internal push_* and pop_* - void push_back_aux(const value_type& t); - void push_front_aux(const value_type& t); - void pop_back_aux(); - void pop_front_aux(); + void _M_push_back_aux(const value_type&); + void _M_push_back_aux(); + void _M_push_front_aux(const value_type&); + void _M_push_front_aux(); + void _M_pop_back_aux(); + void _M_pop_front_aux(); protected: // Internal insert functions #ifdef __STL_MEMBER_TEMPLATES - template - void insert(iterator pos, InputIterator first, InputIterator last, + template + void insert(iterator __pos, _InputIterator __first, _InputIterator __last, input_iterator_tag); - template - void insert(iterator pos, ForwardIterator first, ForwardIterator last, + template + void insert(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag); #endif /* __STL_MEMBER_TEMPLATES */ - iterator insert_aux(iterator pos, const value_type& x); - void insert_aux(iterator pos, size_type n, const value_type& x); + iterator _M_insert_aux(iterator __pos, const value_type& __x); + iterator _M_insert_aux(iterator __pos); + void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); #ifdef __STL_MEMBER_TEMPLATES - template - void insert_aux(iterator pos, ForwardIterator first, ForwardIterator last, - size_type n); + template + void _M_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + size_type __n); #else /* __STL_MEMBER_TEMPLATES */ - void insert_aux(iterator pos, - const value_type* first, const value_type* last, - size_type n); + void _M_insert_aux(iterator __pos, + const value_type* __first, const value_type* __last, + size_type __n); - void insert_aux(iterator pos, const_iterator first, const_iterator last, - size_type n); + void _M_insert_aux(iterator __pos, + const_iterator __first, const_iterator __last, + size_type __n); #endif /* __STL_MEMBER_TEMPLATES */ - iterator reserve_elements_at_front(size_type n) { - size_type vacancies = start.cur - start.first; - if (n > vacancies) - new_elements_at_front(n - vacancies); - return start - difference_type(n); + iterator _M_reserve_elements_at_front(size_type __n) { + size_type __vacancies = _M_start._M_cur - _M_start._M_first; + if (__n > __vacancies) + _M_new_elements_at_front(__n - __vacancies); + return _M_start - difference_type(__n); } - iterator reserve_elements_at_back(size_type n) { - size_type vacancies = (finish.last - finish.cur) - 1; - if (n > vacancies) - new_elements_at_back(n - vacancies); - return finish + difference_type(n); + iterator _M_reserve_elements_at_back(size_type __n) { + size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1; + if (__n > __vacancies) + _M_new_elements_at_back(__n - __vacancies); + return _M_finish + difference_type(__n); } - void new_elements_at_front(size_type new_elements); - void new_elements_at_back(size_type new_elements); + void _M_new_elements_at_front(size_type __new_elements); + void _M_new_elements_at_back(size_type __new_elements); - void destroy_nodes_at_front(iterator before_start); - void destroy_nodes_at_back(iterator after_finish); +protected: // Allocation of _M_map and nodes -protected: // Allocation of map and nodes - - // Makes sure the map has space for new nodes. Does not actually - // add the nodes. Can invalidate map pointers. (And consequently, + // Makes sure the _M_map has space for new nodes. Does not actually + // add the nodes. Can invalidate _M_map pointers. (And consequently, // deque iterators.) - void reserve_map_at_back (size_type nodes_to_add = 1) { - if (nodes_to_add + 1 > map_size - (finish.node - map)) - reallocate_map(nodes_to_add, false); - } - - void reserve_map_at_front (size_type nodes_to_add = 1) { - if (nodes_to_add > start.node - map) - reallocate_map(nodes_to_add, true); + void _M_reserve_map_at_back (size_type __nodes_to_add = 1) { + if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map)) + _M_reallocate_map(__nodes_to_add, false); } - void reallocate_map(size_type nodes_to_add, bool add_at_front); - - pointer allocate_node() { return data_allocator::allocate(buffer_size()); } - void deallocate_node(pointer n) { - data_allocator::deallocate(n, buffer_size()); + void _M_reserve_map_at_front (size_type __nodes_to_add = 1) { + if (__nodes_to_add > size_type(_M_start._M_node - _M_map)) + _M_reallocate_map(__nodes_to_add, true); } + void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front); + #ifdef __STL_NON_TYPE_TMPL_PARAM_BUG public: - bool operator==(const deque& x) const { - return size() == x.size() && equal(begin(), end(), x.begin()); + bool operator==(const deque<_Tp,_Alloc,0>& __x) const { + return size() == __x.size() && equal(begin(), end(), __x.begin()); } - bool operator!=(const deque& x) const { - return size() != x.size() || !equal(begin(), end(), x.begin()); + bool operator!=(const deque<_Tp,_Alloc,0>& __x) const { + return size() != __x.size() || !equal(begin(), end(), __x.begin()); } - bool operator<(const deque& x) const { - return lexicographical_compare(begin(), end(), x.begin(), x.end()); + bool operator<(const deque<_Tp,_Alloc,0>& __x) const { + return lexicographical_compare(begin(), end(), __x.begin(), __x.end()); } #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ }; // Non-inline member functions -template -void deque::insert(iterator pos, - size_type n, const value_type& x) { - if (pos.cur == start.cur) { - iterator new_start = reserve_elements_at_front(n); - uninitialized_fill(new_start, start, x); - start = new_start; +#ifdef __STL_MEMBER_TEMPLATES + +template +template +void deque<_Tp, _Alloc, __bufsize> + ::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag) +{ + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +void +deque<_Tp, _Alloc, __bufsize>::insert(iterator __pos, + size_type __n, const value_type& __x) +{ + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); + uninitialized_fill(__new_start, _M_start, __x); + _M_start = __new_start; } - else if (pos.cur == finish.cur) { - iterator new_finish = reserve_elements_at_back(n); - uninitialized_fill(finish, new_finish, x); - finish = new_finish; + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); + uninitialized_fill(_M_finish, __new_finish, __x); + _M_finish = __new_finish; } else - insert_aux(pos, n, x); + _M_insert_aux(__pos, __n, __x); } #ifndef __STL_MEMBER_TEMPLATES -template -void deque::insert(iterator pos, - const value_type* first, - const value_type* last) { - size_type n = last - first; - if (pos.cur == start.cur) { - iterator new_start = reserve_elements_at_front(n); +template +void deque<_Tp, _Alloc, __bufsize>::insert(iterator __pos, + const value_type* __first, + const value_type* __last) { + size_type __n = __last - __first; + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); __STL_TRY { - uninitialized_copy(first, last, new_start); - start = new_start; + uninitialized_copy(__first, __last, __new_start); + _M_start = __new_start; } - __STL_UNWIND(destroy_nodes_at_front(new_start)); + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } - else if (pos.cur == finish.cur) { - iterator new_finish = reserve_elements_at_back(n); + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); __STL_TRY { - uninitialized_copy(first, last, finish); - finish = new_finish; + uninitialized_copy(__first, __last, _M_finish); + _M_finish = __new_finish; } - __STL_UNWIND(destroy_nodes_at_back(new_finish)); + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); } else - insert_aux(pos, first, last, n); + _M_insert_aux(__pos, __first, __last, __n); } -template -void deque::insert(iterator pos, - const_iterator first, - const_iterator last) +template +void deque<_Tp,_Alloc,__bufsize>::insert(iterator __pos, + const_iterator __first, + const_iterator __last) { - size_type n = last - first; - if (pos.cur == start.cur) { - iterator new_start = reserve_elements_at_front(n); + size_type __n = __last - __first; + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); __STL_TRY { - uninitialized_copy(first, last, new_start); - start = new_start; + uninitialized_copy(__first, __last, __new_start); + _M_start = __new_start; } - __STL_UNWIND(destroy_nodes_at_front(new_start)); + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } - else if (pos.cur == finish.cur) { - iterator new_finish = reserve_elements_at_back(n); + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); __STL_TRY { - uninitialized_copy(first, last, finish); - finish = new_finish; + uninitialized_copy(__first, __last, _M_finish); + _M_finish = __new_finish; } - __STL_UNWIND(destroy_nodes_at_back(new_finish)); + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); } else - insert_aux(pos, first, last, n); + _M_insert_aux(__pos, __first, __last, __n); } #endif /* __STL_MEMBER_TEMPLATES */ -template -deque::iterator -deque::erase(iterator first, iterator last) { - if (first == start && last == finish) { +template +deque<_Tp,_Alloc,__bufsize>::iterator +deque<_Tp,_Alloc,__bufsize>::erase(iterator __first, iterator __last) +{ + if (__first == _M_start && __last == _M_finish) { clear(); - return finish; + return _M_finish; } else { - difference_type n = last - first; - difference_type elems_before = first - start; - if (elems_before < (size() - n) / 2) { - copy_backward(start, first, last); - iterator new_start = start + n; - destroy(start, new_start); - for (map_pointer cur = start.node; cur < new_start.node; ++cur) - data_allocator::deallocate(*cur, buffer_size()); - start = new_start; + difference_type __n = __last - __first; + difference_type __elems_before = __first - _M_start; + if (__elems_before < (size() - __n) / 2) { + copy_backward(_M_start, __first, __last); + iterator __new_start = _M_start + __n; + destroy(_M_start, __new_start); + _M_destroy_nodes(__new_start._M_node, _M_start._M_node); + _M_start = __new_start; } else { - copy(last, finish, first); - iterator new_finish = finish - n; - destroy(new_finish, finish); - for (map_pointer cur = new_finish.node + 1; cur <= finish.node; ++cur) - data_allocator::deallocate(*cur, buffer_size()); - finish = new_finish; + copy(__last, _M_finish, __first); + iterator __new_finish = _M_finish - __n; + destroy(__new_finish, _M_finish); + _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1); + _M_finish = __new_finish; } - return start + elems_before; + return _M_start + __elems_before; } } -template -void deque::clear() { - for (map_pointer node = start.node + 1; node < finish.node; ++node) { - destroy(*node, *node + buffer_size()); - data_allocator::deallocate(*node, buffer_size()); +template +void deque<_Tp,_Alloc,__bufsize>::clear() +{ + for (_Map_pointer __node = _M_start._M_node + 1; + __node < _M_finish._M_node; + ++__node) { + destroy(*__node, *__node + _S_buffer_size()); + _M_deallocate_node(*__node); } - if (start.node != finish.node) { - destroy(start.cur, start.last); - destroy(finish.first, finish.cur); - data_allocator::deallocate(finish.first, buffer_size()); + if (_M_start._M_node != _M_finish._M_node) { + destroy(_M_start._M_cur, _M_start._M_last); + destroy(_M_finish._M_first, _M_finish._M_cur); + _M_deallocate_node(_M_finish._M_first); } else - destroy(start.cur, finish.cur); + destroy(_M_start._M_cur, _M_finish._M_cur); - finish = start; + _M_finish = _M_start; } -template -void deque::create_map_and_nodes(size_type num_elements) { - size_type num_nodes = num_elements / buffer_size() + 1; - - map_size = max(initial_map_size(), num_nodes + 2); - map = map_allocator::allocate(map_size); - - map_pointer nstart = map + (map_size - num_nodes) / 2; - map_pointer nfinish = nstart + num_nodes - 1; - - map_pointer cur; +// Precondition: _M_start and _M_finish have already been initialized, +// but none of the deque's elements have yet been constructed. +template +void +deque<_Tp,_Alloc,__bufsize>::_M_fill_initialize(const value_type& __value) { + _Map_pointer __cur; __STL_TRY { - for (cur = nstart; cur <= nfinish; ++cur) - *cur = allocate_node(); - } -# ifdef __STL_USE_EXCEPTIONS - catch(...) { - for (map_pointer n = nstart; n < cur; ++n) - deallocate_node(*n); - map_allocator::deallocate(map, map_size); - throw; + for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur) + uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value); + uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value); } -# endif /* __STL_USE_EXCEPTIONS */ - - start.set_node(nstart); - finish.set_node(nfinish); - start.cur = start.first; - finish.cur = finish.first + num_elements % buffer_size(); + __STL_UNWIND(destroy(_M_start, iterator(*__cur, __cur))); } -// This is only used as a cleanup function in catch clauses. -template -void deque::destroy_map_and_nodes() { - for (map_pointer cur = start.node; cur <= finish.node; ++cur) - deallocate_node(*cur); - map_allocator::deallocate(map, map_size); +#ifdef __STL_MEMBER_TEMPLATES + +template +template +void +deque<_Tp,_Alloc,__bufsize>::_M_range_initialize(_InputIterator __first, + _InputIterator __last, + input_iterator_tag) +{ + _M_initialize_map(0); + for ( ; __first != __last; ++__first) + push_back(*__first); } - -template -void deque::fill_initialize(size_type n, - const value_type& value) { - create_map_and_nodes(n); - map_pointer cur; +template +template +void +deque<_Tp,_Alloc,__bufsize>::_M_range_initialize(_ForwardIterator __first, + _ForwardIterator __last, + forward_iterator_tag) +{ + size_type __n = 0; + distance(__first, __last, __n); + _M_initialize_map(__n); + + _Map_pointer __cur_node; __STL_TRY { - for (cur = start.node; cur < finish.node; ++cur) - uninitialized_fill(*cur, *cur + buffer_size(), value); - uninitialized_fill(finish.first, finish.cur, value); - } -# ifdef __STL_USE_EXCEPTIONS - catch(...) { - for (map_pointer n = start.node; n < cur; ++n) - destroy(*n, *n + buffer_size()); - destroy_map_and_nodes(); - throw; + for (__cur_node = _M_start._M_node; + __cur_node < _M_finish._M_node; + ++__cur_node) { + _ForwardIterator __mid = __first; + advance(__mid, _S_buffer_size()); + uninitialized_copy(__first, __mid, *__cur_node); + __first = __mid; + } + uninitialized_copy(__first, __last, _M_finish._M_first); } -# endif /* __STL_USE_EXCEPTIONS */ + __STL_UNWIND(destroy(_M_start, iterator(*__cur_node, __cur_node))); } -#ifdef __STL_MEMBER_TEMPLATES - -template -template -void deque::range_initialize(InputIterator first, - InputIterator last, - input_iterator_tag) { - create_map_and_nodes(0); - for ( ; first != last; ++first) - push_back(*first); -} +#endif /* __STL_MEMBER_TEMPLATES */ -template -template -void deque::range_initialize(ForwardIterator first, - ForwardIterator last, - forward_iterator_tag) { - size_type n = 0; - distance(first, last, n); - create_map_and_nodes(n); +// Called only if _M_finish._M_cur == _M_finish._M_last - 1. +template +void +deque<_Tp,_Alloc,__bufsize>::_M_push_back_aux(const value_type& __t) +{ + value_type __t_copy = __t; + _M_reserve_map_at_back(); + *(_M_finish._M_node + 1) = _M_allocate_node(); __STL_TRY { - uninitialized_copy(first, last, start); + construct(_M_finish._M_cur, __t_copy); + _M_finish._M_set_node(_M_finish._M_node + 1); + _M_finish._M_cur = _M_finish._M_first; } - __STL_UNWIND(destroy_map_and_nodes()); + __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1))); } -#endif /* __STL_MEMBER_TEMPLATES */ - -// Called only if finish.cur == finish.last - 1. -template -void deque::push_back_aux(const value_type& t) { - value_type t_copy = t; - reserve_map_at_back(); - *(finish.node + 1) = allocate_node(); +// Called only if _M_finish._M_cur == _M_finish._M_last - 1. +template +void +deque<_Tp,_Alloc,__bufsize>::_M_push_back_aux() +{ + _M_reserve_map_at_back(); + *(_M_finish._M_node + 1) = _M_allocate_node(); __STL_TRY { - construct(finish.cur, t_copy); - finish.set_node(finish.node + 1); - finish.cur = finish.first; + construct(_M_finish._M_cur); + _M_finish._M_set_node(_M_finish._M_node + 1); + _M_finish._M_cur = _M_finish._M_first; } - __STL_UNWIND(deallocate_node(*(finish.node + 1))); + __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1))); } -// Called only if start.cur == start.first. -template -void deque::push_front_aux(const value_type& t) { - value_type t_copy = t; - reserve_map_at_front(); - *(start.node - 1) = allocate_node(); +// Called only if _M_start._M_cur == _M_start._M_first. +template +void +deque<_Tp,_Alloc,__bufsize>::_M_push_front_aux(const value_type& __t) +{ + value_type __t_copy = __t; + _M_reserve_map_at_front(); + *(_M_start._M_node - 1) = _M_allocate_node(); __STL_TRY { - start.set_node(start.node - 1); - start.cur = start.last - 1; - construct(start.cur, t_copy); + _M_start._M_set_node(_M_start._M_node - 1); + _M_start._M_cur = _M_start._M_last - 1; + construct(_M_start._M_cur, __t_copy); } -# ifdef __STL_USE_EXCEPTIONS - catch(...) { - start.set_node(start.node + 1); - start.cur = start.first; - deallocate_node(*(start.node - 1)); - throw; + __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1)))); +} + +// Called only if _M_start._M_cur == _M_start._M_first. +template +void +deque<_Tp,_Alloc,__bufsize>::_M_push_front_aux() +{ + _M_reserve_map_at_front(); + *(_M_start._M_node - 1) = _M_allocate_node(); + __STL_TRY { + _M_start._M_set_node(_M_start._M_node - 1); + _M_start._M_cur = _M_start._M_last - 1; + construct(_M_start._M_cur); } -# endif /* __STL_USE_EXCEPTIONS */ + __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1)))); } -// Called only if finish.cur == finish.first. -template -void deque:: pop_back_aux() { - deallocate_node(finish.first); - finish.set_node(finish.node - 1); - finish.cur = finish.last - 1; - destroy(finish.cur); +// Called only if _M_finish._M_cur == _M_finish._M_first. +template +void +deque<_Tp,_Alloc,__bufsize>::_M_pop_back_aux() +{ + _M_deallocate_node(_M_finish._M_first); + _M_finish._M_set_node(_M_finish._M_node - 1); + _M_finish._M_cur = _M_finish._M_last - 1; + destroy(_M_finish._M_cur); } -// Called only if start.cur == start.last - 1. Note that if the deque -// has at least one element (a necessary precondition for this member -// function), and if start.cur == start.last, then the deque must have -// at least two nodes. -template -void deque::pop_front_aux() { - destroy(start.cur); - deallocate_node(start.first); - start.set_node(start.node + 1); - start.cur = start.first; +// Called only if _M_start._M_cur == _M_start._M_last - 1. Note that +// if the deque has at least one element (a precondition for this member +// function), and if _M_start._M_cur == _M_start._M_last, then the deque +// must have at least two nodes. +template +void +deque<_Tp,_Alloc,__bufsize>::_M_pop_front_aux() +{ + destroy(_M_start._M_cur); + _M_deallocate_node(_M_start._M_first); + _M_start._M_set_node(_M_start._M_node + 1); + _M_start._M_cur = _M_start._M_first; } #ifdef __STL_MEMBER_TEMPLATES -template -template -void deque::insert(iterator pos, - InputIterator first, InputIterator last, - input_iterator_tag) { - copy(first, last, inserter(*this, pos)); +template +template +void +deque<_Tp,_Alloc,__bufsize>::insert(iterator __pos, + _InputIterator __first, + _InputIterator __last, + input_iterator_tag) +{ + copy(__first, __last, inserter(*this, __pos)); } -template -template -void deque::insert(iterator pos, - ForwardIterator first, - ForwardIterator last, - forward_iterator_tag) { - size_type n = 0; - distance(first, last, n); - if (pos.cur == start.cur) { - iterator new_start = reserve_elements_at_front(n); +template +template +void +deque<_Tp,_Alloc,__bufsize>::insert(iterator __pos, + _ForwardIterator __first, + _ForwardIterator __last, + forward_iterator_tag) { + size_type __n = 0; + distance(__first, __last, __n); + if (__pos._M_cur == _M_start._M_cur) { + iterator __new_start = _M_reserve_elements_at_front(__n); __STL_TRY { - uninitialized_copy(first, last, new_start); - start = new_start; + uninitialized_copy(__first, __last, __new_start); + _M_start = __new_start; } - __STL_UNWIND(destroy_nodes_at_front(new_start)); + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } - else if (pos.cur == finish.cur) { - iterator new_finish = reserve_elements_at_back(n); + else if (__pos._M_cur == _M_finish._M_cur) { + iterator __new_finish = _M_reserve_elements_at_back(__n); __STL_TRY { - uninitialized_copy(first, last, finish); - finish = new_finish; + uninitialized_copy(__first, __last, _M_finish); + _M_finish = __new_finish; } - __STL_UNWIND(destroy_nodes_at_back(new_finish)); + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); } else - insert_aux(pos, first, last, n); + _M_insert_aux(__pos, __first, __last, __n); } #endif /* __STL_MEMBER_TEMPLATES */ -template -typename deque::iterator -deque::insert_aux(iterator pos, const value_type& x) { - difference_type index = pos - start; - value_type x_copy = x; - if (index < size() / 2) { +template +typename deque<_Tp, _Alloc, __bufsize>::iterator +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos, + const value_type& __x) +{ + difference_type __index = __pos - _M_start; + value_type __x_copy = __x; + if (__index < size() / 2) { + push_front(front()); + iterator __front1 = _M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = _M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + copy(__front2, __pos1, __front1); + } + else { + push_back(back()); + iterator __back1 = _M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = _M_start + __index; + copy_backward(__pos, __back2, __back1); + } + *__pos = __x_copy; + return __pos; +} + +template +typename deque<_Tp,_Alloc,__bufsize>::iterator +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos) +{ + difference_type __index = __pos - _M_start; + if (__index < size() / 2) { push_front(front()); - iterator front1 = start; - ++front1; - iterator front2 = front1; - ++front2; - pos = start + index; - iterator pos1 = pos; - ++pos1; - copy(front2, pos1, front1); + iterator __front1 = _M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = _M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + copy(__front2, __pos1, __front1); } else { push_back(back()); - iterator back1 = finish; - --back1; - iterator back2 = back1; - --back2; - pos = start + index; - copy_backward(pos, back2, back1); - } - *pos = x_copy; - return pos; + iterator __back1 = _M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = _M_start + __index; + copy_backward(__pos, __back2, __back1); + } + *__pos = value_type(); + return __pos; } -template -void deque::insert_aux(iterator pos, - size_type n, const value_type& x) { - const difference_type elems_before = pos - start; - size_type length = size(); - value_type x_copy = x; - if (elems_before < length / 2) { - iterator new_start = reserve_elements_at_front(n); - iterator old_start = start; - pos = start + elems_before; +template +void +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos, + size_type __n, + const value_type& __x) +{ + const difference_type __elems_before = __pos - _M_start; + size_type __length = size(); + value_type __x_copy = __x; + if (__elems_before < __length / 2) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elems_before; __STL_TRY { - if (elems_before >= difference_type(n)) { - iterator start_n = start + difference_type(n); - uninitialized_copy(start, start_n, new_start); - start = new_start; - copy(start_n, pos, old_start); - fill(pos - difference_type(n), pos, x_copy); + if (__elems_before >= difference_type(__n)) { + iterator __start_n = _M_start + difference_type(__n); + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + fill(__pos - difference_type(__n), __pos, __x_copy); } else { - __uninitialized_copy_fill(start, pos, new_start, start, x_copy); - start = new_start; - fill(old_start, pos, x_copy); + __uninitialized_copy_fill(_M_start, __pos, __new_start, + _M_start, __x_copy); + _M_start = __new_start; + fill(__old_start, __pos, __x_copy); } } - __STL_UNWIND(destroy_nodes_at_front(new_start)); + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else { - iterator new_finish = reserve_elements_at_back(n); - iterator old_finish = finish; - const difference_type elems_after = difference_type(length) - elems_before; - pos = finish - elems_after; + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elems_after = + difference_type(__length) - __elems_before; + __pos = _M_finish - __elems_after; __STL_TRY { - if (elems_after > difference_type(n)) { - iterator finish_n = finish - difference_type(n); - uninitialized_copy(finish_n, finish, finish); - finish = new_finish; - copy_backward(pos, finish_n, old_finish); - fill(pos, pos + difference_type(n), x_copy); + if (__elems_after > difference_type(__n)) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + fill(__pos, __pos + difference_type(__n), __x_copy); } else { - __uninitialized_fill_copy(finish, pos + difference_type(n), - x_copy, - pos, finish); - finish = new_finish; - fill(pos, old_finish, x_copy); + __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n), + __x_copy, __pos, _M_finish); + _M_finish = __new_finish; + fill(__pos, __old_finish, __x_copy); } } - __STL_UNWIND(destroy_nodes_at_back(new_finish)); + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); } } #ifdef __STL_MEMBER_TEMPLATES -template -template -void deque::insert_aux(iterator pos, - ForwardIterator first, - ForwardIterator last, - size_type n) +template +template +void +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos, + _ForwardIterator __first, + _ForwardIterator __last, + size_type __n) { - const difference_type elems_before = pos - start; - size_type length = size(); - if (elems_before < length / 2) { - iterator new_start = reserve_elements_at_front(n); - iterator old_start = start; - pos = start + elems_before; + const difference_type __elemsbefore = __pos - _M_start; + size_type __length = size(); + if (__elemsbefore < __length / 2) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elemsbefore; __STL_TRY { - if (elems_before >= difference_type(n)) { - iterator start_n = start + difference_type(n); - uninitialized_copy(start, start_n, new_start); - start = new_start; - copy(start_n, pos, old_start); - copy(first, last, pos - difference_type(n)); + if (__elemsbefore >= difference_type(__n)) { + iterator __start_n = _M_start + difference_type(__n); + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + copy(__first, __last, __pos - difference_type(__n)); } else { - ForwardIterator mid = first; - advance(mid, difference_type(n) - elems_before); - __uninitialized_copy_copy(start, pos, first, mid, new_start); - start = new_start; - copy(mid, last, old_start); + _ForwardIterator __mid = __first; + advance(__mid, difference_type(__n) - __elemsbefore); + __uninitialized_copy_copy(_M_start, __pos, __first, __mid, + __new_start); + _M_start = __new_start; + copy(__mid, __last, __old_start); } } - __STL_UNWIND(destroy_nodes_at_front(new_start)); + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else { - iterator new_finish = reserve_elements_at_back(n); - iterator old_finish = finish; - const difference_type elems_after = difference_type(length) - elems_before; - pos = finish - elems_after; + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elemsafter = + difference_type(__length) - __elemsbefore; + __pos = _M_finish - __elemsafter; __STL_TRY { - if (elems_after > difference_type(n)) { - iterator finish_n = finish - difference_type(n); - uninitialized_copy(finish_n, finish, finish); - finish = new_finish; - copy_backward(pos, finish_n, old_finish); - copy(first, last, pos); + if (__elemsafter > difference_type(__n)) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + copy(__first, __last, __pos); } else { - ForwardIterator mid = first; - advance(mid, elems_after); - __uninitialized_copy_copy(mid, last, pos, finish, finish); - finish = new_finish; - copy(first, mid, pos); + _ForwardIterator __mid = __first; + advance(__mid, __elemsafter); + __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish); + _M_finish = __new_finish; + copy(__first, __mid, __pos); } } - __STL_UNWIND(destroy_nodes_at_back(new_finish)); + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); } } #else /* __STL_MEMBER_TEMPLATES */ -template -void deque::insert_aux(iterator pos, - const value_type* first, - const value_type* last, - size_type n) +template +void +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos, + const value_type* __first, + const value_type* __last, + size_type __n) { - const difference_type elems_before = pos - start; - size_type length = size(); - if (elems_before < length / 2) { - iterator new_start = reserve_elements_at_front(n); - iterator old_start = start; - pos = start + elems_before; + const difference_type __elemsbefore = __pos - _M_start; + size_type __length = size(); + if (__elemsbefore < __length / 2) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elemsbefore; __STL_TRY { - if (elems_before >= difference_type(n)) { - iterator start_n = start + difference_type(n); - uninitialized_copy(start, start_n, new_start); - start = new_start; - copy(start_n, pos, old_start); - copy(first, last, pos - difference_type(n)); + if (__elemsbefore >= difference_type(__n)) { + iterator __start_n = _M_start + difference_type(__n); + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + copy(__first, __last, __pos - difference_type(__n)); } else { - const value_type* mid = first + (difference_type(n) - elems_before); - __uninitialized_copy_copy(start, pos, first, mid, new_start); - start = new_start; - copy(mid, last, old_start); + const value_type* __mid = + __first + (difference_type(__n) - __elemsbefore); + __uninitialized_copy_copy(_M_start, __pos, __first, __mid, + __new_start); + _M_start = __new_start; + copy(__mid, __last, __old_start); } } - __STL_UNWIND(destroy_nodes_at_front(new_start)); + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else { - iterator new_finish = reserve_elements_at_back(n); - iterator old_finish = finish; - const difference_type elems_after = difference_type(length) - elems_before; - pos = finish - elems_after; + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elemsafter = + difference_type(__length) - __elemsbefore; + __pos = _M_finish - __elemsafter; __STL_TRY { - if (elems_after > difference_type(n)) { - iterator finish_n = finish - difference_type(n); - uninitialized_copy(finish_n, finish, finish); - finish = new_finish; - copy_backward(pos, finish_n, old_finish); - copy(first, last, pos); + if (__elemsafter > difference_type(__n)) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + copy(__first, __last, __pos); } else { - const value_type* mid = first + elems_after; - __uninitialized_copy_copy(mid, last, pos, finish, finish); - finish = new_finish; - copy(first, mid, pos); + const value_type* __mid = __first + __elemsafter; + __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish); + _M_finish = __new_finish; + copy(__first, __mid, __pos); } } - __STL_UNWIND(destroy_nodes_at_back(new_finish)); + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); } } -template -void deque::insert_aux(iterator pos, - const_iterator first, - const_iterator last, - size_type n) +template +void +deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos, + const_iterator __first, + const_iterator __last, + size_type __n) { - const difference_type elems_before = pos - start; - size_type length = size(); - if (elems_before < length / 2) { - iterator new_start = reserve_elements_at_front(n); - iterator old_start = start; - pos = start + elems_before; + const difference_type __elemsbefore = __pos - _M_start; + size_type __length = size(); + if (__elemsbefore < __length / 2) { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = _M_start; + __pos = _M_start + __elemsbefore; __STL_TRY { - if (elems_before >= n) { - iterator start_n = start + n; - uninitialized_copy(start, start_n, new_start); - start = new_start; - copy(start_n, pos, old_start); - copy(first, last, pos - difference_type(n)); + if (__elemsbefore >= __n) { + iterator __start_n = _M_start + __n; + uninitialized_copy(_M_start, __start_n, __new_start); + _M_start = __new_start; + copy(__start_n, __pos, __old_start); + copy(__first, __last, __pos - difference_type(__n)); } else { - const_iterator mid = first + (n - elems_before); - __uninitialized_copy_copy(start, pos, first, mid, new_start); - start = new_start; - copy(mid, last, old_start); + const_iterator __mid = __first + (__n - __elemsbefore); + __uninitialized_copy_copy(_M_start, __pos, __first, __mid, + __new_start); + _M_start = __new_start; + copy(__mid, __last, __old_start); } } - __STL_UNWIND(destroy_nodes_at_front(new_start)); + __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node)); } else { - iterator new_finish = reserve_elements_at_back(n); - iterator old_finish = finish; - const difference_type elems_after = length - elems_before; - pos = finish - elems_after; + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = _M_finish; + const difference_type __elemsafter = __length - __elemsbefore; + __pos = _M_finish - __elemsafter; __STL_TRY { - if (elems_after > n) { - iterator finish_n = finish - difference_type(n); - uninitialized_copy(finish_n, finish, finish); - finish = new_finish; - copy_backward(pos, finish_n, old_finish); - copy(first, last, pos); + if (__elemsafter > __n) { + iterator __finish_n = _M_finish - difference_type(__n); + uninitialized_copy(__finish_n, _M_finish, _M_finish); + _M_finish = __new_finish; + copy_backward(__pos, __finish_n, __old_finish); + copy(__first, __last, __pos); } else { - const_iterator mid = first + elems_after; - __uninitialized_copy_copy(mid, last, pos, finish, finish); - finish = new_finish; - copy(first, mid, pos); + const_iterator __mid = __first + __elemsafter; + __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish); + _M_finish = __new_finish; + copy(__first, __mid, __pos); } } - __STL_UNWIND(destroy_nodes_at_back(new_finish)); + __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1, + __new_finish._M_node + 1)); } } #endif /* __STL_MEMBER_TEMPLATES */ -template -void deque::new_elements_at_front(size_type new_elements) { - size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size(); - reserve_map_at_front(new_nodes); - size_type i; +template +void +deque<_Tp,_Alloc,__bufsize>::_M_new_elements_at_front(size_type __new_elems) +{ + size_type __new_nodes + = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); + _M_reserve_map_at_front(__new_nodes); + size_type __i; __STL_TRY { - for (i = 1; i <= new_nodes; ++i) - *(start.node - i) = allocate_node(); + for (__i = 1; __i <= __new_nodes; ++__i) + *(_M_start._M_node - __i) = _M_allocate_node(); } # ifdef __STL_USE_EXCEPTIONS catch(...) { - for (size_type j = 1; j < i; ++j) - deallocate_node(*(start.node - j)); + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(_M_start._M_node - __j)); throw; } # endif /* __STL_USE_EXCEPTIONS */ } -template -void deque::new_elements_at_back(size_type new_elements) { - size_type new_nodes = (new_elements + buffer_size() - 1) / buffer_size(); - reserve_map_at_back(new_nodes); - size_type i; +template +void +deque<_Tp,_Alloc,__bufsize>::_M_new_elements_at_back(size_type __new_elems) +{ + size_type __new_nodes + = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); + _M_reserve_map_at_back(__new_nodes); + size_type __i; __STL_TRY { - for (i = 1; i <= new_nodes; ++i) - *(finish.node + i) = allocate_node(); + for (__i = 1; __i <= __new_nodes; ++__i) + *(_M_finish._M_node + __i) = _M_allocate_node(); } # ifdef __STL_USE_EXCEPTIONS catch(...) { - for (size_type j = 1; j < i; ++j) - deallocate_node(*(finish.node + j)); + for (size_type __j = 1; __j < __i; ++__j) + _M_deallocate_node(*(_M_finish._M_node + __j)); throw; } # endif /* __STL_USE_EXCEPTIONS */ } -template -void deque::destroy_nodes_at_front(iterator before_start) { - for (map_pointer n = before_start.node; n < start.node; ++n) - deallocate_node(*n); -} - -template -void deque::destroy_nodes_at_back(iterator after_finish) { - for (map_pointer n = after_finish.node; n > finish.node; --n) - deallocate_node(*n); -} - -template -void deque::reallocate_map(size_type nodes_to_add, - bool add_at_front) { - size_type old_num_nodes = finish.node - start.node + 1; - size_type new_num_nodes = old_num_nodes + nodes_to_add; - - map_pointer new_nstart; - if (map_size > 2 * new_num_nodes) { - new_nstart = map + (map_size - new_num_nodes) / 2 - + (add_at_front ? nodes_to_add : 0); - if (new_nstart < start.node) - copy(start.node, finish.node + 1, new_nstart); +template +void +deque<_Tp,_Alloc,__bufsize>::_M_reallocate_map(size_type __nodes_to_add, + bool __add_at_front) +{ + size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1; + size_type __new_num_nodes = __old_num_nodes + __nodes_to_add; + + _Map_pointer __new_nstart; + if (_M_map_size > 2 * __new_num_nodes) { + __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + if (__new_nstart < _M_start._M_node) + copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart); else - copy_backward(start.node, finish.node + 1, new_nstart + old_num_nodes); + copy_backward(_M_start._M_node, _M_finish._M_node + 1, + __new_nstart + __old_num_nodes); } else { - size_type new_map_size = map_size + max(map_size, nodes_to_add) + 2; + size_type __new_map_size = + _M_map_size + max(_M_map_size, __nodes_to_add) + 2; - map_pointer new_map = map_allocator::allocate(new_map_size); - new_nstart = new_map + (new_map_size - new_num_nodes) / 2 - + (add_at_front ? nodes_to_add : 0); - copy(start.node, finish.node + 1, new_nstart); - map_allocator::deallocate(map, map_size); + _Map_pointer __new_map = _M_allocate_map(__new_map_size); + __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart); + _M_deallocate_map(_M_map, _M_map_size); - map = new_map; - map_size = new_map_size; + _M_map = __new_map; + _M_map_size = __new_map_size; } - start.set_node(new_nstart); - finish.set_node(new_nstart + old_num_nodes - 1); + _M_start._M_set_node(__new_nstart); + _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); } @@ -1298,16 +1654,20 @@ void deque::reallocate_map(size_type nodes_to_add, #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG -template -bool operator==(const deque& x, - const deque& y) { - return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); +template +bool operator==(const deque<_Tp, _Alloc, __bufsiz>& __x, + const deque<_Tp, _Alloc, __bufsiz>& __y) +{ + return __x.size() == __y.size() && + equal(__x.begin(), __x.end(), __y.begin()); } -template -bool operator<(const deque& x, - const deque& y) { - return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); +template +bool operator<(const deque<_Tp, _Alloc, __bufsiz>& __x, + const deque<_Tp, _Alloc, __bufsiz>& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ @@ -1315,15 +1675,18 @@ bool operator<(const deque& x, #if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) && \ !defined(__STL_NON_TYPE_TMPL_PARAM_BUG) -template -inline void swap(deque& x, deque& y) { - x.swap(y); +template +inline void +swap(deque<_Tp,_Alloc,__bufsiz>& __x, deque<_Tp,_Alloc,__bufsiz>& __y) +{ + __x.swap(__y); } #endif #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/libstdc++/stl/stl_function.h b/libstdc++/stl/stl_function.h index c0d785d6a60..cd07c1c6730 100644 --- a/libstdc++/stl/stl_function.h +++ b/libstdc++/stl/stl_function.h @@ -12,7 +12,7 @@ * purpose. It is provided "as is" without express or implied warranty. * * - * Copyright (c) 1996 + * Copyright (c) 1996-1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software @@ -33,372 +33,430 @@ __STL_BEGIN_NAMESPACE -template +template struct unary_function { - typedef Arg argument_type; - typedef Result result_type; + typedef _Arg argument_type; + typedef _Result result_type; }; -template +template struct binary_function { - typedef Arg1 first_argument_type; - typedef Arg2 second_argument_type; - typedef Result result_type; + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; }; -template -struct plus : public binary_function { - T operator()(const T& x, const T& y) const { return x + y; } +template +struct plus : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; } }; -template -struct minus : public binary_function { - T operator()(const T& x, const T& y) const { return x - y; } +template +struct minus : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x - __y; } }; -template -struct multiplies : public binary_function { - T operator()(const T& x, const T& y) const { return x * y; } +template +struct multiplies : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; } }; -template -struct divides : public binary_function { - T operator()(const T& x, const T& y) const { return x / y; } +template +struct divides : public binary_function<_Tp,_Tp,_Tp> { + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x / __y; } }; -template inline T identity_element(plus) { return T(0); } +// identity_element (not part of the C++ standard). -template inline T identity_element(multiplies) { return T(1); } +template inline _Tp identity_element(plus<_Tp>) { + return _Tp(0); +} +template inline _Tp identity_element(multiplies<_Tp>) { + return _Tp(1); +} -template -struct modulus : public binary_function { - T operator()(const T& x, const T& y) const { return x % y; } +template +struct modulus : public binary_function<_Tp,_Tp,_Tp> +{ + _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x % __y; } }; -template -struct negate : public unary_function { - T operator()(const T& x) const { return -x; } +template +struct negate : public unary_function<_Tp,_Tp> +{ + _Tp operator()(const _Tp& __x) const { return -__x; } }; -template -struct equal_to : public binary_function { - bool operator()(const T& x, const T& y) const { return x == y; } +template +struct equal_to : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; } }; -template -struct not_equal_to : public binary_function { - bool operator()(const T& x, const T& y) const { return x != y; } +template +struct not_equal_to : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; } }; -template -struct greater : public binary_function { - bool operator()(const T& x, const T& y) const { return x > y; } +template +struct greater : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } }; -template -struct less : public binary_function { - bool operator()(const T& x, const T& y) const { return x < y; } +template +struct less : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } }; -template -struct greater_equal : public binary_function { - bool operator()(const T& x, const T& y) const { return x >= y; } +template +struct greater_equal : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; } }; -template -struct less_equal : public binary_function { - bool operator()(const T& x, const T& y) const { return x <= y; } +template +struct less_equal : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; } }; -template -struct logical_and : public binary_function { - bool operator()(const T& x, const T& y) const { return x && y; } +template +struct logical_and : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x && __y; } }; -template -struct logical_or : public binary_function { - bool operator()(const T& x, const T& y) const { return x || y; } +template +struct logical_or : public binary_function<_Tp,_Tp,bool> +{ + bool operator()(const _Tp& __x, const _Tp& __y) const { return __x || __y; } }; -template -struct logical_not : public unary_function { - bool operator()(const T& x) const { return !x; } +template +struct logical_not : public unary_function<_Tp,bool> +{ + bool operator()(const _Tp& __x) const { return !__x; } }; -template +template class unary_negate - : public unary_function { + : public unary_function { protected: - Predicate pred; + _Predicate _M_pred; public: - explicit unary_negate(const Predicate& x) : pred(x) {} - bool operator()(const typename Predicate::argument_type& x) const { - return !pred(x); + explicit unary_negate(const _Predicate& __x) : _M_pred(__x) {} + bool operator()(const typename _Predicate::argument_type& __x) const { + return !_M_pred(__x); } }; -template -inline unary_negate not1(const Predicate& pred) { - return unary_negate(pred); +template +inline unary_negate<_Predicate> +not1(const _Predicate& __pred) +{ + return unary_negate<_Predicate>(__pred); } -template +template class binary_negate - : public binary_function { protected: - Predicate pred; + _Predicate _M_pred; public: - explicit binary_negate(const Predicate& x) : pred(x) {} - bool operator()(const typename Predicate::first_argument_type& x, - const typename Predicate::second_argument_type& y) const { - return !pred(x, y); + explicit binary_negate(const _Predicate& __x) : _M_pred(__x) {} + bool operator()(const typename _Predicate::first_argument_type& __x, + const typename _Predicate::second_argument_type& __y) const + { + return !_M_pred(__x, __y); } }; -template -inline binary_negate not2(const Predicate& pred) { - return binary_negate(pred); +template +inline binary_negate<_Predicate> +not2(const _Predicate& __pred) +{ + return binary_negate<_Predicate>(__pred); } -template +template class binder1st - : public unary_function { + : public unary_function { protected: - Operation op; - typename Operation::first_argument_type value; + _Operation op; + typename _Operation::first_argument_type value; public: - binder1st(const Operation& x, - const typename Operation::first_argument_type& y) - : op(x), value(y) {} - typename Operation::result_type - operator()(const typename Operation::second_argument_type& x) const { - return op(value, x); + binder1st(const _Operation& __x, + const typename _Operation::first_argument_type& __y) + : op(__x), value(__y) {} + typename _Operation::result_type + operator()(const typename _Operation::second_argument_type& __x) const { + return op(value, __x); } }; -template -inline binder1st bind1st(const Operation& op, const T& x) { - typedef typename Operation::first_argument_type arg1_type; - return binder1st(op, arg1_type(x)); +template +inline binder1st<_Operation> +bind1st(const _Operation& __opr, const _Tp& __x) +{ + typedef typename _Operation::first_argument_type _Arg1_type; + return binder1st<_Operation>(__opr, _Arg1_type(__x)); } -template +template class binder2nd - : public unary_function { + : public unary_function { protected: - Operation op; - typename Operation::second_argument_type value; + _Operation op; + typename _Operation::second_argument_type value; public: - binder2nd(const Operation& x, - const typename Operation::second_argument_type& y) - : op(x), value(y) {} - typename Operation::result_type - operator()(const typename Operation::first_argument_type& x) const { - return op(x, value); + binder2nd(const _Operation& __x, + const typename _Operation::second_argument_type& __y) + : op(__x), value(__y) {} + typename _Operation::result_type + operator()(const typename _Operation::first_argument_type& __x) const { + return op(__x, value); } }; -template -inline binder2nd bind2nd(const Operation& op, const T& x) { - typedef typename Operation::second_argument_type arg2_type; - return binder2nd(op, arg2_type(x)); +template +inline binder2nd<_Operation> +bind2nd(const _Operation& __opr, const _Tp& __x) +{ + typedef typename _Operation::second_argument_type _Arg2_type; + return binder2nd<_Operation>(__opr, _Arg2_type(__x)); } -template -class unary_compose : public unary_function { +// unary_compose and binary_compose (extensions, not part of the standard). + +template +class unary_compose + : public unary_function +{ protected: - Operation1 op1; - Operation2 op2; + _Operation1 __op1; + _Operation2 __op2; public: - unary_compose(const Operation1& x, const Operation2& y) : op1(x), op2(y) {} - typename Operation1::result_type - operator()(const typename Operation2::argument_type& x) const { - return op1(op2(x)); + unary_compose(const _Operation1& __x, const _Operation2& __y) + : __op1(__x), __op2(__y) {} + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const { + return __op1(__op2(__x)); } }; -template -inline unary_compose compose1(const Operation1& op1, - const Operation2& op2) { - return unary_compose(op1, op2); +template +inline unary_compose<_Operation1,_Operation2> +compose1(const _Operation1& __op1, const _Operation2& __op2) +{ + return unary_compose<_Operation1,_Operation2>(__op1, __op2); } -template +template class binary_compose - : public unary_function { + : public unary_function { protected: - Operation1 op1; - Operation2 op2; - Operation3 op3; + _Operation1 _M_op1; + _Operation2 _M_op2; + _Operation3 _M_op3; public: - binary_compose(const Operation1& x, const Operation2& y, - const Operation3& z) : op1(x), op2(y), op3(z) { } - typename Operation1::result_type - operator()(const typename Operation2::argument_type& x) const { - return op1(op2(x), op3(x)); + binary_compose(const _Operation1& __x, const _Operation2& __y, + const _Operation3& __z) + : _M_op1(__x), _M_op2(__y), _M_op3(__z) { } + typename _Operation1::result_type + operator()(const typename _Operation2::argument_type& __x) const { + return _M_op1(_M_op2(__x), _M_op3(__x)); } }; -template -inline binary_compose -compose2(const Operation1& op1, const Operation2& op2, const Operation3& op3) { - return binary_compose(op1, op2, op3); +template +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 pointer_to_unary_function : public unary_function { +template +class pointer_to_unary_function : public unary_function<_Arg, _Result> { protected: - Result (*ptr)(Arg); + _Result (*_M_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); } + explicit pointer_to_unary_function(_Result (*__x)(_Arg)) : _M_ptr(__x) {} + _Result operator()(_Arg __x) const { return _M_ptr(__x); } }; -template -inline pointer_to_unary_function ptr_fun(Result (*x)(Arg)) { - return pointer_to_unary_function(x); +template +inline pointer_to_unary_function<_Arg, _Result> ptr_fun(_Result (*__x)(_Arg)) +{ + return pointer_to_unary_function<_Arg, _Result>(__x); } -template -class pointer_to_binary_function : public binary_function { +template +class pointer_to_binary_function : + public binary_function<_Arg1,_Arg2,_Result> { protected: - Result (*ptr)(Arg1, Arg2); + _Result (*_M_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); } + explicit pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) + : _M_ptr(__x) {} + _Result operator()(_Arg1 __x, _Arg2 __y) const { + return _M_ptr(__x, __y); + } }; -template -inline pointer_to_binary_function -ptr_fun(Result (*x)(Arg1, Arg2)) { - return pointer_to_binary_function(x); +template +inline pointer_to_binary_function<_Arg1,_Arg2,_Result> +ptr_fun(_Result (*__x)(_Arg1, _Arg2)) { + return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__x); } -template -struct identity : public unary_function { - const T& operator()(const T& x) const { return x; } +// identity is an extensions: it is not part of the standard. +template +struct _Identity : public unary_function<_Tp,_Tp> { + const _Tp& operator()(const _Tp& __x) const { return __x; } }; -template -struct select1st : public unary_function { - const typename Pair::first_type& operator()(const Pair& x) const - { - return x.first; +template struct identity : public _Identity<_Tp> {}; + +// select1st and select2nd are extensions: they are not part of the standard. +template +struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> { + const typename _Pair::first_type& operator()(const _Pair& __x) const { + return __x.first; } }; -template -struct select2nd : public unary_function { - const typename Pair::second_type& operator()(const Pair& x) const - { - return x.second; +template +struct _Select2nd : public unary_function<_Pair, typename _Pair::second_type> +{ + const typename _Pair::second_type& operator()(const _Pair& __x) const { + return __x.second; } }; -template -struct project1st : public binary_function { - Arg1 operator()(const Arg1& x, const Arg2&) const { return x; } +template struct select1st : public _Select1st<_Pair> {}; +template struct select2nd : public _Select2nd<_Pair> {}; + +// project1st and project2nd are extensions: they are not part of the standard +template +struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> { + _Arg1 operator()(const _Arg1& __x, const _Arg2&) const { return __x; } }; -template -struct project2nd : public binary_function { - Arg2 operator()(const Arg1&, const Arg2& y) const { return y; } +template +struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> { + _Arg2 operator()(const _Arg1&, const _Arg2& __y) const { return __y; } }; -template +template +struct project1st : public _Project1st<_Arg1, _Arg2> {}; + +template +struct project2nd : public _Project2nd<_Arg1, _Arg2> {}; + +// constant_void_fun, constant_unary_fun, and constant_binary_fun are +// extensions: they are not part of the standard. (The same, of course, +// is true of the helper functions constant0, constant1, and constant2.) +template struct constant_void_fun { - typedef Result result_type; - result_type val; - constant_void_fun(const result_type& v) : val(v) {} - const result_type& operator()() const { return val; } + 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 +template #else -template +template #endif -struct constant_unary_fun : public unary_function { - Result val; - constant_unary_fun(const Result& v) : val(v) {} - const Result& operator()(const Argument&) const { return val; } +struct constant_unary_fun : public unary_function<_Argument, _Result> { + _Result _M_val; + constant_unary_fun(const _Result& __v) : _M_val(__v) {} + const _Result& operator()(const _Argument&) const { return _M_val; } }; #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template +template #else -template +template #endif -struct constant_binary_fun : public binary_function { - Result val; - constant_binary_fun(const Result& v) : val(v) {} - const Result& operator()(const Arg1&, const Arg2&) const { - return val; +struct constant_binary_fun : public binary_function<_Arg1, _Arg2, _Result> { + _Result _M_val; + constant_binary_fun(const _Result& __v) : _M_val(__v) {} + const _Result& operator()(const _Arg1&, const _Arg2&) const { + return _M_val; } }; -template -inline constant_void_fun constant0(const Result& val) +template +inline constant_void_fun<_Result> constant0(const _Result& __val) { - return constant_void_fun(val); + return constant_void_fun<_Result>(__val); } -template -inline constant_unary_fun constant1(const Result& val) +template +inline constant_unary_fun<_Result,_Result> constant1(const _Result& __val) { - return constant_unary_fun(val); + return constant_unary_fun<_Result,_Result>(__val); } -template -inline constant_binary_fun constant2(const Result& val) +template +inline constant_binary_fun<_Result,_Result,_Result> +constant2(const _Result& __val) { - return constant_binary_fun(val); + return constant_binary_fun<_Result,_Result,_Result>(__val); } +// subtractive_rng is an extension: it is not part of the standard. // Note: this code assumes that int is 32 bits. class subtractive_rng : public unary_function { private: - unsigned int table[55]; - size_t index1; - size_t index2; + unsigned int _M_table[55]; + size_t _M_index1; + size_t _M_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; + unsigned int operator()(unsigned int __limit) { + _M_index1 = (_M_index1 + 1) % 55; + _M_index2 = (_M_index2 + 1) % 55; + _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2]; + return _M_table[_M_index1] % __limit; } - void initialize(unsigned int seed) + void _M_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]; + unsigned int __k = 1; + _M_table[54] = __seed; + size_t __i; + for (__i = 0; __i < 54; __i++) { + size_t __ii = (21 * (__i + 1) % 55) - 1; + _M_table[__ii] = __k; + __k = __seed - __k; + __seed = _M_table[__ii]; } - for (int loop = 0; loop < 4; loop++) { - for (i = 0; i < 55; i++) - table[i] = table[i] - table[(1 + i + 30) % 55]; + for (int __loop = 0; __loop < 4; __loop++) { + for (__i = 0; __i < 55; __i++) + _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55]; } - index1 = 0; - index2 = 31; + _M_index1 = 0; + _M_index2 = 31; } - subtractive_rng(unsigned int seed) { initialize(seed); } - subtractive_rng() { initialize(161803398u); } + subtractive_rng(unsigned int __seed) { _M_initialize(__seed); } + subtractive_rng() { _M_initialize(161803398u); } }; @@ -412,212 +470,226 @@ public: // 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 +// Note 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. +// ignore it by using the helper function mem_fun and mem_fun_ref, +// which create whichever type of adaptor is appropriate. +// (mem_fun1 and mem_fun1_ref are no longer part of the C++ standard, +// but they are provided for backward compatibility.) -template -class mem_fun_t : public unary_function { +template +class mem_fun_t : public unary_function<_Tp*,_Ret> { public: - explicit mem_fun_t(S (T::*pf)()) : f(pf) {} - S operator()(T* p) const { return (p->*f)(); } + explicit mem_fun_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} + _Ret operator()(_Tp* __p) const { return (__p->*_M_f)(); } private: - S (T::*f)(); + _Ret (_Tp::*_M_f)(); }; -template -class const_mem_fun_t : public unary_function { +template +class const_mem_fun_t : public unary_function { public: - explicit const_mem_fun_t(S (T::*pf)() const) : f(pf) {} - S operator()(const T* p) const { return (p->*f)(); } + explicit const_mem_fun_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} + _Ret operator()(const _Tp* __p) const { return (__p->*_M_f)(); } private: - S (T::*f)() const; + _Ret (_Tp::*_M_f)() const; }; -template -class mem_fun_ref_t : public unary_function { +template +class mem_fun_ref_t : public unary_function<_Tp,_Ret> { public: - explicit mem_fun_ref_t(S (T::*pf)()) : f(pf) {} - S operator()(T& r) const { return (r.*f)(); } + explicit mem_fun_ref_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} + _Ret operator()(_Tp& __r) const { return (__r.*_M_f)(); } private: - S (T::*f)(); + _Ret (_Tp::*_M_f)(); }; -template -class const_mem_fun_ref_t : public unary_function { +template +class const_mem_fun_ref_t : public unary_function<_Tp,_Ret> { public: - explicit const_mem_fun_ref_t(S (T::*pf)() const) : f(pf) {} - S operator()(const T& r) const { return (r.*f)(); } + explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} + _Ret operator()(const _Tp& __r) const { return (__r.*_M_f)(); } private: - S (T::*f)() const; + _Ret (_Tp::*_M_f)() const; }; -template -class mem_fun1_t : public binary_function { +template +class mem_fun1_t : public binary_function<_Tp*,_Arg,_Ret> { public: - explicit mem_fun1_t(S (T::*pf)(A)) : f(pf) {} - S operator()(T* p, A x) const { return (p->*f)(x); } + explicit mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + _Ret operator()(_Tp* __p, _Arg __x) const { return (__p->*_M_f)(__x); } private: - S (T::*f)(A); + _Ret (_Tp::*_M_f)(_Arg); }; -template -class const_mem_fun1_t : public binary_function { +template +class const_mem_fun1_t : public binary_function { public: - explicit const_mem_fun1_t(S (T::*pf)(A) const) : f(pf) {} - S operator()(const T* p, A x) const { return (p->*f)(x); } + explicit const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + _Ret operator()(const _Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } private: - S (T::*f)(A) const; + _Ret (_Tp::*_M_f)(_Arg) const; }; -template -class mem_fun1_ref_t : public binary_function { +template +class mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> { public: - explicit mem_fun1_ref_t(S (T::*pf)(A)) : f(pf) {} - S operator()(T& r, A x) const { return (r.*f)(x); } + explicit mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + _Ret operator()(_Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } private: - S (T::*f)(A); + _Ret (_Tp::*_M_f)(_Arg); }; -template -class const_mem_fun1_ref_t : public binary_function { +template +class const_mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> { 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); } + explicit const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + _Ret operator()(const _Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } private: - S (T::*f)(A) const; + _Ret (_Tp::*_M_f)(_Arg) const; }; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION -template -class mem_fun_t : public unary_function { +template +class mem_fun_t : public unary_function<_Tp*,void> { public: - explicit mem_fun_t(void (T::*pf)()) : f(pf) {} - void operator()(T* p) const { (p->*f)(); } + explicit mem_fun_t(void (_Tp::*__pf)()) : _M_f(__pf) {} + void operator()(_Tp* __p) const { (__p->*_M_f)(); } private: - void (T::*f)(); + void (_Tp::*_M_f)(); }; -template -class const_mem_fun_t : public unary_function { +template +class const_mem_fun_t : public unary_function { public: - explicit const_mem_fun_t(void (T::*pf)() const) : f(pf) {} - void operator()(const T* p) const { (p->*f)(); } + explicit const_mem_fun_t(void (_Tp::*__pf)() const) : _M_f(__pf) {} + void operator()(const _Tp* __p) const { (__p->*_M_f)(); } private: - void (T::*f)() const; + void (_Tp::*_M_f)() const; }; -template -class mem_fun_ref_t : public unary_function { +template +class mem_fun_ref_t : public unary_function<_Tp,void> { public: - explicit mem_fun_ref_t(void (T::*pf)()) : f(pf) {} - void operator()(T& r) const { (r.*f)(); } + explicit mem_fun_ref_t(void (_Tp::*__pf)()) : _M_f(__pf) {} + void operator()(_Tp& __r) const { (__r.*_M_f)(); } private: - void (T::*f)(); + void (_Tp::*_M_f)(); }; -template -class const_mem_fun_ref_t : public unary_function { +template +class const_mem_fun_ref_t : public unary_function<_Tp,void> { public: - explicit const_mem_fun_ref_t(void (T::*pf)() const) : f(pf) {} - void operator()(const T& r) const { (r.*f)(); } + explicit const_mem_fun_ref_t(void (_Tp::*__pf)() const) : _M_f(__pf) {} + void operator()(const _Tp& __r) const { (__r.*_M_f)(); } private: - void (T::*f)() const; + void (_Tp::*_M_f)() const; }; -template -class mem_fun1_t : public binary_function { +template +class mem_fun1_t : public binary_function<_Tp*,_Arg,void> { public: - explicit mem_fun1_t(void (T::*pf)(A)) : f(pf) {} - void operator()(T* p, A x) const { (p->*f)(x); } + explicit mem_fun1_t(void (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + void operator()(_Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); } private: - void (T::*f)(A); + void (_Tp::*_M_f)(_Arg); }; -template -class const_mem_fun1_t : public binary_function { +template +class const_mem_fun1_t + : public binary_function { public: - explicit const_mem_fun1_t(void (T::*pf)(A) const) : f(pf) {} - void operator()(const T* p, A x) const { (p->*f)(x); } + explicit const_mem_fun1_t(void (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + void operator()(const _Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); } private: - void (T::*f)(A) const; + void (_Tp::*_M_f)(_Arg) const; }; -template -class mem_fun1_ref_t : public binary_function { +template +class mem_fun1_ref_t + : public binary_function<_Tp,_Arg,void> { public: - explicit mem_fun1_ref_t(void (T::*pf)(A)) : f(pf) {} - void operator()(T& r, A x) const { (r.*f)(x); } + explicit mem_fun1_ref_t(void (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} + void operator()(_Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); } private: - void (T::*f)(A); + void (_Tp::*_M_f)(_Arg); }; -template -class const_mem_fun1_ref_t : public binary_function { +template +class const_mem_fun1_ref_t + : public binary_function<_Tp,_Arg,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); } + explicit const_mem_fun1_ref_t(void (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} + void operator()(const _Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); } private: - void (T::*f)(A) const; + void (_Tp::*_M_f)(_Arg) 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. +// Mem_fun adaptor helper functions. There are only two: +// mem_fun and mem_fun_ref. (mem_fun1 and mem_fun1_ref +// are provided for backward compatibility, but they are no longer +// part of the C++ standard.) -template -inline mem_fun_t mem_fun(S (T::*f)()) { - return mem_fun_t(f); -} +template +inline mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)()) + { return mem_fun_t<_Ret,_Tp>(__f); } -template -inline const_mem_fun_t mem_fun(S (T::*f)() const) { - return const_mem_fun_t(f); -} +template +inline const_mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)() const) + { return const_mem_fun_t<_Ret,_Tp>(__f); } -template -inline mem_fun_ref_t mem_fun_ref(S (T::*f)()) { - return mem_fun_ref_t(f); -} +template +inline mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)()) + { return mem_fun_ref_t<_Ret,_Tp>(__f); } -template -inline const_mem_fun_ref_t mem_fun_ref(S (T::*f)() const) { - return const_mem_fun_ref_t(f); -} +template +inline const_mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)() const) + { return const_mem_fun_ref_t<_Ret,_Tp>(__f); } -template -inline mem_fun1_t mem_fun1(S (T::*f)(A)) { - return mem_fun1_t(f); -} +template +inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } -template -inline const_mem_fun1_t mem_fun1(S (T::*f)(A) const) { - return const_mem_fun1_t(f); -} +template +inline const_mem_fun1_t<_Ret,_Tp,_Arg> mem_fun(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret,_Tp,_Arg>(__f); } -template -inline mem_fun1_ref_t mem_fun1_ref(S (T::*f)(A)) { - return mem_fun1_ref_t(f); -} +template +inline mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } -template -inline const_mem_fun1_ref_t mem_fun1_ref(S (T::*f)(A) const) { - return const_mem_fun1_ref_t(f); -} +template +inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> +mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +template +inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template +inline const_mem_fun1_t<_Ret,_Tp,_Arg> mem_fun1(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + +template +inline mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun1_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + +template +inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> +mem_fun1_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } __STL_END_NAMESPACE diff --git a/libstdc++/stl/stl_hash_fun.h b/libstdc++/stl/stl_hash_fun.h index 3afa9dc554d..44ab9bb5679 100644 --- a/libstdc++/stl/stl_hash_fun.h +++ b/libstdc++/stl/stl_hash_fun.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996 + * Copyright (c) 1996-1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software @@ -35,53 +35,53 @@ __STL_BEGIN_NAMESPACE -template struct hash { }; +template struct hash { }; -inline size_t __stl_hash_string(const char* s) +inline size_t __stl_hash_string(const char* __s) { - unsigned long h = 0; - for ( ; *s; ++s) - h = 5*h + *s; + unsigned long __h = 0; + for ( ; *__s; ++__s) + __h = 5*__h + *__s; - return size_t(h); + return size_t(__h); } __STL_TEMPLATE_NULL struct hash { - size_t operator()(const char* s) const { return __stl_hash_string(s); } + size_t operator()(const char* __s) const { return __stl_hash_string(__s); } }; __STL_TEMPLATE_NULL struct hash { - size_t operator()(const char* s) const { return __stl_hash_string(s); } + size_t operator()(const char* __s) const { return __stl_hash_string(__s); } }; __STL_TEMPLATE_NULL struct hash { - size_t operator()(char x) const { return x; } + size_t operator()(char __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { - size_t operator()(unsigned char x) const { return x; } + size_t operator()(unsigned char __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { - size_t operator()(unsigned char x) const { return x; } + size_t operator()(unsigned char __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { - size_t operator()(short x) const { return x; } + size_t operator()(short __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { - size_t operator()(unsigned short x) const { return x; } + size_t operator()(unsigned short __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { - size_t operator()(int x) const { return x; } + size_t operator()(int __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { - size_t operator()(unsigned int x) const { return x; } + size_t operator()(unsigned int __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { - size_t operator()(long x) const { return x; } + size_t operator()(long __x) const { return __x; } }; __STL_TEMPLATE_NULL struct hash { - size_t operator()(unsigned long x) const { return x; } + size_t operator()(unsigned long __x) const { return __x; } }; __STL_END_NAMESPACE diff --git a/libstdc++/stl/stl_hash_map.h b/libstdc++/stl/stl_hash_map.h index 9999e9a401b..bf16f60ecad 100644 --- a/libstdc++/stl/stl_hash_map.h +++ b/libstdc++/stl/stl_hash_map.h @@ -36,317 +36,375 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , - class EqualKey = equal_to, - class Alloc = alloc> +template , + class _EqualKey = equal_to<_Key>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > #else -template +template #endif class hash_map { private: - typedef hashtable, Key, HashFcn, - select1st >, EqualKey, Alloc> ht; - ht rep; + typedef hashtable,_Key,_HashFcn, + _Select1st >,_EqualKey,_Alloc> _Ht; + _Ht _M_ht; public: - typedef typename ht::key_type key_type; - typedef T data_type; - typedef T mapped_type; - typedef typename ht::value_type value_type; - typedef typename ht::hasher hasher; - typedef typename ht::key_equal key_equal; - - typedef typename ht::size_type size_type; - typedef typename ht::difference_type difference_type; - typedef typename ht::pointer pointer; - typedef typename ht::const_pointer const_pointer; - typedef typename ht::reference reference; - typedef typename ht::const_reference const_reference; - - typedef typename ht::iterator iterator; - typedef typename ht::const_iterator const_iterator; - - hasher hash_funct() const { return rep.hash_funct(); } - key_equal key_eq() const { return rep.key_eq(); } + typedef typename _Ht::key_type key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } 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) {} + hash_map() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_map(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_map(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_map(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} #ifdef __STL_MEMBER_TEMPLATES - template - hash_map(InputIterator f, InputIterator l) - : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } - template - hash_map(InputIterator f, InputIterator l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } - template - hash_map(InputIterator f, InputIterator l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } - template - hash_map(InputIterator f, InputIterator l, size_type n, - const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) { rep.insert_unique(f, l); } + template + hash_map(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_map(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.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); } + hash_map(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + + hash_map(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_map(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.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); } + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_map& __hs) { _M_ht.swap(__hs._M_ht); } friend bool operator== __STL_NULL_TMPL_ARGS (const hash_map&, const hash_map&); - iterator begin() { return rep.begin(); } - iterator end() { return rep.end(); } - const_iterator begin() const { return rep.begin(); } - const_iterator end() const { return rep.end(); } + iterator begin() { return _M_ht.begin(); } + iterator end() { return _M_ht.end(); } + const_iterator begin() const { return _M_ht.begin(); } + const_iterator end() const { return _M_ht.end(); } public: - pair insert(const value_type& obj) - { return rep.insert_unique(obj); } + pair insert(const value_type& __obj) + { return _M_ht.insert_unique(__obj); } #ifdef __STL_MEMBER_TEMPLATES - template - void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); } + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_unique(__f,__l); } #else - void insert(const value_type* f, const value_type* l) { - rep.insert_unique(f,l); + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_unique(__f,__l); } - void insert(const_iterator f, const_iterator l) { rep.insert_unique(f, l); } + void insert(const_iterator __f, const_iterator __l) + { _M_ht.insert_unique(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ - pair insert_noresize(const value_type& obj) - { return rep.insert_unique_noresize(obj); } + pair insert_noresize(const value_type& __obj) + { return _M_ht.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); } + iterator find(const key_type& __key) { return _M_ht.find(__key); } + const_iterator find(const key_type& __key) const + { return _M_ht.find(__key); } - T& operator[](const key_type& key) { - return rep.find_or_insert(value_type(key, T())).second; + _Tp& operator[](const key_type& __key) { + return _M_ht.find_or_insert(value_type(__key, _Tp())).second; } - size_type count(const key_type& key) const { return rep.count(key); } + size_type count(const key_type& __key) const { return _M_ht.count(__key); } - pair equal_range(const key_type& key) - { return rep.equal_range(key); } - pair equal_range(const key_type& key) const - { return rep.equal_range(key); } - - size_type erase(const key_type& key) {return rep.erase(key); } - void erase(iterator it) { rep.erase(it); } - void erase(iterator f, iterator l) { rep.erase(f, l); } - void clear() { rep.clear(); } - -public: - void resize(size_type hint) { rep.resize(hint); } - size_type bucket_count() const { return rep.bucket_count(); } - size_type max_bucket_count() const { return rep.max_bucket_count(); } - size_type elems_in_bucket(size_type n) const - { return rep.elems_in_bucket(n); } + pair equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + pair + equal_range(const key_type& __key) const + { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.clear(); } + + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } }; -template -inline bool operator==(const hash_map& hm1, - const hash_map& hm2) +template +inline bool +operator==(const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + const hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { - return hm1.rep == hm2.rep; + return __hm1._M_ht == __hm2._M_ht; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template -inline void swap(hash_map& hm1, - hash_map& hm2) +template +inline void +swap(hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + hash_map<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { - hm1.swap(hm2); + __hm1.swap(__hm2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , - class EqualKey = equal_to, - class Alloc = alloc> +template , + class _EqualKey = equal_to<_Key>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > #else -template +template #endif class hash_multimap { private: - typedef hashtable, Key, HashFcn, - select1st >, EqualKey, Alloc> ht; - ht rep; + typedef hashtable, _Key, _HashFcn, + _Select1st >, _EqualKey, _Alloc> + _Ht; + _Ht _M_ht; public: - typedef typename ht::key_type key_type; - typedef T data_type; - typedef T mapped_type; - typedef typename ht::value_type value_type; - typedef typename ht::hasher hasher; - typedef typename ht::key_equal key_equal; - - typedef typename ht::size_type size_type; - typedef typename ht::difference_type difference_type; - typedef typename ht::pointer pointer; - typedef typename ht::const_pointer const_pointer; - typedef typename ht::reference reference; - typedef typename ht::const_reference const_reference; - - typedef typename ht::iterator iterator; - typedef typename ht::const_iterator const_iterator; - - hasher hash_funct() const { return rep.hash_funct(); } - key_equal key_eq() const { return rep.key_eq(); } + typedef typename _Ht::key_type key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } 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) {} + hash_multimap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_multimap(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_multimap(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} #ifdef __STL_MEMBER_TEMPLATES - template - hash_multimap(InputIterator f, InputIterator l) - : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } - template - hash_multimap(InputIterator f, InputIterator l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } - template - hash_multimap(InputIterator f, InputIterator l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } - template - hash_multimap(InputIterator f, InputIterator l, size_type n, - const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) { rep.insert_equal(f, l); } + template + hash_multimap(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.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); } + hash_multimap(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + + hash_multimap(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multimap(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.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); } + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_multimap& __hs) { _M_ht.swap(__hs._M_ht); } friend bool - operator== __STL_NULL_TMPL_ARGS (const hash_multimap&, const hash_multimap&); + operator== __STL_NULL_TMPL_ARGS (const hash_multimap&, + const hash_multimap&); - iterator begin() { return rep.begin(); } - iterator end() { return rep.end(); } - const_iterator begin() const { return rep.begin(); } - const_iterator end() const { return rep.end(); } + iterator begin() { return _M_ht.begin(); } + iterator end() { return _M_ht.end(); } + const_iterator begin() const { return _M_ht.begin(); } + const_iterator end() const { return _M_ht.end(); } public: - iterator insert(const value_type& obj) { return rep.insert_equal(obj); } + iterator insert(const value_type& __obj) + { return _M_ht.insert_equal(__obj); } #ifdef __STL_MEMBER_TEMPLATES - template - void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); } + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_equal(__f,__l); } #else - void insert(const value_type* f, const value_type* l) { - rep.insert_equal(f,l); + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_equal(__f,__l); } - void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); } + void insert(const_iterator __f, const_iterator __l) + { _M_ht.insert_equal(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ - iterator insert_noresize(const value_type& obj) - { return rep.insert_equal_noresize(obj); } + iterator insert_noresize(const value_type& __obj) + { return _M_ht.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); } + iterator find(const key_type& __key) { return _M_ht.find(__key); } + const_iterator find(const key_type& __key) const + { return _M_ht.find(__key); } - size_type count(const key_type& key) const { return rep.count(key); } + size_type count(const key_type& __key) const { return _M_ht.count(__key); } - pair equal_range(const key_type& key) - { return rep.equal_range(key); } - pair equal_range(const key_type& key) const - { return rep.equal_range(key); } + pair equal_range(const key_type& __key) + { return _M_ht.equal_range(__key); } + pair + equal_range(const key_type& __key) const + { return _M_ht.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(); } + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.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); } + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } }; -template -inline bool operator==(const hash_multimap& hm1, - const hash_multimap& hm2) +template +inline bool +operator==(const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm1, + const hash_multimap<_Key,_Tp,_HF,_EqKey,_Alloc>& __hm2) { - return hm1.rep == hm2.rep; + return __hm1._M_ht == __hm2._M_ht; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template -inline void swap(hash_multimap& hm1, - hash_multimap& hm2) +template +inline void +swap(hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm1, + hash_multimap<_Key,_Tp,_HashFcn,_EqlKey,_Alloc>& __hm2) { - hm1.swap(hm2); + __hm1.swap(__hm2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/libstdc++/stl/stl_hash_set.h b/libstdc++/stl/stl_hash_set.h index 1ba87c48497..b623a642cfc 100644 --- a/libstdc++/stl/stl_hash_set.h +++ b/libstdc++/stl/stl_hash_set.h @@ -35,303 +35,361 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , - class EqualKey = equal_to, - class Alloc = alloc> +template , + class _EqualKey = equal_to<_Value>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > #else -template +template #endif class hash_set { private: - typedef hashtable, - EqualKey, Alloc> ht; - ht rep; + typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, + _EqualKey, _Alloc> _Ht; + _Ht _M_ht; public: - typedef typename ht::key_type key_type; - typedef typename ht::value_type value_type; - typedef typename ht::hasher hasher; - typedef typename ht::key_equal key_equal; + typedef typename _Ht::key_type key_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; - typedef typename ht::size_type size_type; - typedef typename ht::difference_type difference_type; - typedef typename ht::const_pointer pointer; - typedef typename ht::const_pointer const_pointer; - typedef typename ht::const_reference reference; - typedef typename ht::const_reference const_reference; + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::const_pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::const_reference reference; + typedef typename _Ht::const_reference const_reference; - typedef typename ht::const_iterator iterator; - typedef typename ht::const_iterator const_iterator; + typedef typename _Ht::const_iterator iterator; + typedef typename _Ht::const_iterator const_iterator; - hasher hash_funct() const { return rep.hash_funct(); } - key_equal key_eq() const { return rep.key_eq(); } + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } 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) {} + hash_set() + : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_set(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_set(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} #ifdef __STL_MEMBER_TEMPLATES - template - hash_set(InputIterator f, InputIterator l) - : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); } - template - hash_set(InputIterator f, InputIterator l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); } - template - hash_set(InputIterator f, InputIterator l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_unique(f, l); } - template - hash_set(InputIterator f, InputIterator l, size_type n, - const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) { rep.insert_unique(f, l); } + template + hash_set(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + template + hash_set(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.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); } + hash_set(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + + hash_set(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + hash_set(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.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); } + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_set& __hs) { _M_ht.swap(__hs._M_ht); } friend bool operator== __STL_NULL_TMPL_ARGS (const hash_set&, const hash_set&); - iterator begin() const { return rep.begin(); } - iterator end() const { return rep.end(); } + iterator begin() const { return _M_ht.begin(); } + iterator end() const { return _M_ht.end(); } public: - pair insert(const value_type& obj) + pair insert(const value_type& __obj) { - pair p = rep.insert_unique(obj); - return pair(p.first, p.second); + pair __p = _M_ht.insert_unique(__obj); + return pair(__p.first, __p.second); } #ifdef __STL_MEMBER_TEMPLATES - template - void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); } + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_unique(__f,__l); } #else - void insert(const value_type* f, const value_type* l) { - rep.insert_unique(f,l); + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_unique(__f,__l); } - void insert(const_iterator f, const_iterator l) {rep.insert_unique(f, l); } + void insert(const_iterator __f, const_iterator __l) + {_M_ht.insert_unique(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ - pair insert_noresize(const value_type& obj) + pair insert_noresize(const value_type& __obj) { - pair p = rep.insert_unique_noresize(obj); - return pair(p.first, p.second); + pair __p = + _M_ht.insert_unique_noresize(__obj); + return pair(__p.first, __p.second); } - iterator find(const key_type& key) const { return rep.find(key); } + iterator find(const key_type& __key) const { return _M_ht.find(__key); } - size_type count(const key_type& key) const { return rep.count(key); } + size_type count(const key_type& __key) const { return _M_ht.count(__key); } - pair equal_range(const key_type& key) const - { return rep.equal_range(key); } + pair equal_range(const key_type& __key) const + { return _M_ht.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(); } + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.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); } + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } }; -template -inline bool operator==(const hash_set& hs1, - const hash_set& hs2) +template +inline bool +operator==(const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_set<_Value,_HashFcn,_EqualKey,_Alloc>& __hs2) { - return hs1.rep == hs2.rep; + return __hs1._M_ht == __hs2._M_ht; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template -inline void swap(hash_set& hs1, - hash_set& hs2) { - hs1.swap(hs2); +template +inline void +swap(hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + hash_set<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) +{ + __hs1.swap(__hs2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , - class EqualKey = equal_to, - class Alloc = alloc> +template , + class _EqualKey = equal_to<_Value>, + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Value) > #else -template +template #endif class hash_multiset { private: - typedef hashtable, - EqualKey, Alloc> ht; - ht rep; + typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>, + _EqualKey, _Alloc> _Ht; + _Ht _M_ht; public: - typedef typename ht::key_type key_type; - typedef typename ht::value_type value_type; - typedef typename ht::hasher hasher; - typedef typename ht::key_equal key_equal; + typedef typename _Ht::key_type key_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; - typedef typename ht::size_type size_type; - typedef typename ht::difference_type difference_type; - typedef typename ht::const_pointer pointer; - typedef typename ht::const_pointer const_pointer; - typedef typename ht::const_reference reference; - typedef typename ht::const_reference const_reference; + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::const_pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::const_reference reference; + typedef typename _Ht::const_reference const_reference; - typedef typename ht::const_iterator iterator; - typedef typename ht::const_iterator const_iterator; + typedef typename _Ht::const_iterator iterator; + typedef typename _Ht::const_iterator const_iterator; - hasher hash_funct() const { return rep.hash_funct(); } - key_equal key_eq() const { return rep.key_eq(); } + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + key_equal key_eq() const { return _M_ht.key_eq(); } + allocator_type get_allocator() const { return _M_ht.get_allocator(); } 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) {} + hash_multiset() + : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + explicit hash_multiset(size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + hash_multiset(size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) {} #ifdef __STL_MEMBER_TEMPLATES - template - hash_multiset(InputIterator f, InputIterator l) - : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); } - template - hash_multiset(InputIterator f, InputIterator l, size_type n) - : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); } - template - hash_multiset(InputIterator f, InputIterator l, size_type n, - const hasher& hf) - : rep(n, hf, key_equal()) { rep.insert_equal(f, l); } - template - hash_multiset(InputIterator f, InputIterator l, size_type n, - const hasher& hf, const key_equal& eql) - : rep(n, hf, eql) { rep.insert_equal(f, l); } + template + hash_multiset(_InputIterator __f, _InputIterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + template + hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.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); } + hash_multiset(const value_type* __f, const value_type* __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const value_type* __f, const value_type* __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const value_type* __f, const value_type* __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + + hash_multiset(const_iterator __f, const_iterator __l) + : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const_iterator __f, const_iterator __l, size_type __n) + : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + hash_multiset(const_iterator __f, const_iterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.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); } + size_type size() const { return _M_ht.size(); } + size_type max_size() const { return _M_ht.max_size(); } + bool empty() const { return _M_ht.empty(); } + void swap(hash_multiset& hs) { _M_ht.swap(hs._M_ht); } friend bool operator== __STL_NULL_TMPL_ARGS (const hash_multiset&, const hash_multiset&); - iterator begin() const { return rep.begin(); } - iterator end() const { return rep.end(); } + iterator begin() const { return _M_ht.begin(); } + iterator end() const { return _M_ht.end(); } public: - iterator insert(const value_type& obj) { return rep.insert_equal(obj); } + iterator insert(const value_type& __obj) + { return _M_ht.insert_equal(__obj); } #ifdef __STL_MEMBER_TEMPLATES - template - void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); } + template + void insert(_InputIterator __f, _InputIterator __l) + { _M_ht.insert_equal(__f,__l); } #else - void insert(const value_type* f, const value_type* l) { - rep.insert_equal(f,l); + void insert(const value_type* __f, const value_type* __l) { + _M_ht.insert_equal(__f,__l); } - void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); } + void insert(const_iterator __f, const_iterator __l) + { _M_ht.insert_equal(__f, __l); } #endif /*__STL_MEMBER_TEMPLATES */ - iterator insert_noresize(const value_type& obj) - { return rep.insert_equal_noresize(obj); } + iterator insert_noresize(const value_type& __obj) + { return _M_ht.insert_equal_noresize(__obj); } - iterator find(const key_type& key) const { return rep.find(key); } + iterator find(const key_type& __key) const { return _M_ht.find(__key); } - size_type count(const key_type& key) const { return rep.count(key); } + size_type count(const key_type& __key) const { return _M_ht.count(__key); } - pair equal_range(const key_type& key) const - { return rep.equal_range(key); } + pair equal_range(const key_type& __key) const + { return _M_ht.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(); } + size_type erase(const key_type& __key) {return _M_ht.erase(__key); } + void erase(iterator __it) { _M_ht.erase(__it); } + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + void clear() { _M_ht.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); } + void resize(size_type __hint) { _M_ht.resize(__hint); } + size_type bucket_count() const { return _M_ht.bucket_count(); } + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + size_type elems_in_bucket(size_type __n) const + { return _M_ht.elems_in_bucket(__n); } }; -template -inline bool operator==(const hash_multiset& hs1, - const hash_multiset& hs2) +template +inline bool +operator==(const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + const hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { - return hs1.rep == hs2.rep; + return __hs1._M_ht == __hs2._M_ht; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template -inline void swap(hash_multiset& hs1, - hash_multiset& hs2) -{ - hs1.swap(hs2); +template +inline void +swap(hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs1, + hash_multiset<_Val,_HashFcn,_EqualKey,_Alloc>& __hs2) { + __hs1.swap(__hs2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/libstdc++/stl/stl_hashtable.h b/libstdc++/stl/stl_hashtable.h index e5b63b271de..78b36c1d5a0 100644 --- a/libstdc++/stl/stl_hashtable.h +++ b/libstdc++/stl/stl_hashtable.h @@ -46,128 +46,150 @@ __STL_BEGIN_NAMESPACE -template -struct __hashtable_node +template +struct _Hashtable_node { - __hashtable_node* next; - Value val; + _Hashtable_node* _M_next; + _Val _M_val; }; -template +template class hashtable; -template -struct __hashtable_iterator; - -template -struct __hashtable_const_iterator; - -template -struct __hashtable_iterator { - typedef hashtable - hashtable; - typedef __hashtable_iterator +template +struct _Hashtable_iterator; + +template +struct _Hashtable_const_iterator; + +template +struct _Hashtable_iterator { + typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> iterator; - typedef __hashtable_const_iterator + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> const_iterator; - typedef __hashtable_node node; + typedef _Hashtable_node<_Val> _Node; typedef forward_iterator_tag iterator_category; - typedef Value value_type; + typedef _Val value_type; typedef ptrdiff_t difference_type; typedef size_t size_type; - typedef Value& reference; - typedef Value* pointer; + typedef _Val& reference; + typedef _Val* pointer; - node* cur; - hashtable* ht; + _Node* _M_cur; + _Hashtable* _M_ht; - __hashtable_iterator(node* n, hashtable* tab) : cur(n), ht(tab) {} - __hashtable_iterator() {} - reference operator*() const { return cur->val; } + _Hashtable_iterator(_Node* __n, _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) {} + _Hashtable_iterator() {} + reference operator*() const { return _M_cur->_M_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; } + bool operator==(const iterator& __it) const + { return _M_cur == __it._M_cur; } + bool operator!=(const iterator& __it) const + { return _M_cur != __it._M_cur; } }; -template -struct __hashtable_const_iterator { - typedef hashtable - hashtable; - typedef __hashtable_iterator +template +struct _Hashtable_const_iterator { + typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val,_Key,_HashFcn, + _ExtractKey,_EqualKey,_Alloc> iterator; - typedef __hashtable_const_iterator + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> const_iterator; - typedef __hashtable_node node; + typedef _Hashtable_node<_Val> _Node; typedef forward_iterator_tag iterator_category; - typedef Value value_type; + typedef _Val 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; } + typedef const _Val& reference; + typedef const _Val* pointer; + + const _Node* _M_cur; + const _Hashtable* _M_ht; + + _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) {} + _Hashtable_const_iterator() {} + _Hashtable_const_iterator(const iterator& __it) + : _M_cur(__it._M_cur), _M_ht(__it._M_ht) {} + reference operator*() const { return _M_cur->_M_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; } + bool operator==(const const_iterator& __it) const + { return _M_cur == __it._M_cur; } + bool operator!=(const const_iterator& __it) const + { return _M_cur != __it._M_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, 3221225473ul, 4294967291ul + 53ul, 97ul, 193ul, 389ul, 769ul, + 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, + 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, + 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, + 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, + 1610612741ul, 3221225473ul, 4294967291ul }; -inline unsigned long __stl_next_prime(unsigned long n) +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; + 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; } +// Forward declaration of operator==. + +template +class hashtable; + +template +bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2); -template + +// Hashtables handle allocators a bit differently than other containers +// do. If we're using standard-conforming allocators, then a hashtable +// unconditionally has a member variable to hold its allocator, even if +// it so happens that all instances of the allocator type are identical. +// This is because, for hashtables, this extra storage is negligible. +// Additionally, a base class wouldn't serve any other purposes; it +// wouldn't, for example, simplify the exception-handling code. + +template class hashtable { public: - typedef Key key_type; - typedef Value value_type; - typedef HashFcn hasher; - typedef EqualKey key_equal; + typedef _Key key_type; + typedef _Val value_type; + typedef _HashFcn hasher; + typedef _EqualKey key_equal; typedef size_t size_type; typedef ptrdiff_t difference_type; @@ -176,90 +198,126 @@ public: typedef value_type& reference; typedef const value_type& const_reference; - hasher hash_funct() const { return hash; } - key_equal key_eq() const { return equals; } + hasher hash_funct() const { return _M_hash; } + key_equal key_eq() const { return _M_equals; } private: - hasher hash; - key_equal equals; - ExtractKey get_key; + typedef _Hashtable_node<_Val> _Node; - typedef __hashtable_node node; - typedef simple_alloc node_allocator; +#ifdef __STL_USE_STD_ALLOCATORS +public: + typedef typename _Alloc_traits<_Val,_Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } +private: + typename _Alloc_traits<_Node, _Alloc>::allocator_type _M_node_allocator; + _Node* _M_get_node() { return _M_node_allocator.allocate(1); } + void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); } +# define __HASH_ALLOC_INIT(__a) _M_node_allocator(__a), +#else /* __STL_USE_STD_ALLOCATORS */ +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } +private: + typedef simple_alloc<_Node, _Alloc> _M_node_allocator_type; + _Node* _M_get_node() { return _M_node_allocator_type::allocate(1); } + void _M_put_node(_Node* __p) { _M_node_allocator_type::deallocate(__p, 1); } +# define __HASH_ALLOC_INIT(__a) +#endif /* __STL_USE_STD_ALLOCATORS */ - vector buckets; - size_type num_elements; +private: + hasher _M_hash; + key_equal _M_equals; + _ExtractKey _M_get_key; + vector<_Node*,_Alloc> _M_buckets; + size_type _M_num_elements; public: - typedef __hashtable_iterator - iterator; - - typedef __hashtable_const_iterator - const_iterator; + typedef _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey, + _Alloc> + const_iterator; friend struct - __hashtable_iterator; + _Hashtable_iterator<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>; friend struct - __hashtable_const_iterator; + _Hashtable_const_iterator<_Val,_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) + hashtable(size_type __n, + const _HashFcn& __hf, + const _EqualKey& __eql, + const _ExtractKey& __ext, + const allocator_type& __a = allocator_type()) + : __HASH_ALLOC_INIT(__a) + _M_hash(__hf), + _M_equals(__eql), + _M_get_key(__ext), + _M_buckets(__a), + _M_num_elements(0) { - initialize_buckets(n); + _M_initialize_buckets(__n); } - hashtable(size_type n, - const HashFcn& hf, - const EqualKey& eql) - : hash(hf), equals(eql), get_key(ExtractKey()), num_elements(0) + hashtable(size_type __n, + const _HashFcn& __hf, + const _EqualKey& __eql, + const allocator_type& __a = allocator_type()) + : __HASH_ALLOC_INIT(__a) + _M_hash(__hf), + _M_equals(__eql), + _M_get_key(_ExtractKey()), + _M_buckets(__a), + _M_num_elements(0) { - initialize_buckets(n); + _M_initialize_buckets(__n); } - hashtable(const hashtable& ht) - : hash(ht.hash), equals(ht.equals), get_key(ht.get_key), num_elements(0) + hashtable(const hashtable& __ht) + : __HASH_ALLOC_INIT(__ht.get_allocator()) + _M_hash(__ht._M_hash), + _M_equals(__ht._M_equals), + _M_get_key(__ht._M_get_key), + _M_buckets(__ht.get_allocator()), + _M_num_elements(0) { - copy_from(ht); + _M_copy_from(__ht); } - hashtable& operator= (const hashtable& ht) +#undef __HASH_ALLOC_INIT + + hashtable& operator= (const hashtable& __ht) { - if (&ht != this) { + if (&__ht != this) { clear(); - hash = ht.hash; - equals = ht.equals; - get_key = ht.get_key; - copy_from(ht); + _M_hash = __ht._M_hash; + _M_equals = __ht._M_equals; + _M_get_key = __ht._M_get_key; + _M_copy_from(__ht); } return *this; } ~hashtable() { clear(); } - size_type size() const { return num_elements; } + size_type size() const { return _M_num_elements; } size_type max_size() const { return size_type(-1); } bool empty() const { return size() == 0; } - void swap(hashtable& ht) + void swap(hashtable& __ht) { - __STD::swap(hash, ht.hash); - __STD::swap(equals, ht.equals); - __STD::swap(get_key, ht.get_key); - buckets.swap(ht.buckets); - __STD::swap(num_elements, ht.num_elements); + __STD::swap(_M_hash, __ht._M_hash); + __STD::swap(_M_equals, __ht._M_equals); + __STD::swap(_M_get_key, __ht._M_get_key); + _M_buckets.swap(__ht._M_buckets); + __STD::swap(_M_num_elements, __ht._M_num_elements); } iterator begin() { - for (size_type n = 0; n < buckets.size(); ++n) - if (buckets[n]) - return iterator(buckets[n], this); + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return iterator(_M_buckets[__n], this); return end(); } @@ -267,9 +325,9 @@ public: const_iterator begin() const { - for (size_type n = 0; n < buckets.size(); ++n) - if (buckets[n]) - return const_iterator(buckets[n], this); + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return const_iterator(_M_buckets[__n], this); return end(); } @@ -280,329 +338,345 @@ public: public: - size_type bucket_count() const { return buckets.size(); } + size_type bucket_count() const { return _M_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 elems_in_bucket(size_type __bucket) const { - size_type result = 0; - for (node* cur = buckets[bucket]; cur; cur = cur->next) - result += 1; - return result; + size_type __result = 0; + for (_Node* __cur = _M_buckets[__bucket]; __cur; __cur = __cur->_M_next) + __result += 1; + return __result; } - pair insert_unique(const value_type& obj) + pair insert_unique(const value_type& __obj) { - resize(num_elements + 1); - return insert_unique_noresize(obj); + resize(_M_num_elements + 1); + return insert_unique_noresize(__obj); } - iterator insert_equal(const value_type& obj) + iterator insert_equal(const value_type& __obj) { - resize(num_elements + 1); - return insert_equal_noresize(obj); + resize(_M_num_elements + 1); + return insert_equal_noresize(__obj); } - pair insert_unique_noresize(const value_type& obj); - iterator insert_equal_noresize(const value_type& obj); + pair insert_unique_noresize(const value_type& __obj); + iterator insert_equal_noresize(const value_type& __obj); #ifdef __STL_MEMBER_TEMPLATES - template - void insert_unique(InputIterator f, InputIterator l) + template + void insert_unique(_InputIterator __f, _InputIterator __l) { - insert_unique(f, l, iterator_category(f)); + insert_unique(__f, __l, __ITERATOR_CATEGORY(__f)); } - template - void insert_equal(InputIterator f, InputIterator l) + template + void insert_equal(_InputIterator __f, _InputIterator __l) { - insert_equal(f, l, iterator_category(f)); + insert_equal(__f, __l, __ITERATOR_CATEGORY(__f)); } - template - void insert_unique(InputIterator f, InputIterator l, + template + void insert_unique(_InputIterator __f, _InputIterator __l, input_iterator_tag) { - for ( ; f != l; ++f) - insert_unique(*f); + for ( ; __f != __l; ++__f) + insert_unique(*__f); } - template - void insert_equal(InputIterator f, InputIterator l, + template + void insert_equal(_InputIterator __f, _InputIterator __l, input_iterator_tag) { - for ( ; f != l; ++f) - insert_equal(*f); + for ( ; __f != __l; ++__f) + insert_equal(*__f); } - template - void insert_unique(ForwardIterator f, ForwardIterator l, + template + void insert_unique(_ForwardIterator __f, _ForwardIterator __l, forward_iterator_tag) { - size_type n = 0; - distance(f, l, n); - resize(num_elements + n); - for ( ; n > 0; --n, ++f) - insert_unique_noresize(*f); + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); } - template - void insert_equal(ForwardIterator f, ForwardIterator l, + template + void insert_equal(_ForwardIterator __f, _ForwardIterator __l, forward_iterator_tag) { - size_type n = 0; - distance(f, l, n); - resize(num_elements + n); - for ( ; n > 0; --n, ++f) - insert_equal_noresize(*f); + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_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) + 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); + size_type __n = __l - __f; + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); } - void insert_equal(const value_type* f, const value_type* l) + 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); + size_type __n = __l - __f; + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); } - void insert_unique(const_iterator f, const_iterator l) + 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); + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); } - void insert_equal(const_iterator f, const_iterator l) + 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); + size_type __n = 0; + distance(__f, __l, __n); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); } #endif /*__STL_MEMBER_TEMPLATES */ - reference find_or_insert(const value_type& obj); + reference find_or_insert(const value_type& __obj); - iterator find(const key_type& key) + 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) + size_type __n = _M_bkt_num_key(__key); + _Node* __first; + for ( __first = _M_buckets[__n]; + __first && !_M_equals(_M_get_key(__first->_M_val), __key); + __first = __first->_M_next) {} - return iterator(first, this); + return iterator(__first, this); } - const_iterator find(const key_type& key) const + 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) + size_type __n = _M_bkt_num_key(__key); + const _Node* __first; + for ( __first = _M_buckets[__n]; + __first && !_M_equals(_M_get_key(__first->_M_val), __key); + __first = __first->_M_next) {} - return const_iterator(first, this); + return const_iterator(__first, this); } - size_type count(const key_type& key) const + size_type count(const key_type& __key) const { - const size_type n = bkt_num_key(key); - size_type result = 0; + const size_type __n = _M_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; + for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), __key)) + ++__result; + return __result; } - pair equal_range(const key_type& key); - pair equal_range(const key_type& key) const; + pair + equal_range(const key_type& __key); - size_type erase(const key_type& key); - void erase(const iterator& it); - void erase(iterator first, iterator last); + pair + equal_range(const key_type& __key) const; - void erase(const const_iterator& it); - void erase(const_iterator first, const_iterator last); + size_type erase(const key_type& __key); + void erase(const iterator& __it); + void erase(iterator __first, iterator __last); - void resize(size_type num_elements_hint); + 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); } + size_type _M_next_size(size_type __n) const + { return __stl_next_prime(__n); } - void initialize_buckets(size_type n) + void _M_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; + const size_type __n_buckets = _M_next_size(__n); + _M_buckets.reserve(__n_buckets); + _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0); + _M_num_elements = 0; } - size_type bkt_num_key(const key_type& key) const + size_type _M_bkt_num_key(const key_type& __key) const { - return bkt_num_key(key, buckets.size()); + return _M_bkt_num_key(__key, _M_buckets.size()); } - size_type bkt_num(const value_type& obj) const + size_type _M_bkt_num(const value_type& __obj) const { - return bkt_num_key(get_key(obj)); + return _M_bkt_num_key(_M_get_key(__obj)); } - size_type bkt_num_key(const key_type& key, size_t n) const + size_type _M_bkt_num_key(const key_type& __key, size_t __n) const { - return hash(key) % n; + return _M_hash(__key) % __n; } - size_type bkt_num(const value_type& obj, size_t n) const + size_type _M_bkt_num(const value_type& __obj, size_t __n) const { - return bkt_num_key(get_key(obj), n); + return _M_bkt_num_key(_M_get_key(__obj), __n); } - node* new_node(const value_type& obj) + _Node* _M_new_node(const value_type& __obj) { - node* n = node_allocator::allocate(); - n->next = 0; + _Node* __n = _M_get_node(); + __n->_M_next = 0; __STL_TRY { - construct(&n->val, obj); - return n; + construct(&__n->_M_val, __obj); + return __n; } - __STL_UNWIND(node_allocator::deallocate(n)); + __STL_UNWIND(_M_put_node(__n)); } - void delete_node(node* n) + void _M_delete_node(_Node* __n) { - destroy(&n->val); - node_allocator::deallocate(n); + destroy(&__n->_M_val); + _M_put_node(__n); } - void erase_bucket(const size_type n, node* first, node* last); - void erase_bucket(const size_type n, node* last); + void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); + void _M_erase_bucket(const size_type __n, _Node* __last); - void copy_from(const hashtable& ht); + void _M_copy_from(const hashtable& __ht); }; -template -__hashtable_iterator& -__hashtable_iterator::operator++() +template +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::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]; + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; } return *this; } -template -inline __hashtable_iterator -__hashtable_iterator::operator++(int) +template +inline _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> +_Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int) { - iterator tmp = *this; + iterator __tmp = *this; ++*this; - return tmp; + return __tmp; } -template -__hashtable_const_iterator& -__hashtable_const_iterator::operator++() +template +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>& +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::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]; + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; } return *this; } -template -inline __hashtable_const_iterator -__hashtable_const_iterator::operator++(int) +template +inline _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All> +_Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>::operator++(int) { - const_iterator tmp = *this; + const_iterator __tmp = *this; ++*this; - return tmp; + return __tmp; } #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -template +template inline forward_iterator_tag -iterator_category(const __hashtable_iterator&) +iterator_category(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { return forward_iterator_tag(); } -template -inline V* value_type(const __hashtable_iterator&) +template +inline _Val* +value_type(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { - return (V*) 0; + return (_Val*) 0; } -template -inline hashtable::difference_type* -distance_type(const __hashtable_iterator&) +template +inline hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type* +distance_type(const _Hashtable_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { - return (hashtable::difference_type*) 0; + return (hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type*) 0; } -template +template inline forward_iterator_tag -iterator_category(const __hashtable_const_iterator&) +iterator_category(const _Hashtable_const_iterator<_Val,_Key,_HF, + _ExK,_EqK,_All>&) { return forward_iterator_tag(); } -template -inline V* -value_type(const __hashtable_const_iterator&) +template +inline _Val* +value_type(const _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { - return (V*) 0; + return (_Val*) 0; } -template -inline hashtable::difference_type* -distance_type(const __hashtable_const_iterator&) +template +inline hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type* +distance_type(const _Hashtable_const_iterator<_Val,_Key,_HF,_ExK,_EqK,_All>&) { - return (hashtable::difference_type*) 0; + return (hashtable<_Val,_Key,_HF,_ExK,_EqK,_All>::difference_type*) 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template -bool operator==(const hashtable& ht1, - const hashtable& ht2) +template +inline bool operator==(const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht1, + const hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>& __ht2) { - typedef typename hashtable::node node; - if (ht1.buckets.size() != ht2.buckets.size()) + typedef typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::_Node _Node; + if (__ht1._M_buckets.size() != __ht2._M_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) + for (int __n = 0; __n < __ht1._M_buckets.size(); ++__n) { + _Node* __cur1 = __ht1._M_buckets[__n]; + _Node* __cur2 = __ht2._M_buckets[__n]; + for ( ; __cur1 && __cur2 && __cur1->_M_val == __cur2->_M_val; + __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) {} - if (cur1 || cur2) + if (__cur1 || __cur2) return false; } return true; @@ -610,253 +684,265 @@ bool operator==(const hashtable& ht1, #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template -inline void swap(hashtable& ht1, - hashtable& ht2) { - ht1.swap(ht2); +template +inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, + hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) { + __ht1.swap(__ht2); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ -template -pair::iterator, bool> -hashtable::insert_unique_noresize(const value_type& obj) +template +pair::iterator, bool> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::insert_unique_noresize(const value_type& __obj) { - const size_type n = bkt_num(obj); - node* first = buckets[n]; - - for (node* cur = first; cur; cur = cur->next) - if (equals(get_key(cur->val), get_key(obj))) - return pair(iterator(cur, this), false); - - node* tmp = new_node(obj); - tmp->next = first; - buckets[n] = tmp; - ++num_elements; - return pair(iterator(tmp, this), true); + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return pair(iterator(__cur, this), false); + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return pair(iterator(__tmp, this), true); } -template -typename hashtable::iterator -hashtable::insert_equal_noresize(const value_type& obj) +template +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::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); + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) { + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __cur->_M_next; + __cur->_M_next = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); } - node* tmp = new_node(obj); - tmp->next = first; - buckets[n] = tmp; - ++num_elements; - return iterator(tmp, this); + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); } -template -typename hashtable::reference -hashtable::find_or_insert(const value_type& obj) +template +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::reference +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::find_or_insert(const value_type& __obj) { - resize(num_elements + 1); + resize(_M_num_elements + 1); - size_type n = bkt_num(obj); - node* first = buckets[n]; + size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; - for (node* cur = first; cur; cur = cur->next) - if (equals(get_key(cur->val), get_key(obj))) - return cur->val; + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return __cur->_M_val; - node* tmp = new_node(obj); - tmp->next = first; - buckets[n] = tmp; - ++num_elements; - return tmp->val; + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return __tmp->_M_val; } -template -pair::iterator, - typename hashtable::iterator> -hashtable::equal_range(const key_type& key) +template +pair::iterator, + typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::iterator> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::equal_range(const key_type& __key) { - typedef pair pii; - const size_type n = bkt_num_key(key); - - for (node* first = buckets[n]; first; first = first->next) { - if (equals(get_key(first->val), key)) { - for (node* cur = first->next; cur; cur = cur->next) - if (!equals(get_key(cur->val), key)) - return pii(iterator(first, this), iterator(cur, this)); - for (size_type m = n + 1; m < buckets.size(); ++m) - if (buckets[m]) - return pii(iterator(first, this), - iterator(buckets[m], this)); - return pii(iterator(first, this), end()); + typedef pair _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (_Node* __first = _M_buckets[__n]; __first; __first = __first->_M_next) + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + for (_Node* __cur = __first->_M_next; __cur; __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(iterator(__first, this), iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(iterator(__first, this), + iterator(_M_buckets[__m], this)); + return _Pii(iterator(__first, this), end()); } - } - return pii(end(), end()); + return _Pii(end(), end()); } -template -pair::const_iterator, - typename hashtable::const_iterator> -hashtable::equal_range(const key_type& key) const +template +pair::const_iterator, + typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::const_iterator> +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::equal_range(const key_type& __key) const { - typedef pair pii; - const size_type n = bkt_num_key(key); - - for (const node* first = buckets[n] ; first; first = first->next) { - if (equals(get_key(first->val), key)) { - for (const node* cur = first->next; cur; cur = cur->next) - if (!equals(get_key(cur->val), key)) - return pii(const_iterator(first, this), - const_iterator(cur, this)); - for (size_type m = n + 1; m < buckets.size(); ++m) - if (buckets[m]) - return pii(const_iterator(first, this), - const_iterator(buckets[m], this)); - return pii(const_iterator(first, this), end()); + typedef pair _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (const _Node* __first = _M_buckets[__n] ; + __first; + __first = __first->_M_next) { + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + for (const _Node* __cur = __first->_M_next; + __cur; + __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(const_iterator(__first, this), + const_iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(const_iterator(__first, this), + const_iterator(_M_buckets[__m], this)); + return _Pii(const_iterator(__first, this), end()); } } - return pii(end(), end()); + return _Pii(end(), end()); } -template -typename hashtable::size_type -hashtable::erase(const key_type& key) +template +typename hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::size_type +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::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; + const size_type __n = _M_bkt_num_key(__key); + _Node* __first = _M_buckets[__n]; + size_type __erased = 0; + + if (__first) { + _Node* __cur = __first; + _Node* __next = __cur->_M_next; + while (__next) { + if (_M_equals(_M_get_key(__next->_M_val), __key)) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + ++__erased; + --_M_num_elements; } else { - cur = next; - next = cur->next; + __cur = __next; + __next = __cur->_M_next; } } - if (equals(get_key(first->val), key)) { - buckets[n] = first->next; - delete_node(first); - ++erased; - --num_elements; + if (_M_equals(_M_get_key(__first->_M_val), __key)) { + _M_buckets[__n] = __first->_M_next; + _M_delete_node(__first); + ++__erased; + --_M_num_elements; } } - return erased; + return __erased; } -template -void hashtable::erase(const iterator& it) +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::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; + if (_Node* const __p = __it._M_cur) { + const size_type __n = _M_bkt_num(__p->_M_val); + _Node* __cur = _M_buckets[__n]; + + if (__cur == __p) { + _M_buckets[__n] = __cur->_M_next; + _M_delete_node(__cur); + --_M_num_elements; } else { - node* next = cur->next; - while (next) { - if (next == p) { - cur->next = next->next; - delete_node(next); - --num_elements; + _Node* __next = __cur->_M_next; + while (__next) { + if (__next == __p) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + --_M_num_elements; break; } else { - cur = next; - next = cur->next; + __cur = __next; + __next = __cur->_M_next; } } } } } -template -void hashtable::erase(iterator first, iterator last) +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::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(); + size_type __f_bucket = __first._M_cur ? + _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size(); + size_type __l_bucket = __last._M_cur ? + _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size(); - if (first.cur == last.cur) + if (__first._M_cur == __last._M_cur) return; - else if (f_bucket == l_bucket) - erase_bucket(f_bucket, first.cur, last.cur); + else if (__f_bucket == __l_bucket) + _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_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); + _M_erase_bucket(__f_bucket, __first._M_cur, 0); + for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) + _M_erase_bucket(__n, 0); + if (__l_bucket != _M_buckets.size()) + _M_erase_bucket(__l_bucket, __last._M_cur); } } -template +template inline void -hashtable::erase(const_iterator first, - const_iterator last) +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const_iterator __first, + const_iterator __last) { - erase(iterator(const_cast(first.cur), - const_cast(first.ht)), - iterator(const_cast(last.cur), - const_cast(last.ht))); + erase(iterator(const_cast<_Node*>(__first._M_cur), + const_cast(__first._M_ht)), + iterator(const_cast<_Node*>(__last._M_cur), + const_cast(__last._M_ht))); } -template +template inline void -hashtable::erase(const const_iterator& it) +hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::erase(const const_iterator& __it) { - erase(iterator(const_cast(it.cur), - const_cast(it.ht))); + erase(iterator(const_cast<_Node*>(__it._M_cur), + const_cast(__it._M_ht))); } -template -void hashtable::resize(size_type num_elements_hint) +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::resize(size_type __num_elements_hint) { - const size_type old_n = buckets.size(); - if (num_elements_hint > old_n) { - const size_type n = next_size(num_elements_hint); - if (n > old_n) { - vector tmp(n, (node*) 0); + const size_type __old_n = _M_buckets.size(); + if (__num_elements_hint > __old_n) { + const size_type __n = _M_next_size(__num_elements_hint); + if (__n > __old_n) { + vector<_Node*, _All> __tmp(__n, (_Node*)(0), + _M_buckets.get_allocator()); __STL_TRY { - for (size_type bucket = 0; bucket < old_n; ++bucket) { - node* first = buckets[bucket]; - while (first) { - size_type new_bucket = bkt_num(first->val, n); - buckets[bucket] = first->next; - first->next = tmp[new_bucket]; - tmp[new_bucket] = first; - first = buckets[bucket]; + for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) { + _Node* __first = _M_buckets[__bucket]; + while (__first) { + size_type __new_bucket = _M_bkt_num(__first->_M_val, __n); + _M_buckets[__bucket] = __first->_M_next; + __first->_M_next = __tmp[__new_bucket]; + __tmp[__new_bucket] = __first; + __first = _M_buckets[__bucket]; } } - buckets.swap(tmp); + _M_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; + for (size_type __bucket = 0; __bucket < __tmp.size(); ++__bucket) { + while (__tmp[__bucket]) { + _Node* __next = __tmp[__bucket]->_M_next; + _M_delete_node(__tmp[__bucket]); + __tmp[__bucket] = __next; } } throw; @@ -866,75 +952,80 @@ void hashtable::resize(size_type num_elements_hint) } } -template -void hashtable::erase_bucket(const size_type n, - node* first, node* last) +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last) { - node* cur = buckets[n]; - if (cur == first) - erase_bucket(n, last); + _Node* __cur = _M_buckets[__n]; + if (__cur == __first) + _M_erase_bucket(__n, __last); else { - node* next; - for (next = cur->next; next != first; cur = next, next = cur->next) + _Node* __next; + for (__next = __cur->_M_next; + __next != __first; + __cur = __next, __next = __cur->_M_next) ; - while (next) { - cur->next = next->next; - delete_node(next); - next = cur->next; - --num_elements; + while (__next) { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + --_M_num_elements; } } } -template -void -hashtable::erase_bucket(const size_type n, node* last) +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_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; + _Node* __cur = _M_buckets[__n]; + while (__cur != __last) { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; + _M_buckets[__n] = __cur; + --_M_num_elements; } } -template -void hashtable::clear() +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>::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; + for (size_type __i = 0; __i < _M_buckets.size(); ++__i) { + _Node* __cur = _M_buckets[__i]; + while (__cur != 0) { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; } - buckets[i] = 0; + _M_buckets[__i] = 0; } - num_elements = 0; + _M_num_elements = 0; } -template -void hashtable::copy_from(const hashtable& ht) +template +void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> + ::_M_copy_from(const hashtable& __ht) { - buckets.clear(); - buckets.reserve(ht.buckets.size()); - buckets.insert(buckets.end(), ht.buckets.size(), (node*) 0); + _M_buckets.clear(); + _M_buckets.reserve(__ht._M_buckets.size()); + _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); __STL_TRY { - for (size_type i = 0; i < ht.buckets.size(); ++i) { - if (const node* cur = ht.buckets[i]) { - node* copy = new_node(cur->val); - buckets[i] = copy; - - for (node* next = cur->next; next; cur = next, next = cur->next) { - copy->next = new_node(next->val); - copy = copy->next; + for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { + if (const _Node* __cur = __ht._M_buckets[__i]) { + _Node* __copy = _M_new_node(__cur->_M_val); + _M_buckets[__i] = __copy; + + for (_Node* __next = __cur->_M_next; + __next; + __cur = __next, __next = __cur->_M_next) { + __copy->_M_next = _M_new_node(__next->_M_val); + __copy = __copy->_M_next; } } } - num_elements = ht.num_elements; + _M_num_elements = __ht._M_num_elements; } __STL_UNWIND(clear()); } diff --git a/libstdc++/stl/stl_heap.h b/libstdc++/stl/stl_heap.h index 3fe24f833fc..62f142ec970 100644 --- a/libstdc++/stl/stl_heap.h +++ b/libstdc++/stl/stl_heap.h @@ -36,181 +36,236 @@ __STL_BEGIN_NAMESPACE #pragma set woff 1209 #endif -template -void __push_heap(RandomAccessIterator first, Distance holeIndex, - Distance topIndex, T value) { - Distance parent = (holeIndex - 1) / 2; - while (holeIndex > topIndex && *(first + parent) < value) { - *(first + holeIndex) = *(first + parent); - holeIndex = parent; - parent = (holeIndex - 1) / 2; +// Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap. + +template +void +__push_heap(_RandomAccessIterator __first, + _Distance __holeIndex, _Distance __topIndex, _Tp __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; + *(__first + __holeIndex) = __value; } -template -inline void __push_heap_aux(RandomAccessIterator first, - RandomAccessIterator last, Distance*, T*) { - __push_heap(first, Distance((last - first) - 1), Distance(0), - T(*(last - 1))); +template +inline void +__push_heap_aux(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Distance*, _Tp*) +{ + __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), + _Tp(*(__last - 1))); } -template -inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) { - __push_heap_aux(first, last, distance_type(first), value_type(first)); +template +inline void +push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + __push_heap_aux(__first, __last, + __DISTANCE_TYPE(__first), __VALUE_TYPE(__first)); } -template -void __push_heap(RandomAccessIterator first, Distance holeIndex, - Distance topIndex, T value, Compare comp) { - Distance parent = (holeIndex - 1) / 2; - while (holeIndex > topIndex && comp(*(first + parent), value)) { - *(first + holeIndex) = *(first + parent); - holeIndex = parent; - parent = (holeIndex - 1) / 2; +template +void +__push_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __topIndex, _Tp __value, _Compare __comp) +{ + _Distance __parent = (__holeIndex - 1) / 2; + while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value)) { + *(__first + __holeIndex) = *(__first + __parent); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; } - *(first + holeIndex) = value; -} - -template -inline void __push_heap_aux(RandomAccessIterator first, - RandomAccessIterator last, Compare comp, - Distance*, T*) { - __push_heap(first, Distance((last - first) - 1), Distance(0), - T(*(last - 1)), comp); -} - -template -inline void push_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp) { - __push_heap_aux(first, last, comp, distance_type(first), value_type(first)); -} - -template -void __adjust_heap(RandomAccessIterator first, Distance holeIndex, - Distance len, T value) { - Distance topIndex = holeIndex; - Distance secondChild = 2 * holeIndex + 2; - while (secondChild < len) { - if (*(first + secondChild) < *(first + (secondChild - 1))) - secondChild--; - *(first + holeIndex) = *(first + secondChild); - holeIndex = secondChild; - secondChild = 2 * (secondChild + 1); + *(__first + __holeIndex) = __value; +} + +template +inline void +__push_heap_aux(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp, + _Distance*, _Tp*) +{ + __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), + _Tp(*(__last - 1)), __comp); +} + +template +inline void +push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) +{ + __push_heap_aux(__first, __last, __comp, + __DISTANCE_TYPE(__first), __VALUE_TYPE(__first)); +} + +template +void +__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __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; + if (__secondChild == __len) { + *(__first + __holeIndex) = *(__first + (__secondChild - 1)); + __holeIndex = __secondChild - 1; } - __push_heap(first, holeIndex, topIndex, value); + __push_heap(__first, __holeIndex, __topIndex, __value); } -template -inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last, - RandomAccessIterator result, T value, Distance*) { - *result = *first; - __adjust_heap(first, Distance(0), Distance(last - first), value); +template +inline void +__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result, _Tp __value, _Distance*) +{ + *__result = *__first; + __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value); } -template -inline void __pop_heap_aux(RandomAccessIterator first, - RandomAccessIterator last, T*) { - __pop_heap(first, last - 1, last - 1, T(*(last - 1)), distance_type(first)); +template +inline void +__pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Tp*) +{ + __pop_heap(__first, __last - 1, __last - 1, + _Tp(*(__last - 1)), __DISTANCE_TYPE(__first)); } -template -inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last) { - __pop_heap_aux(first, last, value_type(first)); +template +inline void pop_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last) +{ + __pop_heap_aux(__first, __last, __VALUE_TYPE(__first)); } -template -void __adjust_heap(RandomAccessIterator first, Distance holeIndex, - Distance len, T value, Compare comp) { - Distance topIndex = holeIndex; - Distance secondChild = 2 * holeIndex + 2; - while (secondChild < len) { - if (comp(*(first + secondChild), *(first + (secondChild - 1)))) - secondChild--; - *(first + holeIndex) = *(first + secondChild); - holeIndex = secondChild; - secondChild = 2 * (secondChild + 1); +template +void +__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, + _Distance __len, _Tp __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; + if (__secondChild == __len) { + *(__first + __holeIndex) = *(__first + (__secondChild - 1)); + __holeIndex = __secondChild - 1; } - __push_heap(first, holeIndex, topIndex, value, comp); + __push_heap(__first, __holeIndex, __topIndex, __value, __comp); } -template -inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last, - RandomAccessIterator result, T value, Compare comp, - Distance*) { - *result = *first; - __adjust_heap(first, Distance(0), Distance(last - first), value, comp); +template +inline void +__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _RandomAccessIterator __result, _Tp __value, _Compare __comp, + _Distance*) +{ + *__result = *__first; + __adjust_heap(__first, _Distance(0), _Distance(__last - __first), + __value, __comp); } -template -inline void __pop_heap_aux(RandomAccessIterator first, - RandomAccessIterator last, T*, Compare comp) { - __pop_heap(first, last - 1, last - 1, T(*(last - 1)), comp, - distance_type(first)); +template +inline void +__pop_heap_aux(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Tp*, _Compare __comp) +{ + __pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __comp, + __DISTANCE_TYPE(__first)); } -template -inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp) { - __pop_heap_aux(first, last, value_type(first), comp); +template +inline void +pop_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) +{ + __pop_heap_aux(__first, __last, __VALUE_TYPE(__first), __comp); } -template -void __make_heap(RandomAccessIterator first, RandomAccessIterator last, T*, - Distance*) { - if (last - first < 2) return; - Distance len = last - first; - Distance parent = (len - 2)/2; +template +void +__make_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Tp*, _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--; + __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent))); + if (__parent == 0) return; + __parent--; } } -template -inline void make_heap(RandomAccessIterator first, RandomAccessIterator last) { - __make_heap(first, last, value_type(first), distance_type(first)); +template +inline void +make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + __make_heap(__first, __last, + __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); } -template -void __make_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp, T*, Distance*) { - if (last - first < 2) return; - Distance len = last - first; - Distance parent = (len - 2)/2; +template +void +__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp, _Tp*, _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--; + __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)), + __comp); + if (__parent == 0) return; + __parent--; } } -template -inline void make_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp) { - __make_heap(first, last, comp, value_type(first), distance_type(first)); +template +inline void +make_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) +{ + __make_heap(__first, __last, __comp, + __VALUE_TYPE(__first), __DISTANCE_TYPE(__first)); } -template -void sort_heap(RandomAccessIterator first, RandomAccessIterator last) { - while (last - first > 1) pop_heap(first, last--); +template +void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) +{ + while (__last - __first > 1) + pop_heap(__first, __last--); } -template -void sort_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare comp) { - while (last - first > 1) pop_heap(first, last--, comp); +template +void +sort_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) +{ + while (__last - __first > 1) + pop_heap(__first, __last--, __comp); } #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) diff --git a/libstdc++/stl/stl_iterator.h b/libstdc++/stl/stl_iterator.h index 892db3e3dbb..e2bd7149692 100644 --- a/libstdc++/stl/stl_iterator.h +++ b/libstdc++/stl/stl_iterator.h @@ -12,7 +12,7 @@ * purpose. It is provided "as is" without express or implied warranty. * * - * Copyright (c) 1996,1997 + * Copyright (c) 1996-1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software @@ -39,12 +39,17 @@ struct forward_iterator_tag : public input_iterator_tag {}; struct bidirectional_iterator_tag : public forward_iterator_tag {}; struct random_access_iterator_tag : public bidirectional_iterator_tag {}; -template struct input_iterator { +// The base classes input_iterator, output_iterator, forward_iterator, +// bidirectional_iterator, and random_access_iterator are not part of +// the C++ standard. (they have been replaced by struct iterator.) +// They are included for backward compatibility with the HP STL. + +template struct input_iterator { typedef input_iterator_tag iterator_category; - typedef T value_type; - typedef Distance difference_type; - typedef T* pointer; - typedef T& reference; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; }; struct output_iterator { @@ -55,459 +60,502 @@ struct output_iterator { typedef void reference; }; -template struct forward_iterator { +template struct forward_iterator { typedef forward_iterator_tag iterator_category; - typedef T value_type; - typedef Distance difference_type; - typedef T* pointer; - typedef T& reference; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; }; -template struct bidirectional_iterator { +template struct bidirectional_iterator { typedef bidirectional_iterator_tag iterator_category; - typedef T value_type; - typedef Distance difference_type; - typedef T* pointer; - typedef T& reference; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; }; -template struct random_access_iterator { +template struct random_access_iterator { typedef random_access_iterator_tag iterator_category; - typedef T value_type; - typedef Distance difference_type; - typedef T* pointer; - typedef T& reference; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; }; #ifdef __STL_USE_NAMESPACES -template +template struct iterator { - typedef Category iterator_category; - typedef T value_type; - typedef Distance difference_type; - typedef Pointer pointer; - typedef Reference reference; + typedef _Category iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Pointer pointer; + typedef _Reference reference; }; #endif /* __STL_USE_NAMESPACES */ #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION -template +template struct iterator_traits { - typedef typename Iterator::iterator_category iterator_category; - typedef typename Iterator::value_type value_type; - typedef typename Iterator::difference_type difference_type; - typedef typename Iterator::pointer pointer; - typedef typename Iterator::reference reference; + typedef typename _Iterator::iterator_category iterator_category; + typedef typename _Iterator::value_type value_type; + typedef typename _Iterator::difference_type difference_type; + typedef typename _Iterator::pointer pointer; + typedef typename _Iterator::reference reference; }; -template -struct iterator_traits { +template +struct iterator_traits<_Tp*> { typedef random_access_iterator_tag iterator_category; - typedef T value_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef T& reference; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + typedef _Tp& reference; }; -template -struct iterator_traits { +template +struct iterator_traits { typedef random_access_iterator_tag iterator_category; - typedef T value_type; - typedef ptrdiff_t difference_type; - typedef const T* pointer; - typedef const T& reference; + typedef _Tp value_type; + typedef ptrdiff_t difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; }; -template -inline typename iterator_traits::iterator_category -iterator_category(const Iterator&) { - typedef typename iterator_traits::iterator_category category; - return category(); +// The overloaded functions iterator_category, distance_type, and +// value_type are not part of the C++ standard. (They have been +// replaced by struct iterator_traits.) They are included for +// backward compatibility with the HP STL. + +// We introduce internal names for these functions. + +template +inline typename iterator_traits<_Iter>::iterator_category +__iterator_category(const _Iter&) +{ + typedef typename iterator_traits<_Iter>::iterator_category _Category; + return _Category(); } -template -inline typename iterator_traits::difference_type* -distance_type(const Iterator&) { - return static_cast::difference_type*>(0); +template +inline typename iterator_traits<_Iter>::difference_type* +__distance_type(const _Iter&) +{ + return static_cast::difference_type*>(0); } -template -inline typename iterator_traits::value_type* -value_type(const Iterator&) { - return static_cast::value_type*>(0); +template +inline typename iterator_traits<_Iter>::value_type* +__value_type(const _Iter&) +{ + return static_cast::value_type*>(0); } +template +inline typename iterator_traits<_Iter>::iterator_category +iterator_category(const _Iter& __i) { return __iterator_category(__i); } + + +template +inline typename iterator_traits<_Iter>::difference_type* +distance_type(const _Iter& __i) { return __distance_type(__i); } + +template +inline typename iterator_traits<_Iter>::value_type* +value_type(const _Iter& __i) { return __value_type(__i); } + +#define __ITERATOR_CATEGORY(__i) __iterator_category(__i) +#define __DISTANCE_TYPE(__i) __distance_type(__i) +#define __VALUE_TYPE(__i) __value_type(__i) + #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template +template inline input_iterator_tag -iterator_category(const input_iterator&) { - return input_iterator_tag(); -} +iterator_category(const input_iterator<_Tp, _Distance>&) + { return input_iterator_tag(); } -inline output_iterator_tag iterator_category(const output_iterator&) { - return output_iterator_tag(); -} +inline output_iterator_tag iterator_category(const output_iterator&) + { return output_iterator_tag(); } -template +template inline forward_iterator_tag -iterator_category(const forward_iterator&) { - return forward_iterator_tag(); -} +iterator_category(const forward_iterator<_Tp, _Distance>&) + { return forward_iterator_tag(); } -template +template inline bidirectional_iterator_tag -iterator_category(const bidirectional_iterator&) { - return bidirectional_iterator_tag(); -} +iterator_category(const bidirectional_iterator<_Tp, _Distance>&) + { return bidirectional_iterator_tag(); } -template +template inline random_access_iterator_tag -iterator_category(const random_access_iterator&) { - return random_access_iterator_tag(); -} +iterator_category(const random_access_iterator<_Tp, _Distance>&) + { return random_access_iterator_tag(); } -template -inline random_access_iterator_tag iterator_category(const T*) { - return random_access_iterator_tag(); -} +template +inline random_access_iterator_tag iterator_category(const _Tp*) + { return random_access_iterator_tag(); } -template -inline T* value_type(const input_iterator&) { - return (T*)(0); -} +template +inline _Tp* value_type(const input_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } -template -inline T* value_type(const forward_iterator&) { - return (T*)(0); -} +template +inline _Tp* value_type(const forward_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } -template -inline T* value_type(const bidirectional_iterator&) { - return (T*)(0); -} +template +inline _Tp* value_type(const bidirectional_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } -template -inline T* value_type(const random_access_iterator&) { - return (T*)(0); -} +template +inline _Tp* value_type(const random_access_iterator<_Tp, _Distance>&) + { return (_Tp*)(0); } -template -inline T* value_type(const T*) { return (T*)(0); } +template +inline _Tp* value_type(const _Tp*) { return (_Tp*)(0); } -template -inline Distance* distance_type(const input_iterator&) { - return (Distance*)(0); +template +inline _Distance* distance_type(const input_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); } -template -inline Distance* distance_type(const forward_iterator&) { - return (Distance*)(0); +template +inline _Distance* distance_type(const forward_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); } -template -inline Distance* -distance_type(const bidirectional_iterator&) { - return (Distance*)(0); +template +inline _Distance* +distance_type(const bidirectional_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); } -template -inline Distance* -distance_type(const random_access_iterator&) { - return (Distance*)(0); +template +inline _Distance* +distance_type(const random_access_iterator<_Tp, _Distance>&) +{ + return (_Distance*)(0); } -template -inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); } +template +inline ptrdiff_t* distance_type(const _Tp*) { return (ptrdiff_t*)(0); } + +// Without partial specialization we can't use iterator_traits, so +// we must keep the old iterator query functions around. + +#define __ITERATOR_CATEGORY(__i) iterator_category(__i) +#define __DISTANCE_TYPE(__i) distance_type(__i) +#define __VALUE_TYPE(__i) value_type(__i) #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template -inline void __distance(InputIterator first, InputIterator last, Distance& n, - input_iterator_tag) { - while (first != last) { ++first; ++n; } +template +inline void __distance(_InputIterator __first, _InputIterator __last, + _Distance& __n, input_iterator_tag) +{ + while (__first != __last) { ++__first; ++__n; } } -template -inline void __distance(RandomAccessIterator first, RandomAccessIterator last, - Distance& n, random_access_iterator_tag) { - n += last - first; +template +inline void __distance(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Distance& __n, random_access_iterator_tag) +{ + __n += __last - __first; } -template -inline void distance(InputIterator first, InputIterator last, Distance& n) { - __distance(first, last, n, iterator_category(first)); +template +inline void distance(_InputIterator __first, + _InputIterator __last, _Distance& __n) +{ + __distance(__first, __last, __n, iterator_category(__first)); } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION -template -inline iterator_traits::difference_type -__distance(InputIterator first, InputIterator last, input_iterator_tag) { - iterator_traits::difference_type n = 0; - while (first != last) { - ++first; ++n; +template +inline typename iterator_traits<_InputIterator>::difference_type +__distance(_InputIterator __first, _InputIterator __last, input_iterator_tag) +{ + typename iterator_traits<_InputIterator>::difference_type __n = 0; + while (__first != __last) { + ++__first; ++__n; } - return n; + return __n; } -template -inline iterator_traits::difference_type -__distance(RandomAccessIterator first, RandomAccessIterator last, +template +inline typename iterator_traits<_RandomAccessIterator>::difference_type +__distance(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) { - return last - first; + return __last - __first; } -template -inline iterator_traits::difference_type -distance(InputIterator first, InputIterator last) { - typedef typename iterator_traits::iterator_category category; - return __distance(first, last, category()); +template +inline typename iterator_traits<_InputIterator>::difference_type +distance(_InputIterator __first, _InputIterator __last) { + typedef typename iterator_traits<_InputIterator>::iterator_category + _Category; + return __distance(__first, __last, _Category()); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template -inline void __advance(InputIterator& i, Distance n, input_iterator_tag) { - while (n--) ++i; +template +inline void __advance(_InputIter& __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 -inline void __advance(BidirectionalIterator& i, Distance n, +template +inline void __advance(_BidirectionalIterator& __i, _Distance __n, bidirectional_iterator_tag) { - if (n >= 0) - while (n--) ++i; + if (__n >= 0) + while (__n--) ++__i; else - while (n++) --i; + while (__n++) --__i; } #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1183 #endif -template -inline void __advance(RandomAccessIterator& i, Distance n, +template +inline void __advance(_RandomAccessIterator& __i, _Distance __n, random_access_iterator_tag) { - i += n; + __i += __n; } -template -inline void advance(InputIterator& i, Distance n) { - __advance(i, n, iterator_category(i)); +template +inline void advance(_InputIterator& __i, _Distance __n) { + __advance(__i, __n, iterator_category(__i)); } -template +template class back_insert_iterator { protected: - Container* container; + _Container* container; public: + typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; - explicit back_insert_iterator(Container& x) : container(&x) {} - back_insert_iterator& - operator=(const typename Container::value_type& value) { - container->push_back(value); + 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& operator*() { return *this; } - back_insert_iterator& operator++() { return *this; } - back_insert_iterator& operator++(int) { 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 +template inline output_iterator_tag -iterator_category(const back_insert_iterator&) +iterator_category(const back_insert_iterator<_Container>&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template -inline back_insert_iterator back_inserter(Container& x) { - return back_insert_iterator(x); +template +inline back_insert_iterator<_Container> back_inserter(_Container& __x) { + return back_insert_iterator<_Container>(__x); } -template +template class front_insert_iterator { protected: - Container* container; + _Container* container; public: + typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; - explicit front_insert_iterator(Container& x) : container(&x) {} - front_insert_iterator& - operator=(const typename Container::value_type& value) { - container->push_front(value); + 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& operator*() { return *this; } - front_insert_iterator& operator++() { return *this; } - front_insert_iterator& operator++(int) { 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 +template inline output_iterator_tag -iterator_category(const front_insert_iterator&) +iterator_category(const front_insert_iterator<_Container>&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template -inline front_insert_iterator front_inserter(Container& x) { - return front_insert_iterator(x); +template +inline front_insert_iterator<_Container> front_inserter(_Container& __x) { + return front_insert_iterator<_Container>(__x); } -template +template class insert_iterator { protected: - Container* container; - typename Container::iterator iter; + _Container* container; + typename _Container::iterator iter; public: + typedef _Container container_type; typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; - insert_iterator(Container& x, typename Container::iterator i) - : container(&x), iter(i) {} - insert_iterator& - operator=(const typename Container::value_type& value) { - iter = container->insert(iter, value); + 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& operator*() { return *this; } - insert_iterator& operator++() { return *this; } - insert_iterator& operator++(int) { 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 +template inline output_iterator_tag -iterator_category(const insert_iterator&) +iterator_category(const insert_iterator<_Container>&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template -inline insert_iterator inserter(Container& x, Iterator i) { - typedef typename Container::iterator iter; - return insert_iterator(x, iter(i)); +template +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 +template #else -template +template #endif class reverse_bidirectional_iterator { - typedef reverse_bidirectional_iterator self; + typedef reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, + _Reference, _Distance> _Self; protected: - BidirectionalIterator current; + _BidirectionalIterator current; public: typedef bidirectional_iterator_tag iterator_category; - typedef T value_type; - typedef Distance difference_type; - typedef T* pointer; - typedef Reference reference; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Reference reference; reverse_bidirectional_iterator() {} - explicit reverse_bidirectional_iterator(BidirectionalIterator x) - : current(x) {} - BidirectionalIterator base() const { return current; } - Reference operator*() const { - BidirectionalIterator tmp = current; - return *--tmp; + explicit reverse_bidirectional_iterator(_BidirectionalIterator __x) + : current(__x) {} + _BidirectionalIterator base() const { return current; } + _Reference operator*() const { + _BidirectionalIterator __tmp = current; + return *--__tmp; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ - self& operator++() { + _Self& operator++() { --current; return *this; } - self operator++(int) { - self tmp = *this; + _Self operator++(int) { + _Self __tmp = *this; --current; - return tmp; + return __tmp; } - self& operator--() { + _Self& operator--() { ++current; return *this; } - self operator--(int) { - self tmp = *this; + _Self operator--(int) { + _Self __tmp = *this; ++current; - return tmp; + return __tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -template +template inline bidirectional_iterator_tag -iterator_category(const reverse_bidirectional_iterator&) { +iterator_category(const reverse_bidirectional_iterator<_BidirectionalIterator, + _Tp, _Reference, + _Distance>&) +{ return bidirectional_iterator_tag(); } -template -inline T* -value_type(const reverse_bidirectional_iterator&) { - return (T*) 0; +template +inline _Tp* +value_type(const reverse_bidirectional_iterator<_BidirectionalIterator, _Tp, + _Reference, _Distance>&) +{ + return (_Tp*) 0; } -template -inline Distance* -distance_type(const reverse_bidirectional_iterator&) { - return (Distance*) 0; +template +inline _Distance* +distance_type(const reverse_bidirectional_iterator<_BidirectionalIterator, + _Tp, + _Reference, _Distance>&) +{ + return (_Distance*) 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template +template inline bool operator==( - const reverse_bidirectional_iterator& x, - const reverse_bidirectional_iterator& y) { - return x.base() == y.base(); + const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __x, + const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __y) +{ + return __x.base() == __y.base(); } #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION @@ -518,105 +566,106 @@ inline bool operator==( // reverse_bidirectional_iterator is no longer part of the draft // standard, but it is retained for backward compatibility. -template +template class reverse_iterator { protected: - Iterator current; + _Iterator current; public: - typedef typename iterator_traits::iterator_category + typedef typename iterator_traits<_Iterator>::iterator_category iterator_category; - typedef typename iterator_traits::value_type + typedef typename iterator_traits<_Iterator>::value_type value_type; - typedef typename iterator_traits::difference_type + typedef typename iterator_traits<_Iterator>::difference_type difference_type; - typedef typename iterator_traits::pointer + typedef typename iterator_traits<_Iterator>::pointer pointer; - typedef typename iterator_traits::reference + typedef typename iterator_traits<_Iterator>::reference reference; - typedef Iterator iterator_type; - typedef reverse_iterator self; + typedef _Iterator iterator_type; + typedef reverse_iterator<_Iterator> _Self; public: reverse_iterator() {} - explicit reverse_iterator(iterator_type x) : current(x) {} + explicit reverse_iterator(iterator_type __x) : current(__x) {} - reverse_iterator(const self& x) : current(x.current) {} + reverse_iterator(const _Self& __x) : current(__x.current) {} #ifdef __STL_MEMBER_TEMPLATES - template - reverse_iterator(const reverse_iterator& x) : current(x.current) {} + template + reverse_iterator(const reverse_iterator<_Iter>& __x) + : current(__x.base()) {} #endif /* __STL_MEMBER_TEMPLATES */ iterator_type base() const { return current; } reference operator*() const { - Iterator tmp = current; - return *--tmp; + _Iterator __tmp = current; + return *--__tmp; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ - self& operator++() { + _Self& operator++() { --current; return *this; } - self operator++(int) { - self tmp = *this; + _Self operator++(int) { + _Self __tmp = *this; --current; - return tmp; + return __tmp; } - self& operator--() { + _Self& operator--() { ++current; return *this; } - self operator--(int) { - self tmp = *this; + _Self operator--(int) { + _Self __tmp = *this; ++current; - return tmp; + return __tmp; } - self operator+(difference_type n) const { - return self(current - n); + _Self operator+(difference_type __n) const { + return _Self(current - __n); } - self& operator+=(difference_type n) { - 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) const { + return _Self(current + __n); } - self& operator-=(difference_type n) { - current += n; + _Self& operator-=(difference_type __n) { + current += __n; return *this; } - reference operator[](difference_type n) const { return *(*this + n); } + reference operator[](difference_type __n) const { return *(*this + __n); } }; -template -inline bool operator==(const reverse_iterator& x, - const reverse_iterator& y) { - return x.base() == y.base(); +template +inline bool operator==(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return __x.base() == __y.base(); } -template -inline bool operator<(const reverse_iterator& x, - const reverse_iterator& y) { - return y.base() < x.base(); +template +inline bool operator<(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return __y.base() < __x.base(); } -template -inline typename reverse_iterator::difference_type -operator-(const reverse_iterator& x, - const reverse_iterator& y) { - return y.base() - x.base(); +template +inline typename reverse_iterator<_Iterator>::difference_type +operator-(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) { + return __y.base() - __x.base(); } -template -inline reverse_iterator -operator+(reverse_iterator::difference_type n, - const reverse_iterator& x) { - return reverse_iterator(x.base() - n); +template +inline reverse_iterator<_Iterator> +operator+(typename reverse_iterator<_Iterator>::difference_type __n, + const reverse_iterator<_Iterator>& __x) { + return reverse_iterator<_Iterator>(__x.base() - __n); } #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ @@ -625,186 +674,208 @@ operator+(reverse_iterator::difference_type n, // HP STL. It does not use partial specialization. #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template +template #else -template +template #endif class reverse_iterator { - typedef reverse_iterator - self; + typedef reverse_iterator<_RandomAccessIterator, _Tp, _Reference, _Distance> + _Self; protected: - RandomAccessIterator current; + _RandomAccessIterator current; public: typedef random_access_iterator_tag iterator_category; - typedef T value_type; - typedef Distance difference_type; - typedef T* pointer; - typedef Reference reference; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Tp* pointer; + typedef _Reference reference; reverse_iterator() {} - explicit reverse_iterator(RandomAccessIterator x) : current(x) {} - RandomAccessIterator base() const { return current; } - Reference operator*() const { return *(current - 1); } + explicit reverse_iterator(_RandomAccessIterator __x) : current(__x) {} + _RandomAccessIterator base() const { return current; } + _Reference operator*() const { return *(current - 1); } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ - self& operator++() { + _Self& operator++() { --current; return *this; } - self operator++(int) { - self tmp = *this; + _Self operator++(int) { + _Self __tmp = *this; --current; - return tmp; + return __tmp; } - self& operator--() { + _Self& operator--() { ++current; return *this; } - self operator--(int) { - self tmp = *this; + _Self operator--(int) { + _Self __tmp = *this; ++current; - return tmp; + return __tmp; } - self operator+(Distance n) const { - return self(current - n); + _Self operator+(_Distance __n) const { + return _Self(current - __n); } - self& operator+=(Distance n) { - current -= n; + _Self& operator+=(_Distance __n) { + current -= __n; return *this; } - self operator-(Distance n) const { - return self(current + n); + _Self operator-(_Distance __n) const { + return _Self(current + __n); } - self& operator-=(Distance n) { - current += n; + _Self& operator-=(_Distance __n) { + current += __n; return *this; } - Reference operator[](Distance n) const { return *(*this + n); } + _Reference operator[](_Distance __n) const { return *(*this + __n); } }; -template +template inline random_access_iterator_tag -iterator_category(const reverse_iterator&) { +iterator_category(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>&) +{ return random_access_iterator_tag(); } -template -inline T* value_type(const reverse_iterator&) { - return (T*) 0; +template +inline _Tp* value_type(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>&) +{ + return (_Tp*) 0; } -template -inline Distance* distance_type(const reverse_iterator&) { - return (Distance*) 0; +template +inline _Distance* +distance_type(const reverse_iterator<_RandomAccessIterator, + _Tp, _Reference, _Distance>&) +{ + return (_Distance*) 0; } -template -inline bool operator==(const reverse_iterator& x, - const reverse_iterator& y) { - return x.base() == y.base(); +template +inline bool +operator==(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) +{ + return __x.base() == __y.base(); } -template -inline bool operator<(const reverse_iterator& x, - const reverse_iterator& y) { - return y.base() < x.base(); +template +inline bool +operator<(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) +{ + return __y.base() < __x.base(); } -template -inline Distance operator-(const reverse_iterator& x, - const reverse_iterator& y) { - return y.base() - x.base(); +template +inline _Distance +operator-(const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __x, + const reverse_iterator<_RandomAccessIterator, _Tp, + _Reference, _Distance>& __y) +{ + return __y.base() - __x.base(); } -template -inline reverse_iterator -operator+(Dist n, const reverse_iterator& x) { - return reverse_iterator(x.base() - n); +template +inline reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist> +operator+(_Dist __n, + const reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist>& __x) +{ + return reverse_iterator<_RandAccIter, _Tp, _Ref, _Dist>(__x.base() - __n); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template +// When we have templatized iostreams, istream_iterator and ostream_iterator +// must be rewritten. + +template class istream_iterator { - friend bool - operator== __STL_NULL_TMPL_ARGS (const istream_iterator& x, - const istream_iterator& y); + friend bool operator== __STL_NULL_TMPL_ARGS (const istream_iterator&, + const istream_iterator&); 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; + istream* _M_stream; + _Tp _M_value; + bool _M_end_marker; + void _M_read() { + _M_end_marker = (*_M_stream) ? true : false; + if (_M_end_marker) *_M_stream >> _M_value; + _M_end_marker = (*_M_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; } + typedef input_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Dist difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + + istream_iterator() : _M_stream(&cin), _M_end_marker(false) {} + istream_iterator(istream& __s) : _M_stream(&__s) { _M_read(); } + reference operator*() const { return _M_value; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ - istream_iterator& operator++() { - read(); + istream_iterator<_Tp, _Dist>& operator++() { + _M_read(); return *this; } - istream_iterator operator++(int) { - istream_iterator tmp = *this; - read(); - return tmp; + istream_iterator<_Tp, _Dist> operator++(int) { + istream_iterator<_Tp, _Dist> __tmp = *this; + _M_read(); + return __tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -template +template inline input_iterator_tag -iterator_category(const istream_iterator&) { +iterator_category(const istream_iterator<_Tp, _Dist>&) +{ return input_iterator_tag(); } -template -inline T* value_type(const istream_iterator&) { return (T*) 0; } +template +inline _Tp* +value_type(const istream_iterator<_Tp, _Dist>&) { return (_Tp*) 0; } -template -inline Distance* distance_type(const istream_iterator&) { - return (Distance*) 0; -} +template +inline _Dist* +distance_type(const istream_iterator<_Tp, _Dist>&) { return (_Dist*)0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template -inline bool operator==(const istream_iterator& x, - const istream_iterator& y) { - return x.stream == y.stream && x.end_marker == y.end_marker || - x.end_marker == false && y.end_marker == false; +template +inline bool operator==(const istream_iterator<_Tp, _Distance>& __x, + const istream_iterator<_Tp, _Distance>& __y) { + return (__x._M_stream == __y._M_stream && + __x._M_end_marker == __y._M_end_marker) || + __x._M_end_marker == false && __y._M_end_marker == false; } -template +template class ostream_iterator { protected: - ostream* stream; - const char* string; + ostream* _M_stream; + const char* _M_string; public: typedef output_iterator_tag iterator_category; typedef void value_type; @@ -812,23 +883,24 @@ public: typedef void pointer; typedef void reference; - ostream_iterator(ostream& s) : stream(&s), string(0) {} - ostream_iterator(ostream& s, const char* c) : stream(&s), string(c) {} - ostream_iterator& operator=(const T& value) { - *stream << value; - if (string) *stream << string; + ostream_iterator(ostream& __s) : _M_stream(&__s), _M_string(0) {} + ostream_iterator(ostream& __s, const char* __c) + : _M_stream(&__s), _M_string(__c) {} + ostream_iterator<_Tp>& operator=(const _Tp& __value) { + *_M_stream << __value; + if (_M_string) *_M_stream << _M_string; return *this; } - ostream_iterator& operator*() { return *this; } - ostream_iterator& operator++() { return *this; } - ostream_iterator& operator++(int) { return *this; } + ostream_iterator<_Tp>& operator*() { return *this; } + ostream_iterator<_Tp>& operator++() { return *this; } + ostream_iterator<_Tp>& operator++(int) { return *this; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -template +template inline output_iterator_tag -iterator_category(const ostream_iterator&) { +iterator_category(const ostream_iterator<_Tp>&) { return output_iterator_tag(); } diff --git a/libstdc++/stl/stl_list.h b/libstdc++/stl/stl_list.h index ac836b6fcf9..5d95d641e52 100644 --- a/libstdc++/stl/stl_list.h +++ b/libstdc++/stl/stl_list.h @@ -35,577 +35,800 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif -template -struct __list_node { - typedef void* void_pointer; - void_pointer next; - void_pointer prev; - T data; +template +struct _List_node { + typedef void* _Void_pointer; + _Void_pointer _M_next; + _Void_pointer _M_prev; + _Tp _M_data; }; -template -struct __list_iterator { - typedef __list_iterator iterator; - typedef __list_iterator const_iterator; - typedef __list_iterator self; +template +struct _List_iterator { + typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; + typedef _List_iterator<_Tp,_Ref,_Ptr> _Self; typedef bidirectional_iterator_tag iterator_category; - typedef T value_type; - typedef Ptr pointer; - typedef Ref reference; - typedef __list_node* link_type; + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef _List_node<_Tp> _Node; typedef size_t size_type; typedef ptrdiff_t difference_type; - link_type node; + _Node* _M_node; - __list_iterator(link_type x) : node(x) {} - __list_iterator() {} - __list_iterator(const iterator& x) : node(x.node) {} + _List_iterator(_Node* __x) : _M_node(__x) {} + _List_iterator() {} + _List_iterator(const iterator& __x) : _M_node(__x._M_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; } + bool operator==(const _Self& __x) const { return _M_node == __x._M_node; } + bool operator!=(const _Self& __x) const { return _M_node != __x._M_node; } + reference operator*() const { return (*_M_node)._M_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); + _Self& operator++() { + _M_node = (_Node*)(_M_node->_M_next); return *this; } - self operator++(int) { - self tmp = *this; + _Self operator++(int) { + _Self __tmp = *this; ++*this; - return tmp; + return __tmp; } - self& operator--() { - node = (link_type)((*node).prev); + _Self& operator--() { + _M_node = (_Node*)(_M_node->_M_prev); return *this; } - self operator--(int) { - self tmp = *this; + _Self operator--(int) { + _Self __tmp = *this; --*this; - return tmp; + return __tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -template +template inline bidirectional_iterator_tag -iterator_category(const __list_iterator&) { +iterator_category(const _List_iterator<_Tp, _Ref, _Ptr>&) +{ return bidirectional_iterator_tag(); } -template -inline T* -value_type(const __list_iterator&) { +template +inline _Tp* +value_type(const _List_iterator<_Tp, _Ref, _Ptr>&) +{ return 0; } -template +template inline ptrdiff_t* -distance_type(const __list_iterator&) { +distance_type(const _List_iterator<_Tp, _Ref, _Ptr>&) +{ return 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -template -class list { + +// Base class that encapsulates details of allocators. Three cases: +// an ordinary standard-conforming allocator, a standard-conforming +// allocator with no non-static data, and an SGI-style allocator. +// This complexity is necessary only because we're worrying about backward +// compatibility and because we want to avoid wasting storage on an +// allocator instance if it isn't necessary. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base for general standard-conforming allocators. +template +class _List_alloc_base { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _Node_allocator; } + + _List_alloc_base(const allocator_type& __a) : _Node_allocator(__a) {} + +protected: + _List_node<_Tp>* _M_get_node() + { return _Node_allocator.allocate(1); } + void _M_put_node(_List_node<_Tp>* __p) + { _Node_allocator.deallocate(__p, 1); } + +protected: + typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type + _Node_allocator; + _List_node<_Tp>* _M_node; +}; + +// Specialization for instanceless allocators. + +template +class _List_alloc_base<_Tp, _Allocator, true> { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _List_alloc_base(const allocator_type&) {} + +protected: + typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type + _Alloc_type; + _List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + +protected: + _List_node<_Tp>* _M_node; +}; + +template +class _List_base + : public _List_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ +public: + typedef _List_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _List_base(const allocator_type& __a) : _Base(__a) { + _M_node = _M_get_node(); + _M_node->_M_next = _M_node; + _M_node->_M_prev = _M_node; + } + ~_List_base() { + clear(); + _M_put_node(_M_node); + } + + void clear(); +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +class _List_base +{ +public: + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _List_base(const allocator_type&) { + _M_node = _M_get_node(); + _M_node->_M_next = _M_node; + _M_node->_M_prev = _M_node; + } + ~_List_base() { + clear(); + _M_put_node(_M_node); + } + + void clear(); + +protected: + typedef simple_alloc<_List_node<_Tp>, _Alloc> _Alloc_type; + _List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + protected: - typedef void* void_pointer; - typedef __list_node list_node; - typedef simple_alloc list_node_allocator; + _List_node<_Tp>* _M_node; +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template +void +_List_base<_Tp,_Alloc>::clear() +{ + _List_node<_Tp>* __cur = (_List_node<_Tp>*) _M_node->_M_next; + while (__cur != _M_node) { + _List_node<_Tp>* __tmp = __cur; + __cur = (_List_node<_Tp>*) __cur->_M_next; + destroy(&__tmp->_M_data); + _M_put_node(__tmp); + } + _M_node->_M_next = _M_node; + _M_node->_M_prev = _M_node; +} + +template +class list : protected _List_base<_Tp, _Alloc> { + typedef _List_base<_Tp, _Alloc> _Base; +protected: + typedef void* _Void_pointer; + public: - typedef T value_type; + typedef _Tp value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; - typedef list_node* link_type; + typedef _List_node<_Tp> _Node; typedef size_t size_type; typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + public: - typedef __list_iterator iterator; - typedef __list_iterator const_iterator; + typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; - typedef reverse_iterator reverse_iterator; + typedef reverse_iterator reverse_iterator; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - typedef reverse_bidirectional_iterator - const_reverse_iterator; - typedef reverse_bidirectional_iterator - reverse_iterator; + typedef reverse_bidirectional_iterator + const_reverse_iterator; + typedef reverse_bidirectional_iterator + reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ protected: - link_type get_node() { return list_node_allocator::allocate(); } - void put_node(link_type p) { list_node_allocator::deallocate(p); } - - link_type create_node(const T& x) { - link_type p = get_node(); - __STL_TRY { - construct(&p->data, x); - } - __STL_UNWIND(put_node(p)); - return p; - } - void destroy_node(link_type p) { - destroy(&p->data); - put_node(p); - } +#ifdef __STL_HAS_NAMESPACES + using _Base::_M_node; + using _Base::_M_put_node; + using _Base::_M_get_node; +#endif /* __STL_HAS_NAMESPACES */ protected: - void empty_initialize() { - node = get_node(); - node->next = node; - node->prev = node; - } - - void fill_initialize(size_type n, const T& value) { - empty_initialize(); + _Node* _M_create_node(const _Tp& __x) + { + _Node* __p = _M_get_node(); __STL_TRY { - insert(begin(), n, value); + construct(&__p->_M_data, __x); } - __STL_UNWIND(clear(); put_node(node)); + __STL_UNWIND(_M_put_node(__p)); + return __p; } -#ifdef __STL_MEMBER_TEMPLATES - template - void range_initialize(InputIterator first, InputIterator last) { - empty_initialize(); - __STL_TRY { - insert(begin(), first, last); - } - __STL_UNWIND(clear(); put_node(node)); - } -#else /* __STL_MEMBER_TEMPLATES */ - void range_initialize(const T* first, const T* last) { - empty_initialize(); - __STL_TRY { - insert(begin(), first, last); - } - __STL_UNWIND(clear(); put_node(node)); - } - void range_initialize(const_iterator first, const_iterator last) { - empty_initialize(); + _Node* _M_create_node() + { + _Node* __p = _M_get_node(); __STL_TRY { - insert(begin(), first, last); + construct(&__p->_M_data); } - __STL_UNWIND(clear(); put_node(node)); + __STL_UNWIND(_M_put_node(__p)); + return __p; } -#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; } + explicit list(const allocator_type& __a = allocator_type()) : _Base(__a) {} + + iterator begin() { return (_Node*)(_M_node->_M_next); } + const_iterator begin() const { return (_Node*)(_M_node->_M_next); } + + iterator end() { return _M_node; } + const_iterator end() const { return _M_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 _M_node->_M_next == _M_node; } size_type size() const { - size_type result = 0; - distance(begin(), end(), result); - return result; + size_type __result = 0; + distance(begin(), end(), __result); + return __result; } size_type max_size() const { return size_type(-1); } + reference front() { return *begin(); } const_reference front() const { return *begin(); } reference back() { return *(--end()); } const_reference back() const { return *(--end()); } - void swap(list& x) { __STD::swap(node, x.node); } - iterator insert(iterator position, const T& x) { - link_type tmp = create_node(x); - tmp->next = position.node; - tmp->prev = position.node->prev; - (link_type(position.node->prev))->next = tmp; - position.node->prev = tmp; - return tmp; + + void swap(list<_Tp, _Alloc>& __x) { __STD::swap(_M_node, __x._M_node); } + + iterator insert(iterator __position, const _Tp& __x) { + _Node* __tmp = _M_create_node(__x); + __tmp->_M_next = __position._M_node; + __tmp->_M_prev = __position._M_node->_M_prev; + ((_Node*) (__position._M_node->_M_prev))->_M_next = __tmp; + __position._M_node->_M_prev = __tmp; + return __tmp; } - iterator insert(iterator position) { return insert(position, T()); } + iterator insert(iterator __position) { return insert(__position, _Tp()); } #ifdef __STL_MEMBER_TEMPLATES - template - void insert(iterator position, InputIterator first, InputIterator last); -#else /* __STL_MEMBER_TEMPLATES */ - void insert(iterator position, const T* first, const T* last); - void insert(iterator position, - const_iterator first, const_iterator last); -#endif /* __STL_MEMBER_TEMPLATES */ - void insert(iterator pos, size_type n, const T& x); - void insert(iterator pos, int n, const T& x) { - insert(pos, (size_type)n, x); - } - void insert(iterator pos, long n, const T& x) { - insert(pos, (size_type)n, x); + // Check whether it's an integral type. If so, it's not an iterator. + + template + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) { + insert(__pos, (size_type) __n, (_Tp) __x); } - void push_front(const T& x) { insert(begin(), x); } - void push_back(const T& x) { insert(end(), x); } - iterator erase(iterator position) { - link_type next_node = link_type(position.node->next); - link_type prev_node = link_type(position.node->prev); - prev_node->next = next_node; - next_node->prev = prev_node; - destroy_node(position.node); - return iterator(next_node); + template + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type); + + template + void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__pos, __first, __last, _Integral()); } - iterator erase(iterator first, iterator last); - void resize(size_type new_size, const T& x); - void resize(size_type new_size) { resize(new_size, T()); } - void clear(); + +#else /* __STL_MEMBER_TEMPLATES */ + void insert(iterator __position, const _Tp* __first, const _Tp* __last); + void insert(iterator __position, + const_iterator __first, const_iterator __last); +#endif /* __STL_MEMBER_TEMPLATES */ + void insert(iterator __pos, size_type __n, const _Tp& __x); + + void push_front(const _Tp& __x) { insert(begin(), __x); } + void push_front() {insert(begin());} + void push_back(const _Tp& __x) { insert(end(), __x); } + void push_back() {insert(end());} + + iterator erase(iterator __position) { + _Node* __next_node = (_Node*) (__position._M_node->_M_next); + _Node* __prev_node = (_Node*) (__position._M_node->_M_prev); + __prev_node->_M_next = __next_node; + __next_node->_M_prev = __prev_node; + destroy(&__position._M_node->_M_data); + _M_put_node(__position._M_node); + return iterator(__next_node); + } + iterator erase(iterator __first, iterator __last); + void clear() { _Base::clear(); } + + void resize(size_type __new_size, const _Tp& __x); + void resize(size_type __new_size) { resize(__new_size, _Tp()); } void pop_front() { erase(begin()); } void pop_back() { - iterator tmp = end(); - erase(--tmp); + 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()); } + list(size_type __n, const _Tp& __value, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { insert(begin(), __n, __value); } + explicit list(size_type __n) + : _Base(allocator_type()) + { insert(begin(), __n, _Tp()); } #ifdef __STL_MEMBER_TEMPLATES - template - list(InputIterator first, InputIterator last) { - range_initialize(first, last); - } + + // We don't need any dispatching tricks here, because insert does all of + // that anyway. + template + list(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { insert(begin(), __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); - } + + list(const _Tp* __first, const _Tp* __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { insert(begin(), __first, __last); } + list(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { insert(begin(), __first, __last); } + #endif /* __STL_MEMBER_TEMPLATES */ - list(const list& x) { - range_initialize(x.begin(), x.end()); - } - ~list() { - clear(); - put_node(node); + list(const list<_Tp, _Alloc>& __x) : _Base(__x.get_allocator()) + { insert(begin(), __x.begin(), __x.end()); } + + ~list() { } + + list<_Tp, _Alloc>& operator=(const list<_Tp, _Alloc>& __x); + +public: + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void assign(size_type __n, const _Tp& __val); + +#ifdef __STL_MEMBER_TEMPLATES + + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); } - list& operator=(const list& x); + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { assign((size_type) __n, (_Tp) __val); } + + template + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + +#endif /* __STL_MEMBER_TEMPLATES */ 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; + void transfer(iterator __position, iterator __first, iterator __last) { + if (__position != __last) { + // Remove [first, last) from its old position. + ((_Node*) (__last._M_node->_M_prev))->_M_next = __position._M_node; + ((_Node*) (__first._M_node->_M_prev))->_M_next = __last._M_node; + ((_Node*) (__position._M_node->_M_prev))->_M_next = __first._M_node; + + // Splice [first, last) into its new position. + _Node* __tmp = (_Node*) (__position._M_node->_M_prev); + __position._M_node->_M_prev = __last._M_node->_M_prev; + __last._M_node->_M_prev = __first._M_node->_M_prev; + __first._M_node->_M_prev = __tmp; } } public: - void splice(iterator position, list& x) { - if (!x.empty()) - transfer(position, x.begin(), x.end()); + 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 __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 splice(iterator __position, list&, iterator __first, iterator __last) { + if (__first != __last) + transfer(__position, __first, __last); } - void remove(const T& value); + void remove(const _Tp& __value); void unique(); - void merge(list& x); + void merge(list& __x); void reverse(); void sort(); #ifdef __STL_MEMBER_TEMPLATES - template void remove_if(Predicate); - template void unique(BinaryPredicate); - template void merge(list&, StrictWeakOrdering); - template void sort(StrictWeakOrdering); + template void remove_if(_Predicate); + template void unique(_BinaryPredicate); + template void merge(list&, _StrictWeakOrdering); + template void sort(_StrictWeakOrdering); #endif /* __STL_MEMBER_TEMPLATES */ - friend bool operator== __STL_NULL_TMPL_ARGS (const list& x, const list& y); + friend bool operator== __STL_NULL_TMPL_ARGS ( + const list& __x, const list& __y); }; -template -inline bool operator==(const list& x, const list& y) { - typedef typename list::link_type link_type; - link_type e1 = x.node; - link_type e2 = y.node; - link_type n1 = (link_type) e1->next; - link_type n2 = (link_type) e2->next; - for ( ; n1 != e1 && n2 != e2 ; - n1 = (link_type) n1->next, n2 = (link_type) n2->next) - if (n1->data != n2->data) +template +inline bool operator==(const list<_Tp,_Alloc>& __x, + const list<_Tp,_Alloc>& __y) +{ + typedef typename list<_Tp,_Alloc>::_Node _Node; + _Node* __e1 = __x._M_node; + _Node* __e2 = __y._M_node; + _Node* __n1 = (_Node*) __e1->_M_next; + _Node* __n2 = (_Node*) __e2->_M_next; + for ( ; __n1 != __e1 && __n2 != __e2 ; + __n1 = (_Node*) __n1->_M_next, __n2 = (_Node*) __n2->_M_next) + if (__n1->_M_data != __n2->_M_data) return false; - return n1 == e1 && n2 == e2; + return __n1 == __e1 && __n2 == __e2; } -template -inline bool operator<(const list& x, const list& y) { - return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); +template +inline bool operator<(const list<_Tp,_Alloc>& __x, + const list<_Tp,_Alloc>& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template -inline void swap(list& x, list& y) { - x.swap(y); +template +inline void +swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) +{ + __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #ifdef __STL_MEMBER_TEMPLATES -template template -void list::insert(iterator position, - InputIterator first, InputIterator last) { - for ( ; first != last; ++first) - insert(position, *first); +template template +void +list<_Tp, _Alloc>::_M_insert_dispatch(iterator __position, + _InputIter __first, _InputIter __last, + __false_type) +{ + for ( ; __first != __last; ++__first) + insert(__position, *__first); } #else /* __STL_MEMBER_TEMPLATES */ -template -void list::insert(iterator position, const T* first, const T* last) { - for ( ; first != last; ++first) - insert(position, *first); +template +void +list<_Tp, _Alloc>::insert(iterator __position, + const _Tp* __first, const _Tp* __last) +{ + for ( ; __first != __last; ++__first) + insert(__position, *__first); } -template -void list::insert(iterator position, - const_iterator first, const_iterator last) { - for ( ; first != last; ++first) - insert(position, *first); +template +void +list<_Tp, _Alloc>::insert(iterator __position, + const_iterator __first, const_iterator __last) +{ + for ( ; __first != __last; ++__first) + insert(__position, *__first); } #endif /* __STL_MEMBER_TEMPLATES */ -template -void list::insert(iterator position, size_type n, const T& x) { - for ( ; n > 0; --n) - insert(position, x); +template +void +list<_Tp, _Alloc>::insert(iterator __position, size_type __n, const _Tp& __x) +{ + for ( ; __n > 0; --__n) + insert(__position, __x); } -template -list::iterator list::erase(iterator first, iterator last) { - while (first != last) erase(first++); - return last; +template +list<_Tp,_Alloc>::iterator list<_Tp, _Alloc>::erase(iterator __first, + iterator __last) +{ + while (__first != __last) + erase(__first++); + return __last; } -template -void list::resize(size_type new_size, const T& x) +template +void list<_Tp, _Alloc>::resize(size_type __new_size, const _Tp& __x) { - iterator i = begin(); - size_type len = 0; - for ( ; i != end() && len < new_size; ++i, ++len) + iterator __i = begin(); + size_type __len = 0; + for ( ; __i != end() && __len < __new_size; ++__i, ++__len) ; - if (len == new_size) - erase(i, end()); - else // i == end() - insert(end(), new_size - len, x); + if (__len == __new_size) + erase(__i, end()); + else // __i == end() + insert(end(), __new_size - __len, __x); } -template -void list::clear() +template +list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list<_Tp, _Alloc>& __x) { - link_type cur = (link_type) node->next; - while (cur != node) { - link_type tmp = cur; - cur = (link_type) cur->next; - destroy_node(tmp); - } - node->next = node; - node->prev = node; -} - -template -list& list::operator=(const list& x) { - if (this != &x) { - iterator first1 = begin(); - iterator last1 = end(); - const_iterator first2 = x.begin(); - const_iterator last2 = x.end(); - while (first1 != last1 && first2 != last2) *first1++ = *first2++; - if (first2 == last2) - erase(first1, last1); + 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); + insert(__last1, __first2, __last2); } return *this; } -template -void list::remove(const T& value) { - iterator first = begin(); - iterator last = end(); - while (first != last) { - iterator next = first; - ++next; - if (*first == value) erase(first); - first = next; +template +void list<_Tp, _Alloc>::assign(size_type __n, const _Tp& __val) { + iterator __i = begin(); + for ( ; __i != end() && __n > 0; ++__i, --__n) + *__i = __val; + if (__n > 0) + insert(end(), __n, __val); + else + erase(__i, end()); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void +list<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first2, _InputIter __last2, + __false_type) +{ + iterator __first1 = begin(); + iterator __last1 = end(); + for ( ; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) + *__first1 = *__first2; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +void list<_Tp, _Alloc>::remove(const _Tp& __value) +{ + iterator __first = begin(); + iterator __last = end(); + while (__first != __last) { + iterator __next = __first; + ++__next; + if (*__first == __value) erase(__first); + __first = __next; } } -template -void list::unique() { - iterator first = begin(); - iterator last = end(); - if (first == last) return; - iterator next = first; - while (++next != last) { - if (*first == *next) - erase(next); +template +void list<_Tp, _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; + __first = __next; + __next = __first; } } -template -void list::merge(list& x) { - iterator first1 = begin(); - iterator last1 = end(); - iterator first2 = x.begin(); - iterator last2 = x.end(); - while (first1 != last1 && first2 != last2) - if (*first2 < *first1) { - iterator next = first2; - transfer(first1, first2, ++next); - first2 = next; +template +void list<_Tp, _Alloc>::merge(list<_Tp, _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); + ++__first1; + if (__first2 != __last2) transfer(__last1, __first2, __last2); } -template -void list::reverse() { - if (node->next == node || link_type(node->next)->next == node) return; - iterator first = begin(); - ++first; - while (first != end()) { - iterator old = first; - ++first; - transfer(begin(), old, first); +template +void list<_Tp, _Alloc>::reverse() +{ + // Do nothing if the list has length 0 or 1. + if (_M_node->_M_next != _M_node && + ((_Node*) (_M_node->_M_next))->_M_next != _M_node) { + iterator __first = begin(); + ++__first; + while (__first != end()) { + iterator __old = __first; + ++__first; + transfer(begin(), __old, __first); + } } } -template -void list::sort() { - if (node->next == node || link_type(node->next)->next == node) return; - list carry; - list counter[64]; - int fill = 0; - while (!empty()) { - carry.splice(carry.begin(), *this, begin()); - int i = 0; - while(i < fill && !counter[i].empty()) { - counter[i].merge(carry); - carry.swap(counter[i++]); - } - carry.swap(counter[i]); - if (i == fill) ++fill; - } - - for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1]); - swap(counter[fill-1]); +template +void list<_Tp, _Alloc>::sort() +{ + // Do nothing if the list has length 0 or 1. + if (_M_node->_M_next != _M_node && + ((_Node*) (_M_node->_M_next))->_M_next != _M_node) { + list<_Tp, _Alloc> __carry; + list<_Tp, _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 template -void list::remove_if(Predicate pred) { - iterator first = begin(); - iterator last = end(); - while (first != last) { - iterator next = first; - ++next; - if (pred(*first)) erase(first); - first = next; +template template +void list<_Tp, _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 template -void list::unique(BinaryPredicate binary_pred) { - iterator first = begin(); - iterator last = end(); - if (first == last) return; - iterator next = first; - while (++next != last) { - if (binary_pred(*first, *next)) - erase(next); +template template +void list<_Tp, _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; + __first = __next; + __next = __first; } } -template template -void list::merge(list& x, StrictWeakOrdering comp) { - iterator first1 = begin(); - iterator last1 = end(); - iterator first2 = x.begin(); - iterator last2 = x.end(); - while (first1 != last1 && first2 != last2) - if (comp(*first2, *first1)) { - iterator next = first2; - transfer(first1, first2, ++next); - first2 = next; +template template +void list<_Tp, _Alloc>::merge(list<_Tp, _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); + ++__first1; + if (__first2 != __last2) transfer(__last1, __first2, __last2); } -template template -void list::sort(StrictWeakOrdering comp) { - if (node->next == node || link_type(node->next)->next == node) return; - list carry; - list counter[64]; - int fill = 0; - while (!empty()) { - carry.splice(carry.begin(), *this, begin()); - int i = 0; - while(i < fill && !counter[i].empty()) { - counter[i].merge(carry, comp); - carry.swap(counter[i++]); - } - carry.swap(counter[i]); - if (i == fill) ++fill; - } - - for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1], comp); - swap(counter[fill-1]); +template template +void list<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp) +{ + // Do nothing if the list has length 0 or 1. + if (_M_node->_M_next != _M_node && + ((_Node*) (_M_node->_M_next))->_M_next != _M_node) { + list<_Tp, _Alloc> __carry; + list<_Tp, _Alloc> __counter[64]; + int __fill = 0; + while (!empty()) { + __carry.splice(__carry.begin(), *this, begin()); + int __i = 0; + while(__i < __fill && !__counter[__i].empty()) { + __counter[__i].merge(__carry, __comp); + __carry.swap(__counter[__i++]); + } + __carry.swap(__counter[__i]); + if (__i == __fill) ++__fill; + } + + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1], __comp); + swap(__counter[__fill-1]); + } } #endif /* __STL_MEMBER_TEMPLATES */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/libstdc++/stl/stl_map.h b/libstdc++/stl/stl_map.h index 2a830cc65f2..a702e8023ef 100644 --- a/libstdc++/stl/stl_map.h +++ b/libstdc++/stl/stl_map.h @@ -35,177 +35,202 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , class Alloc = alloc> +template , + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > #else -template +template #endif class map { public: // typedefs: - typedef Key key_type; - typedef T data_type; - typedef T mapped_type; - typedef pair value_type; - typedef Compare key_compare; + typedef _Key key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef _Compare key_compare; class value_compare : public binary_function { - friend class map; + friend class map<_Key,_Tp,_Compare,_Alloc>; protected : - Compare comp; - value_compare(Compare c) : comp(c) {} + _Compare _M_comp; + value_compare(_Compare __c) : _M_comp(__c) {} public: - bool operator()(const value_type& x, const value_type& y) const { - return comp(x.first, y.first); + bool operator()(const value_type& __x, const value_type& __y) const { + return _M_comp(__x.first, __y.first); } }; private: - typedef rb_tree, key_compare, Alloc> rep_type; - rep_type t; // red-black tree representing map + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing map public: - typedef typename rep_type::pointer pointer; - typedef typename rep_type::const_pointer const_pointer; - typedef typename rep_type::reference reference; - typedef typename rep_type::const_reference const_reference; - typedef typename rep_type::iterator iterator; - typedef typename rep_type::const_iterator const_iterator; - typedef typename rep_type::reverse_iterator reverse_iterator; - typedef typename rep_type::const_reverse_iterator const_reverse_iterator; - typedef typename rep_type::size_type size_type; - typedef typename rep_type::difference_type difference_type; + typedef typename _Rep_type::pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation - map() : t(Compare()) {} - explicit map(const Compare& comp) : t(comp) {} + map() : _M_t(_Compare(), allocator_type()) {} + explicit map(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} #ifdef __STL_MEMBER_TEMPLATES - template - map(InputIterator first, InputIterator last) - : t(Compare()) { t.insert_unique(first, last); } - - template - map(InputIterator first, InputIterator last, const Compare& comp) - : t(comp) { t.insert_unique(first, last); } + template + map(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + template + map(_InputIterator __first, _InputIterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_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); } + map(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + map(const value_type* __first, + const value_type* __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } + + map(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + map(const_iterator __first, const_iterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } + #endif /* __STL_MEMBER_TEMPLATES */ - map(const map& x) : t(x.t) {} - map& operator=(const map& x) + map(const map<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} + map<_Key,_Tp,_Compare,_Alloc>& + operator=(const map<_Key, _Tp, _Compare, _Alloc>& __x) { - t = x.t; + _M_t = __x._M_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; + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return value_compare(_M_t.key_comp()); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() { return _M_t.begin(); } + const_iterator begin() const { return _M_t.begin(); } + iterator end() { return _M_t.end(); } + const_iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() { return _M_t.rbegin(); } + const_reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() { return _M_t.rend(); } + const_reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + _Tp& operator[](const key_type& __k) { + iterator __i = lower_bound(__k); + // __i->first is greater than or equivalent to __k. + if (__i == end() || key_comp()(__k, (*__i).first)) + __i = insert(__i, value_type(__k, _Tp())); + return (*__i).second; } - void swap(map& x) { t.swap(x.t); } + void swap(map<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } // insert/erase - pair insert(const value_type& x) { return t.insert_unique(x); } - iterator insert(iterator position, const value_type& x) { - return t.insert_unique(position, x); - } + pair insert(const value_type& __x) + { return _M_t.insert_unique(__x); } + iterator insert(iterator position, const value_type& __x) + { return _M_t.insert_unique(position, __x); } #ifdef __STL_MEMBER_TEMPLATES - template - void insert(InputIterator first, InputIterator last) { - t.insert_unique(first, last); + template + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_unique(__first, __last); } #else - void insert(const value_type* first, const value_type* last) { - t.insert_unique(first, last); + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_unique(__first, __last); } - void insert(const_iterator first, const_iterator last) { - t.insert_unique(first, last); + void insert(const_iterator __first, const_iterator __last) { + _M_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(); } + void erase(iterator __position) { _M_t.erase(__position); } + size_type erase(const key_type& __x) { return _M_t.erase(__x); } + void erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + void clear() { _M_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 find(const key_type& __x) { return _M_t.find(__x); } + const_iterator find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { return _M_t.count(__x); } + iterator lower_bound(const key_type& __x) {return _M_t.lower_bound(__x); } + const_iterator lower_bound(const key_type& __x) const { + return _M_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); + iterator upper_bound(const key_type& __x) {return _M_t.upper_bound(__x); } + const_iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); } - pair equal_range(const key_type& x) { - return t.equal_range(x); + pair equal_range(const key_type& __x) { + return _M_t.equal_range(__x); } - pair equal_range(const key_type& x) const { - return t.equal_range(x); + pair equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); } friend bool operator== __STL_NULL_TMPL_ARGS (const map&, const map&); friend bool operator< __STL_NULL_TMPL_ARGS (const map&, const map&); }; -template -inline bool operator==(const map& x, - const map& y) { - return x.t == y.t; +template +inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; } -template -inline bool operator<(const map& x, - const map& y) { - return x.t < y.t; +template +inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x, + const map<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template -inline void swap(map& x, - map& y) { - x.swap(y); +template +inline void swap(map<_Key,_Tp,_Compare,_Alloc>& __x, + map<_Key,_Tp,_Compare,_Alloc>& __y) { + __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/libstdc++/stl/stl_multimap.h b/libstdc++/stl/stl_multimap.h index b82159b648e..b7d3b87e52d 100644 --- a/libstdc++/stl/stl_multimap.h +++ b/libstdc++/stl/stl_multimap.h @@ -35,143 +35,160 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , class Alloc = alloc> +template , + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > #else -template +template #endif class multimap { public: // typedefs: - typedef Key key_type; - typedef T data_type; - typedef T mapped_type; - typedef pair value_type; - typedef Compare key_compare; + typedef _Key key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef _Compare key_compare; class value_compare : public binary_function { - friend class multimap; + friend class multimap<_Key,_Tp,_Compare,_Alloc>; protected: - Compare comp; - value_compare(Compare c) : comp(c) {} + _Compare _M_comp; + value_compare(_Compare __c) : _M_comp(__c) {} public: - bool operator()(const value_type& x, const value_type& y) const { - return comp(x.first, y.first); + bool operator()(const value_type& __x, const value_type& __y) const { + return _M_comp(__x.first, __y.first); } }; private: - typedef rb_tree, key_compare, Alloc> rep_type; - rep_type t; // red-black tree representing multimap + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing multimap public: - typedef typename rep_type::pointer pointer; - typedef typename rep_type::const_pointer const_pointer; - typedef typename rep_type::reference reference; - typedef typename rep_type::const_reference const_reference; - typedef typename rep_type::iterator iterator; - typedef typename rep_type::const_iterator const_iterator; - typedef typename rep_type::reverse_iterator reverse_iterator; - typedef typename rep_type::const_reverse_iterator const_reverse_iterator; - typedef typename rep_type::size_type size_type; - typedef typename rep_type::difference_type difference_type; + typedef typename _Rep_type::pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation - multimap() : t(Compare()) { } - explicit multimap(const Compare& comp) : t(comp) { } + multimap() : _M_t(_Compare(), allocator_type()) { } + explicit multimap(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } #ifdef __STL_MEMBER_TEMPLATES - template - multimap(InputIterator first, InputIterator last) - : t(Compare()) { t.insert_equal(first, last); } - - template - multimap(InputIterator first, InputIterator last, const Compare& comp) - : t(comp) { t.insert_equal(first, last); } + template + multimap(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + template + multimap(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_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); } + multimap(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + multimap(const value_type* __first, const value_type* __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } + + multimap(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + multimap(const_iterator __first, const_iterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ - multimap(const multimap& x) : t(x.t) { } - multimap& - operator=(const multimap& x) { - t = x.t; + multimap(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) : _M_t(__x._M_t) { } + multimap<_Key,_Tp,_Compare,_Alloc>& + operator=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x) { + _M_t = __x._M_t; return *this; } // accessors: - key_compare key_comp() const { return t.key_comp(); } - value_compare value_comp() const { return value_compare(t.key_comp()); } - iterator begin() { return t.begin(); } - const_iterator begin() const { return t.begin(); } - iterator end() { return t.end(); } - const_iterator end() const { return t.end(); } - reverse_iterator rbegin() { return t.rbegin(); } - const_reverse_iterator rbegin() const { return t.rbegin(); } - reverse_iterator rend() { return t.rend(); } - const_reverse_iterator rend() const { return t.rend(); } - bool empty() const { return t.empty(); } - size_type size() const { return t.size(); } - size_type max_size() const { return t.max_size(); } - void swap(multimap& x) { t.swap(x.t); } + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return value_compare(_M_t.key_comp()); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() { return _M_t.begin(); } + const_iterator begin() const { return _M_t.begin(); } + iterator end() { return _M_t.end(); } + const_iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() { return _M_t.rbegin(); } + const_reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() { return _M_t.rend(); } + const_reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + void swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_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); + iterator insert(const value_type& __x) { return _M_t.insert_equal(__x); } + iterator insert(iterator __position, const value_type& __x) { + return _M_t.insert_equal(__position, __x); } #ifdef __STL_MEMBER_TEMPLATES - template - void insert(InputIterator first, InputIterator last) { - t.insert_equal(first, last); + template + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_equal(__first, __last); } #else - void insert(const value_type* first, const value_type* last) { - t.insert_equal(first, last); + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_equal(__first, __last); } - void insert(const_iterator first, const_iterator last) { - t.insert_equal(first, last); + void insert(const_iterator __first, const_iterator __last) { + _M_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(); } + void erase(iterator __position) { _M_t.erase(__position); } + size_type erase(const key_type& __x) { return _M_t.erase(__x); } + void erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + void clear() { _M_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 find(const key_type& __x) { return _M_t.find(__x); } + const_iterator find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { return _M_t.count(__x); } + iterator lower_bound(const key_type& __x) {return _M_t.lower_bound(__x); } + const_iterator lower_bound(const key_type& __x) const { + return _M_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); + iterator upper_bound(const key_type& __x) {return _M_t.upper_bound(__x); } + const_iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); } - pair equal_range(const key_type& x) { - return t.equal_range(x); + pair equal_range(const key_type& __x) { + return _M_t.equal_range(__x); } - pair equal_range(const key_type& x) const { - return t.equal_range(x); + pair equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); } friend bool operator== __STL_NULL_TMPL_ARGS (const multimap&, const multimap&); @@ -179,30 +196,31 @@ public: const multimap&); }; -template -inline bool operator==(const multimap& x, - const multimap& y) { - return x.t == y.t; +template +inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; } -template -inline bool operator<(const multimap& x, - const multimap& y) { - return x.t < y.t; +template +inline bool operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, + const multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template -inline void swap(multimap& x, - multimap& y) { - x.swap(y); +template +inline void swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x, + multimap<_Key,_Tp,_Compare,_Alloc>& __y) { + __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/libstdc++/stl/stl_multiset.h b/libstdc++/stl/stl_multiset.h index ff5947e1490..7378e43f8b3 100644 --- a/libstdc++/stl/stl_multiset.h +++ b/libstdc++/stl/stl_multiset.h @@ -35,129 +35,152 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , class Alloc = alloc> +template , + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) > #else -template +template #endif class multiset { public: // typedefs: - typedef Key key_type; - typedef Key value_type; - typedef Compare key_compare; - typedef Compare value_compare; + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; private: - typedef rb_tree, key_compare, Alloc> rep_type; - rep_type t; // red-black tree representing multiset + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing multiset public: - typedef typename rep_type::const_pointer pointer; - typedef typename rep_type::const_pointer const_pointer; - typedef typename rep_type::const_reference reference; - typedef typename rep_type::const_reference const_reference; - typedef typename rep_type::const_iterator iterator; - typedef typename rep_type::const_iterator const_iterator; - typedef typename rep_type::const_reverse_iterator reverse_iterator; - typedef typename rep_type::const_reverse_iterator const_reverse_iterator; - typedef typename rep_type::size_type size_type; - typedef typename rep_type::difference_type difference_type; + typedef typename _Rep_type::const_pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::const_reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation - multiset() : t(Compare()) {} - explicit multiset(const Compare& comp) : t(comp) {} + multiset() : _M_t(_Compare(), allocator_type()) {} + explicit multiset(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} #ifdef __STL_MEMBER_TEMPLATES - template - multiset(InputIterator first, InputIterator last) - : t(Compare()) { t.insert_equal(first, last); } - template - multiset(InputIterator first, InputIterator last, const Compare& comp) - : t(comp) { t.insert_equal(first, last); } + + template + multiset(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + template + multiset(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_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); } + + multiset(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + multiset(const value_type* __first, const value_type* __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } + + multiset(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } + + multiset(const_iterator __first, const_iterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } + #endif /* __STL_MEMBER_TEMPLATES */ - multiset(const multiset& x) : t(x.t) {} - multiset& - operator=(const multiset& x) { - t = x.t; + multiset(const multiset<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} + multiset<_Key,_Compare,_Alloc>& + operator=(const multiset<_Key,_Compare,_Alloc>& __x) { + _M_t = __x._M_t; return *this; } // accessors: - key_compare key_comp() const { return t.key_comp(); } - value_compare value_comp() const { return t.key_comp(); } - iterator begin() const { return t.begin(); } - iterator end() const { return t.end(); } - reverse_iterator rbegin() const { return t.rbegin(); } - reverse_iterator rend() const { return t.rend(); } - bool empty() const { return t.empty(); } - size_type size() const { return t.size(); } - size_type max_size() const { return t.max_size(); } - void swap(multiset& x) { t.swap(x.t); } + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return _M_t.key_comp(); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() const { return _M_t.begin(); } + iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + void swap(multiset<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } // insert/erase - iterator insert(const value_type& x) { - return t.insert_equal(x); + iterator insert(const value_type& __x) { + return _M_t.insert_equal(__x); } - iterator insert(iterator position, const value_type& x) { - typedef typename rep_type::iterator rep_iterator; - return t.insert_equal((rep_iterator&)position, x); + iterator insert(iterator __position, const value_type& __x) { + typedef typename _Rep_type::iterator _Rep_iterator; + return _M_t.insert_equal((_Rep_iterator&)__position, __x); } #ifdef __STL_MEMBER_TEMPLATES - template - void insert(InputIterator first, InputIterator last) { - t.insert_equal(first, last); + template + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_equal(__first, __last); } #else - void insert(const value_type* first, const value_type* last) { - t.insert_equal(first, last); + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_equal(__first, __last); } - void insert(const_iterator first, const_iterator last) { - t.insert_equal(first, last); + void insert(const_iterator __first, const_iterator __last) { + _M_t.insert_equal(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ - void erase(iterator position) { - typedef typename rep_type::iterator rep_iterator; - t.erase((rep_iterator&)position); + void erase(iterator __position) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__position); } - size_type erase(const key_type& x) { - return t.erase(x); + size_type erase(const key_type& __x) { + return _M_t.erase(__x); } - void erase(iterator first, iterator last) { - typedef typename rep_type::iterator rep_iterator; - t.erase((rep_iterator&)first, (rep_iterator&)last); + void erase(iterator __first, iterator __last) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); } - void clear() { t.clear(); } + void clear() { _M_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 find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { return _M_t.count(__x); } + iterator lower_bound(const key_type& __x) const { + return _M_t.lower_bound(__x); } - iterator upper_bound(const key_type& x) const { - return t.upper_bound(x); + iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); } - pair equal_range(const key_type& x) const { - return t.equal_range(x); + pair equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); } friend bool operator== __STL_NULL_TMPL_ARGS (const multiset&, const multiset&); @@ -165,30 +188,31 @@ public: const multiset&); }; -template -inline bool operator==(const multiset& x, - const multiset& y) { - return x.t == y.t; +template +inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; } -template -inline bool operator<(const multiset& x, - const multiset& y) { - return x.t < y.t; +template +inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template -inline void swap(multiset& x, - multiset& y) { - x.swap(y); +template +inline void swap(multiset<_Key,_Compare,_Alloc>& __x, + multiset<_Key,_Compare,_Alloc>& __y) { + __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/libstdc++/stl/stl_numeric.h b/libstdc++/stl/stl_numeric.h index 57fee2b1b5c..da7865498ca 100644 --- a/libstdc++/stl/stl_numeric.h +++ b/libstdc++/stl/stl_numeric.h @@ -34,157 +34,200 @@ __STL_BEGIN_NAMESPACE -template -T accumulate(InputIterator first, InputIterator last, T init) { - for ( ; first != last; ++first) - init = init + *first; - return init; -} - -template -T accumulate(InputIterator first, InputIterator last, T init, - BinaryOperation binary_op) { - for ( ; first != last; ++first) - init = binary_op(init, *first); - return init; -} - -template -T inner_product(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, T init) { - for ( ; first1 != last1; ++first1, ++first2) - init = init + (*first1 * *first2); - return init; -} - -template -T inner_product(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, T init, BinaryOperation1 binary_op1, - BinaryOperation2 binary_op2) { - for ( ; first1 != last1; ++first1, ++first2) - init = binary_op1(init, binary_op2(*first1, *first2)); - return init; -} - -template -OutputIterator __partial_sum(InputIterator first, InputIterator last, - OutputIterator result, T*) { - T value = *first; - while (++first != last) { - value = value + *first; - *++result = value; +template +_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) +{ + for ( ; __first != __last; ++__first) + __init = __init + *__first; + return __init; +} + +template +_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, + _BinaryOperation __binary_op) +{ + for ( ; __first != __last; ++__first) + __init = __binary_op(__init, *__first); + return __init; +} + +template +_Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init) +{ + for ( ; __first1 != __last1; ++__first1, ++__first2) + __init = __init + (*__first1 * *__first2); + return __init; +} + +template +_Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, + _InputIterator2 __first2, _Tp __init, + _BinaryOperation1 __binary_op1, + _BinaryOperation2 __binary_op2) +{ + for ( ; __first1 != __last1; ++__first1, ++__first2) + __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); + return __init; +} + +template +_OutputIterator +__partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*) +{ + _Tp __value = *__first; + while (++__first != __last) { + __value = __value + *__first; + *++__result = __value; } - return ++result; -} - -template -OutputIterator partial_sum(InputIterator first, InputIterator last, - OutputIterator result) { - if (first == last) return result; - *result = *first; - return __partial_sum(first, last, result, value_type(first)); -} - -template -OutputIterator __partial_sum(InputIterator first, InputIterator last, - OutputIterator result, T*, - BinaryOperation binary_op) { - T value = *first; - while (++first != last) { - value = binary_op(value, *first); - *++result = value; + return ++__result; +} + +template +_OutputIterator +partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) +{ + if (__first == __last) return __result; + *__result = *__first; + return __partial_sum(__first, __last, __result, __VALUE_TYPE(__first)); +} + +template +_OutputIterator +__partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*, _BinaryOperation __binary_op) +{ + _Tp __value = *__first; + while (++__first != __last) { + __value = __binary_op(__value, *__first); + *++__result = __value; } - return ++result; + return ++__result; } -template -OutputIterator partial_sum(InputIterator first, InputIterator last, - OutputIterator result, BinaryOperation binary_op) { - if (first == last) return result; - *result = *first; - return __partial_sum(first, last, result, value_type(first), binary_op); +template +_OutputIterator +partial_sum(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryOperation __binary_op) +{ + if (__first == __last) return __result; + *__result = *__first; + return __partial_sum(__first, __last, __result, __VALUE_TYPE(__first), + __binary_op); } -template -OutputIterator __adjacent_difference(InputIterator first, InputIterator last, - OutputIterator result, T*) { - T value = *first; - while (++first != last) { - T tmp = *first; - *++result = tmp - value; - value = tmp; +template +_OutputIterator +__adjacent_difference(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*) +{ + _Tp __value = *__first; + while (++__first != __last) { + _Tp __tmp = *__first; + *++__result = __tmp - __value; + __value = __tmp; } - return ++result; -} - -template -OutputIterator adjacent_difference(InputIterator first, InputIterator last, - OutputIterator result) { - if (first == last) return result; - *result = *first; - return __adjacent_difference(first, last, result, value_type(first)); -} - -template -OutputIterator __adjacent_difference(InputIterator first, InputIterator last, - OutputIterator result, T*, - BinaryOperation binary_op) { - T value = *first; - while (++first != last) { - T tmp = *first; - *++result = binary_op(tmp, value); - value = tmp; + return ++__result; +} + +template +_OutputIterator +adjacent_difference(_InputIterator __first, + _InputIterator __last, _OutputIterator __result) +{ + if (__first == __last) return __result; + *__result = *__first; + return __adjacent_difference(__first, __last, __result, + __VALUE_TYPE(__first)); +} + +template +_OutputIterator +__adjacent_difference(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _Tp*, + _BinaryOperation __binary_op) { + _Tp __value = *__first; + while (++__first != __last) { + _Tp __tmp = *__first; + *++__result = __binary_op(__tmp, __value); + __value = __tmp; } - return ++result; -} - -template -OutputIterator adjacent_difference(InputIterator first, InputIterator last, - OutputIterator result, - BinaryOperation binary_op) { - if (first == last) return result; - *result = *first; - return __adjacent_difference(first, last, result, value_type(first), - binary_op); -} - -// Returns x ** n, where n >= 0. Note that "multiplication" -// is required to be associative, but not necessarily commutative. - -template -T power(T x, Integer n, MonoidOperation op) { - if (n == 0) - return identity_element(op); + return ++__result; +} + +template +_OutputIterator +adjacent_difference(_InputIterator __first, _InputIterator __last, + _OutputIterator __result, _BinaryOperation __binary_op) +{ + if (__first == __last) return __result; + *__result = *__first; + return __adjacent_difference(__first, __last, __result, + __VALUE_TYPE(__first), + __binary_op); +} + +// Returns __x ** __n, where __n >= 0. _Note that "multiplication" +// is required to be associative, but not necessarily commutative. + + +template +_Tp __power(_Tp __x, _Integer __n, _MonoidOperation __opr) +{ + if (__n == 0) + return identity_element(__opr); else { - while ((n & 1) == 0) { - n >>= 1; - x = op(x, x); + while ((__n & 1) == 0) { + __n >>= 1; + __x = __opr(__x, __x); } - T result = x; - n >>= 1; - while (n != 0) { - x = op(x, x); - if ((n & 1) != 0) - result = op(result, x); - n >>= 1; + _Tp __result = __x; + __n >>= 1; + while (__n != 0) { + __x = __opr(__x, __x); + if ((__n & 1) != 0) + __result = __opr(__result, __x); + __n >>= 1; } - return result; + return __result; } } -template -inline T power(T x, Integer n) { - return power(x, n, multiplies()); +template +inline _Tp __power(_Tp __x, _Integer __n) +{ + return __power(__x, __n, multiplies<_Tp>()); +} + +// Alias for the internal name __power. Note that power is an extension, +// not part of the C++ standard. + +template +inline _Tp power(_Tp __x, _Integer __n, _MonoidOperation __opr) +{ + return __power(__x, __n, __opr); +} + +template +inline _Tp power(_Tp __x, _Integer __n) +{ + return __power(__x, __n); } +// iota is not part of the C++ standard. It is an extension. -template -void iota(ForwardIterator first, ForwardIterator last, T value) { - while (first != last) *first++ = value++; +template +void +iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value) +{ + while (__first != __last) + *__first++ = __value++; } __STL_END_NAMESPACE diff --git a/libstdc++/stl/stl_pair.h b/libstdc++/stl/stl_pair.h index 10a9cb08e3b..3aa290b59ed 100644 --- a/libstdc++/stl/stl_pair.h +++ b/libstdc++/stl/stl_pair.h @@ -33,35 +33,39 @@ __STL_BEGIN_NAMESPACE -template +template struct pair { - typedef T1 first_type; - typedef T2 second_type; + 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) {} + _T1 first; + _T2 second; + pair() : first(_T1()), second(_T2()) {} + pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) {} #ifdef __STL_MEMBER_TEMPLATES - template - pair(const pair& p) : first(p.first), second(p.second) {} + template + pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {} #endif }; -template -inline bool operator==(const pair& x, const pair& y) { - return x.first == y.first && x.second == y.second; +template +inline bool operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) +{ + return __x.first == __y.first && __x.second == __y.second; } -template -inline bool operator<(const pair& x, const pair& y) { - return x.first < y.first || (!(y.first < x.first) && x.second < y.second); +template +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 -inline pair make_pair(const T1& x, const T2& y) { - return pair(x, y); +template +inline pair<_T1, _T2> make_pair(const _T1& __x, const _T2& __y) +{ + return pair<_T1, _T2>(__x, __y); } __STL_END_NAMESPACE diff --git a/libstdc++/stl/stl_queue.h b/libstdc++/stl/stl_queue.h index ff6eedeb701..489cc4ac442 100644 --- a/libstdc++/stl/stl_queue.h +++ b/libstdc++/stl/stl_queue.h @@ -34,92 +34,160 @@ __STL_BEGIN_NAMESPACE #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template > +template > #else -template +template #endif class queue { - friend bool operator== __STL_NULL_TMPL_ARGS (const queue& x, const queue& y); - friend bool operator< __STL_NULL_TMPL_ARGS (const queue& x, const queue& y); + friend bool operator== __STL_NULL_TMPL_ARGS (const queue&, const queue&); + friend bool operator< __STL_NULL_TMPL_ARGS (const queue&, const queue&); public: - typedef typename Sequence::value_type value_type; - typedef typename Sequence::size_type size_type; - typedef typename Sequence::reference reference; - typedef typename Sequence::const_reference const_reference; + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; protected: - Sequence c; + _Sequence _M_c; public: - bool empty() const { return c.empty(); } - size_type size() const { return c.size(); } - reference front() { return c.front(); } - const_reference front() const { return c.front(); } - reference back() { return c.back(); } - const_reference back() const { return c.back(); } - void push(const value_type& x) { c.push_back(x); } - void pop() { c.pop_front(); } + queue() : _M_c() {} + explicit queue(const _Sequence& __c) : _M_c(__c) {} + + bool empty() const { return _M_c.empty(); } + size_type size() const { return _M_c.size(); } + reference front() { return _M_c.front(); } + const_reference front() const { return _M_c.front(); } + reference back() { return _M_c.back(); } + const_reference back() const { return _M_c.back(); } + void push(const value_type& __x) { _M_c.push_back(__x); } + void pop() { _M_c.pop_front(); } }; -template -bool operator==(const queue& x, const queue& y) { - return x.c == y.c; +template +bool +operator==(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return __x._M_c == __y._M_c; +} + +template +bool +operator<(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return __x._M_c < __y._M_c; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +bool +operator!=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return !(__x == __y); } -template -bool operator<(const queue& x, const queue& y) { - return x.c < y.c; +template +bool +operator>(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return __y < __x; } +template +bool +operator<=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return !(__y < __x); +} + +template +bool +operator>=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y) +{ + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , - class Compare = less > +template , + class _Compare = less > #else -template +template #endif class priority_queue { public: - typedef typename Sequence::value_type value_type; - typedef typename Sequence::size_type size_type; - typedef typename Sequence::reference reference; - typedef typename Sequence::const_reference const_reference; + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; protected: - Sequence c; - Compare comp; + _Sequence _M_c; + _Compare _M_comp; public: - priority_queue() : c() {} - explicit priority_queue(const Compare& x) : c(), comp(x) {} + priority_queue() : _M_c() {} + explicit priority_queue(const _Compare& __x) : _M_c(), _M_comp(__x) {} + priority_queue(const _Compare& __x, const _Sequence& __s) + : _M_c(__s), _M_comp(__x) + { make_heap(_M_c.begin(), _M_c.end(), _M_comp); } #ifdef __STL_MEMBER_TEMPLATES - template - priority_queue(InputIterator first, InputIterator last, const Compare& x) - : c(first, last), comp(x) { make_heap(c.begin(), c.end(), comp); } - template - priority_queue(InputIterator first, InputIterator last) - : c(first, last) { make_heap(c.begin(), c.end(), comp); } + template + priority_queue(_InputIterator __first, _InputIterator __last) + : _M_c(__first, __last) { make_heap(_M_c.begin(), _M_c.end(), _M_comp); } + + template + priority_queue(_InputIterator __first, + _InputIterator __last, const _Compare& __x) + : _M_c(__first, __last), _M_comp(__x) + { make_heap(_M_c.begin(), _M_c.end(), _M_comp); } + + template + priority_queue(_InputIterator __first, _InputIterator __last, + const _Compare& __x, const _Sequence& __s) + : _M_c(__s), _M_comp(__x) + { + _M_c.insert(_M_c.end(), __first, __last); + make_heap(_M_c.begin(), _M_c.end(), _M_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) + : _M_c(__first, __last) { make_heap(_M_c.begin(), _M_c.end(), _M_comp); } + + priority_queue(const value_type* __first, const value_type* __last, + const _Compare& __x) + : _M_c(__first, __last), _M_comp(__x) + { make_heap(_M_c.begin(), _M_c.end(), _M_comp); } + + priority_queue(const value_type* __first, const value_type* __last, + const _Compare& __x, const _Sequence& __c) + : _M_c(__c), _M_comp(__x) + { + _M_c.insert(_M_c.end(), __first, __last); + make_heap(_M_c.begin(), _M_c.end(), _M_comp); } - priority_queue(const value_type* first, const value_type* last) - : c(first, last) { make_heap(c.begin(), c.end(), comp); } #endif /* __STL_MEMBER_TEMPLATES */ - bool empty() const { return c.empty(); } - size_type size() const { return c.size(); } - const_reference top() const { return c.front(); } - void push(const value_type& x) { + bool empty() const { return _M_c.empty(); } + size_type size() const { return _M_c.size(); } + const_reference top() const { return _M_c.front(); } + void push(const value_type& __x) { __STL_TRY { - c.push_back(x); - push_heap(c.begin(), c.end(), comp); + _M_c.push_back(__x); + push_heap(_M_c.begin(), _M_c.end(), _M_comp); } - __STL_UNWIND(c.clear()); + __STL_UNWIND(_M_c.clear()); } void pop() { __STL_TRY { - pop_heap(c.begin(), c.end(), comp); - c.pop_back(); + pop_heap(_M_c.begin(), _M_c.end(), _M_comp); + _M_c.pop_back(); } - __STL_UNWIND(c.clear()); + __STL_UNWIND(_M_c.clear()); } }; diff --git a/libstdc++/stl/stl_raw_storage_iter.h b/libstdc++/stl/stl_raw_storage_iter.h index 5d3d0747b5e..6f3951cb8af 100644 --- a/libstdc++/stl/stl_raw_storage_iter.h +++ b/libstdc++/stl/stl_raw_storage_iter.h @@ -25,7 +25,7 @@ */ /* NOTE: This is an internal header file, included by other STL headers. - * You should not attempt to use it directly. + * You should not attempt to use it directly. */ #ifndef __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H @@ -33,10 +33,10 @@ __STL_BEGIN_NAMESPACE -template +template class raw_storage_iterator { protected: - ForwardIterator iter; + _ForwardIterator _M_iter; public: typedef output_iterator_tag iterator_category; typedef void value_type; @@ -44,38 +44,38 @@ public: typedef void pointer; typedef void reference; - explicit raw_storage_iterator(ForwardIterator x) : iter(x) {} - raw_storage_iterator& operator*() { return *this; } - raw_storage_iterator& operator=(const T& element) { - construct(&*iter, element); + explicit raw_storage_iterator(_ForwardIterator __x) : _M_iter(__x) {} + raw_storage_iterator& operator*() { return *this; } + raw_storage_iterator& operator=(const _Tp& __element) { + construct(&*_M_iter, __element); return *this; } - raw_storage_iterator& operator++() { - ++iter; + raw_storage_iterator<_ForwardIterator, _Tp>& operator++() { + ++_M_iter; return *this; } - raw_storage_iterator operator++(int) { - raw_storage_iterator tmp = *this; - ++iter; - return tmp; + raw_storage_iterator<_ForwardIterator, _Tp> operator++(int) { + raw_storage_iterator<_ForwardIterator, _Tp> __tmp = *this; + ++_M_iter; + return __tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -template +template inline output_iterator_tag -iterator_category(const raw_storage_iterator&) +iterator_category(const raw_storage_iterator<_ForwardIterator, _Tp>&) { return output_iterator_tag(); } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -#endif /* __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H */ - __STL_END_NAMESPACE +#endif /* __SGI_STL_INTERNAL_RAW_STORAGE_ITERATOR_H */ + // Local Variables: // mode:C++ // End: diff --git a/libstdc++/stl/stl_relops.h b/libstdc++/stl/stl_relops.h index 01a0c7cdfcb..16cad1b84e2 100644 --- a/libstdc++/stl/stl_relops.h +++ b/libstdc++/stl/stl_relops.h @@ -33,24 +33,24 @@ __STL_BEGIN_RELOPS_NAMESPACE -template -inline bool operator!=(const T& x, const T& y) { - return !(x == y); +template +inline bool operator!=(const _Tp& __x, const _Tp& __y) { + return !(__x == __y); } -template -inline bool operator>(const T& x, const T& y) { - return y < x; +template +inline bool operator>(const _Tp& __x, const _Tp& __y) { + return __y < __x; } -template -inline bool operator<=(const T& x, const T& y) { - return !(y < x); +template +inline bool operator<=(const _Tp& __x, const _Tp& __y) { + return !(__y < __x); } -template -inline bool operator>=(const T& x, const T& y) { - return !(x < y); +template +inline bool operator>=(const _Tp& __x, const _Tp& __y) { + return !(__x < __y); } __STL_END_RELOPS_NAMESPACE diff --git a/libstdc++/stl/stl_rope.h b/libstdc++/stl/stl_rope.h index d37c679ba28..44f51aed1ae 100644 --- a/libstdc++/stl/stl_rope.h +++ b/libstdc++/stl/stl_rope.h @@ -15,6 +15,12 @@ * You should not attempt to use it directly. */ +// rope<_CharT,_Alloc> is a sequence of _CharT. +// Ropes appear to be mutable, but update operations +// really copy enough of the data structure to leave the original +// valid. Thus ropes can be logically copied by just copying +// a pointer value. + #ifndef __SGI_STL_INTERNAL_ROPE_H # define __SGI_STL_INTERNAL_ROPE_H @@ -33,49 +39,47 @@ __STL_BEGIN_NAMESPACE #pragma set woff 1174 #endif +// The _S_eos function is used for those functions that +// convert to/from C-like strings to detect the end of the string. + // The end-of-C-string character. // This is what the draft standard says it should be. -template -inline charT __eos(charT*) { return charT(); } +template +inline _CharT _S_eos(_CharT*) { return _CharT(); } // Test for basic character types. // For basic character types leaves having a trailing eos. -template -inline bool __is_basic_char_type(charT *) { return false; } -template -inline bool __is_one_byte_char_type(charT *) { return false; } - -inline bool __is_basic_char_type(char *) { return true; } -inline bool __is_one_byte_char_type(char *) { return true; } -inline bool __is_basic_char_type(wchar_t *) { return true; } - -// Store an eos iff charT is a basic character type. -// Do not reference __eos if it isn't. -template -inline void __cond_store_eos(charT&) {} - -inline void __cond_store_eos(char& c) { c = 0; } -inline void __cond_store_eos(wchar_t& c) { c = 0; } - - -// rope is a sequence of charT. -// Ropes appear to be mutable, but update operations -// really copy enough of the data structure to leave the original -// valid. Thus ropes can be logically copied by just copying -// a pointer value. -// The __eos function is used for those functions that -// convert to/from C-like strings to detect the end of the string. -// __compare is used as the character comparison function. -template +template +inline bool _S_is_basic_char_type(_CharT*) { return false; } +template +inline bool _S_is_one_byte_char_type(_CharT*) { return false; } + +inline bool _S_is_basic_char_type(char*) { return true; } +inline bool _S_is_one_byte_char_type(char*) { return true; } +inline bool _S_is_basic_char_type(wchar_t*) { return true; } + +// Store an eos iff _CharT is a basic character type. +// Do not reference _S_eos if it isn't. +template +inline void _S_cond_store_eos(_CharT&) {} + +inline void _S_cond_store_eos(char& __c) { __c = 0; } +inline void _S_cond_store_eos(wchar_t& __c) { __c = 0; } + +// char_producers are logically functions that generate a section of +// a string. These can be convereted to ropes. The resulting rope +// invokes the char_producer on demand. This allows, for example, +// files to be viewed as ropes without reading the entire file. +template class char_producer { public: - virtual ~char_producer() {}; - virtual void operator()(size_t start_pos, size_t len, charT* buffer) - = 0; - // Buffer should really be an arbitrary output iterator. - // That way we could flatten directly into an ostream, etc. - // This is thoroughly impossible, since iterator types don't - // have runtime descriptions. + virtual ~char_producer() {}; + virtual void operator()(size_t __start_pos, size_t __len, + _CharT* __buffer) = 0; + // Buffer should really be an arbitrary output iterator. + // That way we could flatten directly into an ostream, etc. + // This is thoroughly impossible, since iterator types don't + // have runtime descriptions. }; // Sequence buffers: @@ -92,111 +96,112 @@ class char_producer { // behave a little like basic_ostringstream and a // little like containers. -template // The 3rd parameter works around a common compiler bug. class sequence_buffer : public output_iterator { public: # ifndef __TYPEDEF_WORKAROUND - typedef typename sequence::value_type value_type; -# else - typedef v value_type; -# endif + typedef typename _Sequence::value_type value_type; +# else + typedef _V value_type; +# endif protected: - sequence *prefix; - value_type buffer[buf_sz]; - size_t buf_count; + _Sequence* _M_prefix; + value_type _M_buffer[_Buf_sz]; + size_t _M_buf_count; public: - void flush() { - prefix->append(buffer, buffer + buf_count); - buf_count = 0; - } - ~sequence_buffer() { flush(); } - sequence_buffer() : prefix(0), buf_count(0) {} - sequence_buffer(const sequence_buffer & x) { - prefix = x.prefix; - buf_count = x.buf_count; - copy(x.buffer, x.buffer + x.buf_count, buffer); - } - sequence_buffer(sequence_buffer & x) { - x.flush(); - prefix = x.prefix; - buf_count = 0; - } - sequence_buffer(sequence& s) : prefix(&s), buf_count(0) {} - sequence_buffer& operator= (sequence_buffer& x) { - x.flush(); - prefix = x.prefix; - buf_count = 0; - return *this; - } - sequence_buffer& operator= (const sequence_buffer& x) { - prefix = x.prefix; - buf_count = x.buf_count; - copy(x.buffer, x.buffer + x.buf_count, buffer); - return *this; - } - void push_back(value_type x) - { - if (buf_count < buf_sz) { - buffer[buf_count] = x; - ++buf_count; - } else { - flush(); - buffer[0] = x; - buf_count = 1; - } - } - void append(value_type *s, size_t len) - { - if (len + buf_count <= buf_sz) { - size_t i, j; - for (i = buf_count, j = 0; j < len; i++, j++) { - buffer[i] = s[j]; - } - buf_count += len; - } else if (0 == buf_count) { - prefix->append(s, s + len); - } else { - flush(); - append(s, len); - } - } - sequence_buffer& write(value_type *s, size_t len) - { - append(s, len); - return *this; - } - sequence_buffer& put(value_type x) - { - push_back(x); - return *this; - } - sequence_buffer& operator=(const value_type& rhs) - { - push_back(rhs); - return *this; - } - sequence_buffer& operator*() { return *this; } - sequence_buffer& operator++() { return *this; } - sequence_buffer& operator++(int) { return *this; } + void flush() { + _M_prefix->append(_M_buffer, _M_buffer + _M_buf_count); + _M_buf_count = 0; + } + ~sequence_buffer() { flush(); } + sequence_buffer() : _M_prefix(0), _M_buf_count(0) {} + sequence_buffer(const sequence_buffer& __x) { + _M_prefix = __x._M_prefix; + _M_buf_count = __x._M_buf_count; + copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); + } + sequence_buffer(sequence_buffer& __x) { + __x.flush(); + _M_prefix = __x._M_prefix; + _M_buf_count = 0; + } + sequence_buffer(_Sequence& __s) : _M_prefix(&__s), _M_buf_count(0) {} + sequence_buffer& operator= (sequence_buffer& __x) { + __x.flush(); + _M_prefix = __x._M_prefix; + _M_buf_count = 0; + return *this; + } + sequence_buffer& operator= (const sequence_buffer& __x) { + _M_prefix = __x._M_prefix; + _M_buf_count = __x._M_buf_count; + copy(__x._M_buffer, __x._M_buffer + __x._M_buf_count, _M_buffer); + return *this; + } + void push_back(value_type __x) + { + if (_M_buf_count < _Buf_sz) { + _M_buffer[_M_buf_count] = __x; + ++_M_buf_count; + } else { + flush(); + _M_buffer[0] = __x; + _M_buf_count = 1; + } + } + void append(value_type* __s, size_t __len) + { + if (__len + _M_buf_count <= _Buf_sz) { + size_t __i = _M_buf_count; + size_t __j = 0; + for (; __j < __len; __i++, __j++) { + _M_buffer[__i] = __s[__j]; + } + _M_buf_count += __len; + } else if (0 == _M_buf_count) { + _M_prefix->append(__s, __s + __len); + } else { + flush(); + append(__s, __len); + } + } + sequence_buffer& write(value_type* __s, size_t __len) + { + append(__s, __len); + return *this; + } + sequence_buffer& put(value_type __x) + { + push_back(__x); + return *this; + } + sequence_buffer& operator=(const value_type& __rhs) + { + push_back(__rhs); + return *this; + } + sequence_buffer& operator*() { return *this; } + sequence_buffer& operator++() { return *this; } + sequence_buffer& operator++(int) { return *this; } }; // The following should be treated as private, at least for now. -template -class __rope_char_consumer { +template +class _Rope_char_consumer { public: - // If we had member templates, these should not be virtual. - // For now we need to use run-time parametrization where - // compile-time would do. Hence this should all be private - // for now. - // The symmetry with char_producer is accidental and temporary. - virtual ~__rope_char_consumer() {}; - virtual bool operator()(const charT* buffer, size_t len) = 0; + // If we had member templates, these should not be virtual. + // For now we need to use run-time parametrization where + // compile-time would do. _Hence this should all be private + // for now. + // The symmetry with char_producer is accidental and temporary. + virtual ~_Rope_char_consumer() {}; + virtual bool operator()(const _CharT* __buffer, size_t __len) = 0; }; // @@ -205,22 +210,22 @@ class __rope_char_consumer { // equality on rope iterators. According to the draft standard, the // template parameters for such an equality operator cannot be inferred // from the occurence of a member class as a parameter. -// (SGI compilers in fact allow this, but the result wouldn't be +// (SGI compilers in fact allow this, but the __result wouldn't be // portable.) // Similarly, some of the static member functions are member functions // only to avoid polluting the global namespace, and to circumvent // restrictions on type inference for template functions. // -template class rope; -template struct __rope_RopeConcatenation; -template struct __rope_RopeLeaf; -template struct __rope_RopeFunction; -template struct __rope_RopeSubstring; -template class __rope_iterator; -template class __rope_const_iterator; -template class __rope_charT_ref_proxy; -template class __rope_charT_ptr_proxy; +template class rope; +template struct _Rope_RopeConcatenation; +template struct _Rope_RopeLeaf; +template struct _Rope_RopeFunction; +template struct _Rope_RopeSubstring; +template class _Rope_iterator; +template class _Rope_const_iterator; +template class _Rope_char_ref_proxy; +template class _Rope_char_ptr_proxy; // // The internal data structure for representing a rope. This is @@ -228,273 +233,488 @@ template class __rope_charT_ptr_proxy; // to one of these. // // A few basic functions for manipulating this data structure -// are members of RopeBase. Most of the more complex algorithms +// are members of _RopeRep. Most of the more complex algorithms // are implemented as rope members. // -// Some of the static member functions of RopeBase have identically -// named functions in rope that simply invoke the RopeBase versions. +// Some of the static member functions of _RopeRep have identically +// named functions in rope that simply invoke the _RopeRep versions. // +// A macro to introduce various allocation and deallocation functions +// These need to be defined differently depending on whether or not +// we are using standard conforming allocators, and whether the allocator +// instances have real state. Thus this macro is invoked repeatedly +// with different definitions of __ROPE_DEFINE_ALLOC. +// __ROPE_DEFINE_ALLOC(type,name) defines +// type * name_allocate(size_t) and +// void name_deallocate(tipe *, size_t) +// Both functions may or may not be static. + +#define __ROPE_DEFINE_ALLOCS(__a) \ + __ROPE_DEFINE_ALLOC(_CharT,_Data) /* character data */ \ + typedef _Rope_RopeConcatenation<_CharT,__a> __C; \ + __ROPE_DEFINE_ALLOC(__C,_C) \ + typedef _Rope_RopeLeaf<_CharT,__a> __L; \ + __ROPE_DEFINE_ALLOC(__L,_L) \ + typedef _Rope_RopeFunction<_CharT,__a> __F; \ + __ROPE_DEFINE_ALLOC(__F,_F) \ + typedef _Rope_RopeSubstring<_CharT,__a> __S; \ + __ROPE_DEFINE_ALLOC(__S,_S) + +// Internal rope nodes potentially store a copy of the allocator +// instance used to allocate them. This is mostly redundant. +// But the alternative would be to pass allocator instances around +// in some form to nearly all internal functions, since any pointer +// assignment may result in a zero reference count and thus require +// deallocation. +// The _Rope_rep_base class encapsulates +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +#define __STATIC_IF_SGI_ALLOC /* not static */ + +// Base class for ordinary allocators. +template +class _Rope_rep_alloc_base { +public: + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + _Rope_rep_alloc_base(size_t __size, const allocator_type& __a) + : _M_size(__size), _M_data_allocator(__a) {} + size_t _M_size; // This is here only to avoid wasting space + // for an otherwise empty base class. + + +protected: + allocator_type _M_data_allocator; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + /*static*/ _Tp * __name##_allocate(size_t __n) \ + { return __name##Allocator(_M_data_allocator).allocate(__n); } \ + void __name##_deallocate(_Tp* __p, size_t __n) \ + { __name##Allocator(_M_data_allocator).deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator); +# undef __ROPE_DEFINE_ALLOC +}; + +// Specialization for allocators that have the property that we don't +// actually have to store an allocator object. +template +class _Rope_rep_alloc_base<_CharT,_Allocator,true> { +public: + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + _Rope_rep_alloc_base(size_t __size, const allocator_type&) + : _M_size(__size) {} + size_t _M_size; + +protected: + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::_Alloc_type __name##Alloc; \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator); +# undef __ROPE_DEFINE_ALLOC +}; + +template +struct _Rope_rep_base + : public _Rope_rep_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> +{ + typedef _Rope_rep_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + _Rope_rep_base(size_t __size, const allocator_type& __a) + : _Base(__size, __a) {} +}; + +#else /* !__STL_USE_STD_ALLOCATORS */ + +#define __STATIC_IF_SGI_ALLOC static + +template +class _Rope_rep_base { +public: + typedef _Alloc allocator_type; + static allocator_type get_allocator() { return allocator_type(); } + _Rope_rep_base(size_t __size, const allocator_type&) : _M_size(__size) {} + size_t _M_size; + +protected: + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef simple_alloc<_Tp, _Alloc> __name##Alloc; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + static void __name##_deallocate(_Tp* __p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Alloc); +# undef __ROPE_DEFINE_ALLOC +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ -template -struct __rope_RopeBase { - typedef rope my_rope; - typedef simple_alloc DataAlloc; - typedef simple_alloc<__rope_RopeConcatenation, Alloc> CAlloc; - typedef simple_alloc<__rope_RopeLeaf, Alloc> LAlloc; - typedef simple_alloc<__rope_RopeFunction, Alloc> FAlloc; - typedef simple_alloc<__rope_RopeSubstring, Alloc> SAlloc; + +template +struct _Rope_RopeRep : public _Rope_rep_base<_CharT,_Alloc> { public: - enum { max_rope_depth = 45 }; - enum {leaf, concat, substringfn, function} tag:8; - bool is_balanced:8; - unsigned char depth; - size_t size; - __GC_CONST charT * c_string; - /* Flattened version of string, if needed. */ - /* typically 0. */ - /* If it's not 0, then the memory is owned */ - /* by this node. */ - /* In the case of a leaf, this may point to */ - /* the same memory as the data field. */ + enum { _S_max_rope_depth = 45 }; + enum _Tag {_S_leaf, _S_concat, _S_substringfn, _S_function}; + _Tag _M_tag:8; + bool _M_is_balanced:8; + unsigned char _M_depth; + __GC_CONST _CharT* _M_c_string; + /* Flattened version of string, if needed. */ + /* typically 0. */ + /* If it's not 0, then the memory is owned */ + /* by this node. */ + /* In the case of a leaf, this may point to */ + /* the same memory as the data field. */ + typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; + _Rope_RopeRep(_Tag __t, int __d, bool __b, size_t __size, + allocator_type __a) + : _M_tag(__t), _M_depth(__d), _M_is_balanced(__b), _M_c_string(0), + _Rope_rep_base<_CharT,_Alloc>(__size, __a) + { +# ifndef __GC + _M_refcount = 1; + _M_init_refcount_lock(); +# endif + } # ifndef __GC # if defined(__STL_WIN32THREADS) - long refcount; // InterlockedIncrement wants a long * -# else - size_t refcount; -# endif - // We count references from rope instances - // and references from other rope nodes. We - // do not count const_iterator references. - // Iterator references are counted so that rope modifications - // can be detected after the fact. - // Generally function results are counted, i.e. - // a pointer returned by a function is included at the - // point at which the pointer is returned. - // The recipient should decrement the count if the - // result is not needed. - // Generally function arguments are not reflected - // in the reference count. The callee should increment - // the count before saving the argument someplace that - // will outlive the call. + long _M_refcount; // InterlockedIncrement wants a long * +# else + size_t _M_refcount; +# endif + // We count references from rope instances + // and references from other rope nodes. We + // do not count const_iterator references. + // Iterator references are counted so that rope modifications + // can be detected after the fact. + // Generally function results are counted, i.__e. + // a pointer returned by a function is included at the + // point at which the pointer is returned. + // The recipient should decrement the count if the + // __result is not needed. + // Generally function arguments are not reflected + // in the reference count. The callee should increment + // the count before saving the argument someplace that + // will outlive the call. # endif # ifndef __GC # ifdef __STL_SGI_THREADS - // Reference counting with multiple threads and no - // hardware or thread package support is pretty awful. - // Mutexes are normally too expensive. - // We'll assume a COMPARE_AND_SWAP(destp, old, new) - // operation, which might be cheaper. + // Reference counting with multiple threads and no + // hardware or thread package support is pretty awful. + // Mutexes are normally too expensive. + // We'll assume a COMPARE_AND_SWAP(destp, __old, new) + // operation, which might be cheaper. # if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) -# define __add_and_fetch(l,v) add_then_test((unsigned long *)l,v) +# define __add_and_fetch(l,v) add_then_test((unsigned long*)l,v) # endif - void init_refcount_lock() {} - void incr_refcount () - { - __add_and_fetch(&refcount, 1); - } - size_t decr_refcount () - { - return __add_and_fetch(&refcount, (size_t)(-1)); - } + void _M_init_refcount_lock() {} + void _M_incr_refcount () + { + __add_and_fetch(&_M_refcount, 1); + } + size_t _M_decr_refcount () + { + return __add_and_fetch(&_M_refcount, (size_t)(-1)); + } # elif defined(__STL_WIN32THREADS) - void init_refcount_lock() {} - void incr_refcount () + void _M_init_refcount_lock() {} + void _M_incr_refcount () { - InterlockedIncrement(&refcount); + InterlockedIncrement(&_M_refcount); } - size_t decr_refcount () + size_t _M_decr_refcount () { - return InterlockedDecrement(&refcount); + return InterlockedDecrement(&_M_refcount); } # elif defined(__STL_PTHREADS) - // This should be portable, but performance is expected - // to be quite awful. This really needs platform specific - // code. - pthread_mutex_t refcount_lock; - void init_refcount_lock() { - pthread_mutex_init(&refcount_lock, 0); - } - void incr_refcount () + // This should be portable, but performance is expected + // to be quite awful. This really needs platform specific + // code. + pthread_mutex_t _M_refcount_lock; + void _M_init_refcount_lock() { + pthread_mutex_init(&_M_refcount_lock, 0); + } + void _M_incr_refcount () { - pthread_mutex_lock(&refcount_lock); - ++refcount; - pthread_mutex_unlock(&refcount_lock); + pthread_mutex_lock(&_M_refcount_lock); + ++_M_refcount; + pthread_mutex_unlock(&_M_refcount_lock); } - size_t decr_refcount () + size_t _M_decr_refcount () { - size_t result; - pthread_mutex_lock(&refcount_lock); - result = --refcount; - pthread_mutex_unlock(&refcount_lock); - return result; + size_t __result; + pthread_mutex_lock(&_M_refcount_lock); + __result = --_M_refcount; + pthread_mutex_unlock(&_M_refcount_lock); + return __result; + } +# else + void _M_init_refcount_lock() {} + void _M_incr_refcount () + { + ++_M_refcount; + } + size_t _M_decr_refcount () + { + --_M_refcount; + return _M_refcount; } -# else - void init_refcount_lock() {} - void incr_refcount () - { - ++refcount; - } - size_t decr_refcount () - { - --refcount; - return refcount; - } # endif # else - void incr_refcount () {} + void _M_incr_refcount () {} +# endif +# ifdef __STL_USE_STD_ALLOCATORS + static void _S_free_string(__GC_CONST _CharT*, size_t __len, + allocator_type __a); +# define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l, __a); +# else + static void _S_free_string(__GC_CONST _CharT*, size_t __len); +# define __STL_FREE_STRING(__s, __l, __a) _S_free_string(__s, __l); # endif - static void free_string(charT *, size_t len); - // Deallocate data section of a leaf. - // This shouldn't be a member function. - // But its hard to do anything else at the - // moment, because it's templatized w.r.t. - // an allocator. - // Does nothing if __GC is defined. + // Deallocate data section of a leaf. + // This shouldn't be a member function. + // But its hard to do anything else at the + // moment, because it's templatized w.r.t. + // an allocator. + // Does nothing if __GC is defined. # ifndef __GC - void free_c_string(); - void free_tree(); - // Deallocate t. Assumes t is not 0. - void unref_nonnil() - { - if (0 == decr_refcount()) free_tree(); - } - void ref_nonnil() - { - incr_refcount(); - } - static void unref(__rope_RopeBase* t) - { - if (0 != t) { - t -> unref_nonnil(); - } - } - static void ref(__rope_RopeBase* t) - { - if (0 != t) t -> incr_refcount(); - } - static void free_if_unref(__rope_RopeBase* t) - { - if (0 != t && 0 == t -> refcount) t -> free_tree(); - } + void _M_free_c_string(); + void _M_free_tree(); + // Deallocate t. Assumes t is not 0. + void _M_unref_nonnil() + { + if (0 == _M_decr_refcount()) _M_free_tree(); + } + void _M_ref_nonnil() + { + _M_incr_refcount(); + } + static void _S_unref(_Rope_RopeRep* __t) + { + if (0 != __t) { + __t->_M_unref_nonnil(); + } + } + static void _S_ref(_Rope_RopeRep* __t) + { + if (0 != __t) __t->_M_incr_refcount(); + } + static void _S_free_if_unref(_Rope_RopeRep* __t) + { + if (0 != __t && 0 == __t->_M_refcount) __t->_M_free_tree(); + } # else /* __GC */ - void unref_nonnil() {} - void ref_nonnil() {} - static void unref(__rope_RopeBase* t) {} - static void ref(__rope_RopeBase* t) {} - static void fn_finalization_proc(void * tree, void *); - static void free_if_unref(__rope_RopeBase* t) {} + void _M_unref_nonnil() {} + void _M_ref_nonnil() {} + static void _S_unref(_Rope_RopeRep*) {} + static void _S_ref(_Rope_RopeRep*) {} + static void _S_free_if_unref(_Rope_RopeRep*) {} # endif +}; + +template +struct _Rope_RopeLeaf : public _Rope_RopeRep<_CharT,_Alloc> { + public: + // Apparently needed by VC++ // The data fields of leaves are allocated with some // extra space, to accomodate future growth and for basic // character types, to hold a trailing eos character. - enum { alloc_granularity = 8 }; - static size_t rounded_up_size(size_t n) { - size_t size_with_eos; - - if (__is_basic_char_type((charT *)0)) { - size_with_eos = n + 1; - } else { - size_with_eos = n; - } + enum { _S_alloc_granularity = 8 }; + static size_t _S_rounded_up_size(size_t __n) { + size_t __size_with_eos; + + if (_S_is_basic_char_type((_CharT*)0)) { + __size_with_eos = __n + 1; + } else { + __size_with_eos = __n; + } # ifdef __GC - return size_with_eos; -# else - // Allow slop for in-place expansion. - return (size_with_eos + alloc_granularity-1) - &~ (alloc_granularity-1); -# endif + return __size_with_eos; +# else + // Allow slop for in-place expansion. + return (__size_with_eos + _S_alloc_granularity-1) + &~ (_S_alloc_granularity-1); +# endif } + __GC_CONST _CharT* _M_data; /* Not necessarily 0 terminated. */ + /* The allocated size is */ + /* _S_rounded_up_size(size), except */ + /* in the GC case, in which it */ + /* doesn't matter. */ + typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; + _Rope_RopeLeaf(__GC_CONST _CharT* __d, size_t __size, allocator_type __a) + : _M_data(__d) + , _Rope_RopeRep<_CharT,_Alloc>(_S_leaf, 0, true, __size, __a) + { + __stl_assert(__size > 0); + if (_S_is_basic_char_type((_CharT *)0)) { + // already eos terminated. + _M_c_string = __d; + } + } + // The constructor assumes that d has been allocated with + // the proper allocator and the properly padded size. + // In contrast, the destructor deallocates the data: +# ifndef __GC + ~_Rope_RopeLeaf() { + if (_M_data != _M_c_string) { + _M_free_c_string(); + } + __STL_FREE_STRING(_M_data, _M_size, get_allocator()); + } +# endif }; -template -struct __rope_RopeLeaf : public __rope_RopeBase { - public: // Apparently needed by VC++ - __GC_CONST charT* data; /* Not necessarily 0 terminated. */ - /* The allocated size is */ - /* rounded_up_size(size), except */ - /* in the GC case, in which it */ - /* doesn't matter. */ -}; - -template -struct __rope_RopeConcatenation : public __rope_RopeBase { +template +struct _Rope_RopeConcatenation : public _Rope_RopeRep<_CharT,_Alloc> { public: - __rope_RopeBase* left; - __rope_RopeBase* right; + _Rope_RopeRep<_CharT,_Alloc>* _M_left; + _Rope_RopeRep<_CharT,_Alloc>* _M_right; + typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; + _Rope_RopeConcatenation(_Rope_RopeRep<_CharT,_Alloc>* __l, + _Rope_RopeRep<_CharT,_Alloc>* __r, + allocator_type __a) + : _M_left(__l), _M_right(__r) + , _Rope_RopeRep<_CharT,_Alloc>( + _S_concat, max(__l->_M_depth, __r->_M_depth) + 1, false, + __l->_M_size + __r->_M_size, __a) + {} +# ifndef __GC + ~_Rope_RopeConcatenation() { + _M_free_c_string(); + _M_left->_M_unref_nonnil(); + _M_right->_M_unref_nonnil(); + } +# endif }; -template -struct __rope_RopeFunction : public __rope_RopeBase { +template +struct _Rope_RopeFunction : public _Rope_RopeRep<_CharT,_Alloc> { public: - char_producer* fn; + char_producer<_CharT>* _M_fn; # ifndef __GC - bool delete_when_done; // Char_producer is owned by the - // rope and should be explicitly - // deleted when the rope becomes - // inaccessible. + bool _M_delete_when_done; // Char_producer is owned by the + // rope and should be explicitly + // deleted when the rope becomes + // inaccessible. # else // In the GC case, we either register the rope for // finalization, or not. Thus the field is unnecessary; // the information is stored in the collector data structures. + // We do need a finalization procedure to be invoked by the + // collector. + static void _S_fn_finalization_proc(void * __tree, void *) { + delete ((_Rope_RopeFunction *)__tree) -> _M_fn; + } # endif + typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; + _Rope_RopeFunction(char_producer<_CharT>* __f, size_t __size, + bool __d, allocator_type __a) + : _M_fn(__f) +# ifndef __GC + , _M_delete_when_done(__d) +# endif + , _Rope_RopeRep<_CharT,_Alloc>(_S_function, 0, true, __size, __a) { + __stl_assert(__size > 0); +# ifdef __GC + if (__d) { + GC_REGISTER_FINALIZER( + this, _Rope_RopeFunction::_S_fn_finalization_proc, 0, 0, 0); + } +# endif + } +# ifndef __GC + ~_Rope_RopeFunction() { + _M_free_c_string(); + if (_M_delete_when_done) { + delete _M_fn; + } + } +# endif }; // Substring results are usually represented using just // concatenation nodes. But in the case of very long flat ropes // or ropes with a functional representation that isn't practical. -// In that case, we represent the result as a special case of +// In that case, we represent the __result as a special case of // RopeFunction, whose char_producer points back to the rope itself. // In all cases except repeated substring operations and -// deallocation, we treat the result as a RopeFunction. -template -struct __rope_RopeSubstring: public __rope_RopeFunction, - public char_producer { +// deallocation, we treat the __result as a RopeFunction. +template +struct _Rope_RopeSubstring : public _Rope_RopeFunction<_CharT,_Alloc>, + public char_producer<_CharT> { public: - __rope_RopeBase * base; // not 0 - size_t start; - virtual ~__rope_RopeSubstring() {} - virtual void operator()(size_t start_pos, size_t req_len, - charT *buffer) { - switch(base -> tag) { - case function: - case substringfn: - { - char_producer *fn = - ((__rope_RopeFunction *)base) -> fn; - __stl_assert(start_pos + req_len <= size); - __stl_assert(start + size <= base -> size); - (*fn)(start_pos + start, req_len, buffer); - } - break; - case leaf: - { - __GC_CONST charT * s = - ((__rope_RopeLeaf *)base) -> data; - uninitialized_copy_n(s + start_pos + start, req_len, - buffer); - } - break; - default: - __stl_assert(false); - } + // XXX this whole class should be rewritten. + _Rope_RopeRep<_CharT,_Alloc>* _M_base; // not 0 + size_t _M_start; + virtual void operator()(size_t __start_pos, size_t __req_len, + _CharT* __buffer) { + switch(_M_base->_M_tag) { + case _S_function: + case _S_substringfn: + { + char_producer<_CharT>* __fn = + ((_Rope_RopeFunction<_CharT,_Alloc>*)_M_base)->_M_fn; + __stl_assert(__start_pos + __req_len <= _M_size); + __stl_assert(_M_start + _M_size <= _M_base->_M_size); + (*__fn)(__start_pos + _M_start, __req_len, __buffer); + } + break; + case _S_leaf: + { + __GC_CONST _CharT* __s = + ((_Rope_RopeLeaf<_CharT,_Alloc>*)_M_base)->_M_data; + uninitialized_copy_n(__s + __start_pos + _M_start, __req_len, + __buffer); + } + break; + default: + __stl_assert(false); + } } - __rope_RopeSubstring(__rope_RopeBase * b, size_t s, size_t l) : - base(b), start(s) { + typedef _Rope_rep_base<_CharT,_Alloc>::allocator_type allocator_type; + _Rope_RopeSubstring(_Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, + size_t __l, allocator_type __a) + : _M_base(__b) + , _M_start(__s) + , _Rope_RopeFunction<_CharT,_Alloc>(this, __l, false, __a) + { + __stl_assert(__l > 0); + __stl_assert(__s + __l <= __b->_M_size); # ifndef __GC - refcount = 1; - init_refcount_lock(); - base -> ref_nonnil(); + _M_base->_M_ref_nonnil(); # endif - size = l; - tag = substringfn; - depth = 0; - c_string = 0; - fn = this; + _M_tag = _S_substringfn; } + virtual ~_Rope_RopeSubstring() + { +# ifndef __GC + _M_base->_M_unref_nonnil(); + // _M_free_c_string(); -- done by parent class +# endif + } }; -// Self-destructing pointers to RopeBase. +// Self-destructing pointers to Rope_rep. // These are not conventional smart pointers. Their // only purpose in life is to ensure that unref is called // on the pointer either at normal exit or if an exception @@ -504,21 +724,22 @@ struct __rope_RopeSubstring: public __rope_RopeFunction, // the number of potentially expensive reference count // updates.) #ifndef __GC - template - struct __rope_self_destruct_ptr { - __rope_RopeBase * ptr; - ~__rope_self_destruct_ptr() { __rope_RopeBase::unref(ptr); } + template + struct _Rope_self_destruct_ptr { + _Rope_RopeRep<_CharT,_Alloc>* _M_ptr; + ~_Rope_self_destruct_ptr() + { _Rope_RopeRep<_CharT,_Alloc>::_S_unref(_M_ptr); } # ifdef __STL_USE_EXCEPTIONS - __rope_self_destruct_ptr() : ptr(0) {}; + _Rope_self_destruct_ptr() : _M_ptr(0) {}; # else - __rope_self_destruct_ptr() {}; + _Rope_self_destruct_ptr() {}; # endif - __rope_self_destruct_ptr(__rope_RopeBase * p) : ptr(p) {} - __rope_RopeBase & operator*() { return *ptr; } - __rope_RopeBase * operator->() { return ptr; } - operator __rope_RopeBase *() { return ptr; } - __rope_self_destruct_ptr & operator= (__rope_RopeBase * x) - { ptr = x; return *this; } + _Rope_self_destruct_ptr(_Rope_RopeRep<_CharT,_Alloc>* __p) : _M_ptr(__p) {} + _Rope_RopeRep<_CharT,_Alloc>& operator*() { return *_M_ptr; } + _Rope_RopeRep<_CharT,_Alloc>* operator->() { return _M_ptr; } + operator _Rope_RopeRep<_CharT,_Alloc>*() { return _M_ptr; } + _Rope_self_destruct_ptr& operator= (_Rope_RopeRep<_CharT,_Alloc>* __x) + { _M_ptr = __x; return *this; } }; #endif @@ -527,73 +748,100 @@ struct __rope_RopeSubstring: public __rope_RopeFunction, // return an actual reference since assignment requires extra // work. And we would get into the same problems as with the // CD2 version of basic_string. -template -class __rope_charT_ref_proxy { - friend class rope; - friend class __rope_iterator; - friend class __rope_charT_ptr_proxy; +template +class _Rope_char_ref_proxy { + friend class rope<_CharT,_Alloc>; + friend class _Rope_iterator<_CharT,_Alloc>; + friend class _Rope_char_ptr_proxy<_CharT,_Alloc>; # ifdef __GC - typedef __rope_RopeBase * self_destruct_ptr; + typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr; # else - typedef __rope_self_destruct_ptr self_destruct_ptr; + typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr; # endif - typedef __rope_RopeBase RopeBase; - typedef rope my_rope; - size_t pos; - charT current; - bool current_valid; - my_rope * root; // The whole rope. + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + typedef rope<_CharT,_Alloc> _My_rope; + size_t _M_pos; + _CharT _M_current; + bool _M_current_valid; + _My_rope* _M_root; // The whole rope. public: - __rope_charT_ref_proxy(my_rope * r, size_t p) : - pos(p), root(r), current_valid(false) {} - __rope_charT_ref_proxy(my_rope * r, size_t p, - charT c) : - pos(p), root(r), current(c), current_valid(true) {} - operator charT () const; - __rope_charT_ref_proxy& operator= (charT c); - __rope_charT_ptr_proxy operator& () const; - __rope_charT_ref_proxy& operator= (const __rope_charT_ref_proxy& c) { - return operator=((charT)c); + _Rope_char_ref_proxy(_My_rope* __r, size_t __p) : + _M_pos(__p), _M_root(__r), _M_current_valid(false) {} + _Rope_char_ref_proxy(const _Rope_char_ref_proxy& __x) : + _M_pos(__x._M_pos), _M_root(__x._M_root), _M_current_valid(false) {} + // Don't preserve cache if the reference can outlive the + // expression. We claim that's not possible without calling + // a copy constructor or generating reference to a proxy + // reference. We declare the latter to have undefined semantics. + _Rope_char_ref_proxy(_My_rope* __r, size_t __p, + _CharT __c) : + _M_pos(__p), _M_root(__r), _M_current(__c), _M_current_valid(true) {} + inline operator _CharT () const; + _Rope_char_ref_proxy& operator= (_CharT __c); + _Rope_char_ptr_proxy<_CharT,_Alloc> operator& () const; + _Rope_char_ref_proxy& operator= (const _Rope_char_ref_proxy& __c) { + return operator=((_CharT)__c); } }; -template -class __rope_charT_ptr_proxy { - friend class __rope_charT_ref_proxy; - size_t pos; - charT current; - bool current_valid; - rope * root; // The whole rope. +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + template + inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, + _Rope_char_ref_proxy <_CharT, __Alloc > __b) { + _CharT __tmp = __a; + __a = __b; + __b = __tmp; + } +#else +// There is no really acceptable way to handle this. The default +// definition of swap doesn't work for proxy references. +// It can't really be made to work, even with ugly hacks, since +// the only unusual operation it uses is the copy constructor, which +// is needed for other purposes. We provide a macro for +// full specializations, and instantiate the most common case. +# define _ROPE_SWAP_SPECIALIZATION(_CharT, __Alloc) \ + inline void swap(_Rope_char_ref_proxy <_CharT, __Alloc > __a, \ + _Rope_char_ref_proxy <_CharT, __Alloc > __b) { \ + _CharT __tmp = __a; \ + __a = __b; \ + __b = __tmp; \ + } + +_ROPE_SWAP_SPECIALIZATION(char,__STL_DEFAULT_ALLOCATOR(char)) + +#endif /* !__STL_FUNCTION_TMPL_PARTIAL_ORDER */ + +template +class _Rope_char_ptr_proxy { + // XXX this class should be rewritten. + friend class _Rope_char_ref_proxy<_CharT,_Alloc>; + size_t _M_pos; + rope<_CharT,_Alloc>* _M_root; // The whole rope. public: - __rope_charT_ptr_proxy(const __rope_charT_ref_proxy & x) : - pos(x.pos), root(x.root), current_valid(x.current_valid), - current(x.current) {} - __rope_charT_ptr_proxy(const __rope_charT_ptr_proxy & x) : - pos(x.pos), root(x.root), current_valid(x.current_valid), - current(x.current) {} - __rope_charT_ptr_proxy() {} - __rope_charT_ptr_proxy(charT * x) : root(0), pos(0) { - __stl_assert(0 == x); + _Rope_char_ptr_proxy(const _Rope_char_ref_proxy<_CharT,_Alloc>& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) {} + _Rope_char_ptr_proxy(const _Rope_char_ptr_proxy& __x) + : _M_pos(__x._M_pos), _M_root(__x._M_root) {} + _Rope_char_ptr_proxy() {} + _Rope_char_ptr_proxy(_CharT* __x) : _M_root(0), _M_pos(0) { + __stl_assert(0 == __x); } - __rope_charT_ptr_proxy& operator= (const __rope_charT_ptr_proxy& x) { - pos = x.pos; - current = x.current; - current_valid = x.current_valid; - root = x.root; - return *this; + _Rope_char_ptr_proxy& + operator= (const _Rope_char_ptr_proxy& __x) { + _M_pos = __x._M_pos; + _M_root = __x._M_root; + return *this; } - friend bool operator== __STL_NULL_TMPL_ARGS - (const __rope_charT_ptr_proxy & x, - const __rope_charT_ptr_proxy & y); - __rope_charT_ref_proxy operator *() const { - if (current_valid) { - return __rope_charT_ref_proxy(root, pos, current); - } else { - return __rope_charT_ref_proxy(root, pos); - } + friend bool operator== __STL_NULL_TMPL_ARGS + (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y); + + _Rope_char_ref_proxy<_CharT,_Alloc> operator*() const { + return _Rope_char_ref_proxy<_CharT,_Alloc>(_M_root, _M_pos); } }; + // Rope iterators: // Unlike in the C version, we cache only part of the stack // for rope iterators, since they must be efficiently copyable. @@ -607,294 +855,297 @@ class __rope_charT_ptr_proxy { #pragma set woff 1375 #endif -template -class __rope_iterator_base: - public random_access_iterator { - friend class rope; +template +class _Rope_iterator_base + : public random_access_iterator<_CharT, ptrdiff_t> { + friend class rope<_CharT,_Alloc>; public: - typedef __rope_RopeBase RopeBase; - // Borland doesnt want this to be protected. + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + // Borland doesnt want this to be protected. protected: - enum { path_cache_len = 4 }; // Must be <= 9. - enum { iterator_buf_len = 15 }; - size_t current_pos; - RopeBase * root; // The whole rope. - size_t leaf_pos; // Starting position for current leaf - __GC_CONST charT * buf_start; - // Buffer possibly - // containing current char. - __GC_CONST charT * buf_ptr; - // Pointer to current char in buffer. - // != 0 ==> buffer valid. - __GC_CONST charT * buf_end; - // One past last valid char in buffer. + enum { _S_path_cache_len = 4 }; // Must be <= 9. + enum { _S_iterator_buf_len = 15 }; + size_t _M_current_pos; + _RopeRep* _M_root; // The whole rope. + size_t _M_leaf_pos; // Starting position for current leaf + __GC_CONST _CharT* _M_buf_start; + // Buffer possibly + // containing current char. + __GC_CONST _CharT* _M_buf_ptr; + // Pointer to current char in buffer. + // != 0 ==> buffer valid. + __GC_CONST _CharT* _M_buf_end; + // One past __last valid char in buffer. // What follows is the path cache. We go out of our // way to make this compact. // Path_end contains the bottom section of the path from // the root to the current leaf. - const RopeBase * path_end[path_cache_len]; - int leaf_index; // Last valid pos in path_end; - // path_end[0] ... path_end[leaf_index-1] - // point to concatenation nodes. - unsigned char path_directions; - // (path_directions >> i) & 1 is 1 - // iff we got from path_end[leaf_index - i - 1] - // to path_end[leaf_index - i] by going to the - // right. Assumes path_cache_len <= 9. - charT tmp_buf[iterator_buf_len]; - // Short buffer for surrounding chars. - // This is useful primarily for - // RopeFunctions. We put the buffer - // here to avoid locking in the - // multithreaded case. + const _RopeRep* _M_path_end[_S_path_cache_len]; + int _M_leaf_index; // Last valid __pos in path_end; + // _M_path_end[0] ... _M_path_end[leaf_index-1] + // point to concatenation nodes. + unsigned char _M_path_directions; + // (path_directions >> __i) & 1 is 1 + // iff we got from _M_path_end[leaf_index - __i - 1] + // to _M_path_end[leaf_index - __i] by going to the + // __right. Assumes path_cache_len <= 9. + _CharT _M_tmp_buf[_S_iterator_buf_len]; + // Short buffer for surrounding chars. + // This is useful primarily for + // RopeFunctions. We put the buffer + // here to avoid locking in the + // multithreaded case. // The cached path is generally assumed to be valid // only if the buffer is valid. - static void setbuf(__rope_iterator_base &x); - // Set buffer contents given - // path cache. - static void setcache(__rope_iterator_base &x); - // Set buffer contents and - // path cache. - static void setcache_for_incr(__rope_iterator_base &x); - // As above, but assumes path - // cache is valid for previous posn. - __rope_iterator_base() {} - __rope_iterator_base(RopeBase * root, size_t pos): - root(root), current_pos(pos), buf_ptr(0) {} - __rope_iterator_base(const __rope_iterator_base& x) { - if (0 != x.buf_ptr) { - *this = x; - } else { - current_pos = x.current_pos; - root = x.root; - buf_ptr = 0; - } - } - void incr(size_t n); - void decr(size_t n); + static void _S_setbuf(_Rope_iterator_base& __x); + // Set buffer contents given + // path cache. + static void _S_setcache(_Rope_iterator_base& __x); + // Set buffer contents and + // path cache. + static void _S_setcache_for_incr(_Rope_iterator_base& __x); + // As above, but assumes path + // cache is valid for previous posn. + _Rope_iterator_base() {} + _Rope_iterator_base(_RopeRep* __root, size_t __pos) + : _M_root(__root), _M_current_pos(__pos), _M_buf_ptr(0) {} + void _M_incr(size_t __n); + void _M_decr(size_t __n); public: - size_t index() const { return current_pos; } + size_t index() const { return _M_current_pos; } + _Rope_iterator_base(const _Rope_iterator_base& __x) { + if (0 != __x._M_buf_ptr) { + *this = __x; + } else { + _M_current_pos = __x._M_current_pos; + _M_root = __x._M_root; + _M_buf_ptr = 0; + } + } }; -template class __rope_iterator; +template class _Rope_iterator; -template -class __rope_const_iterator : public __rope_iterator_base { - friend class rope; +template +class _Rope_const_iterator : public _Rope_iterator_base<_CharT,_Alloc> { + friend class rope<_CharT,_Alloc>; protected: - __rope_const_iterator(const RopeBase * root, size_t pos): - __rope_iterator_base( - const_cast(root), pos) - // Only nonconst iterators modify root ref count + _Rope_const_iterator(const _RopeRep* __root, size_t __pos): + _Rope_iterator_base<_CharT,_Alloc>( + const_cast<_RopeRep*>(__root), __pos) + // Only nonconst iterators modify root ref count {} public: - typedef charT reference; // Really a value. Returning a reference - // Would be a mess, since it would have - // to be included in refcount. - typedef const charT* pointer; + typedef _CharT reference; // Really a value. Returning a reference + // Would be a mess, since it would have + // to be included in refcount. + typedef const _CharT* pointer; public: - __rope_const_iterator() {}; - __rope_const_iterator(const __rope_const_iterator & x) : - __rope_iterator_base(x) { } - __rope_const_iterator(const __rope_iterator & x); - __rope_const_iterator(const rope &r, size_t pos) : - __rope_iterator_base(r.tree_ptr, pos) {} - __rope_const_iterator& operator= (const __rope_const_iterator & x) { - if (0 != x.buf_ptr) { - *this = x; - } else { - current_pos = x.current_pos; - root = x.root; - buf_ptr = 0; - } - return(*this); + _Rope_const_iterator() {}; + _Rope_const_iterator(const _Rope_const_iterator& __x) : + _Rope_iterator_base<_CharT,_Alloc>(__x) { } + _Rope_const_iterator(const _Rope_iterator<_CharT,_Alloc>& __x); + _Rope_const_iterator(const rope<_CharT,_Alloc>& __r, size_t __pos) : + _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos) {} + _Rope_const_iterator& operator= (const _Rope_const_iterator& __x) { + if (0 != __x._M_buf_ptr) { + *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x; + } else { + _M_current_pos = __x._M_current_pos; + _M_root = __x._M_root; + _M_buf_ptr = 0; + } + return(*this); } reference operator*() { - if (0 == buf_ptr) setcache(*this); - return *buf_ptr; + if (0 == _M_buf_ptr) _S_setcache(*this); + return *_M_buf_ptr; } - __rope_const_iterator& operator++() { - __GC_CONST charT * next; - if (0 != buf_ptr && (next = buf_ptr + 1) < buf_end) { - buf_ptr = next; - ++current_pos; - } else { - incr(1); - } - return *this; + _Rope_const_iterator& operator++() { + __GC_CONST _CharT* __next; + if (0 != _M_buf_ptr && (__next = _M_buf_ptr + 1) < _M_buf_end) { + _M_buf_ptr = __next; + ++_M_current_pos; + } else { + _M_incr(1); + } + return *this; } - __rope_const_iterator& operator+=(ptrdiff_t n) { - if (n >= 0) { - incr(n); - } else { - decr(-n); - } - return *this; + _Rope_const_iterator& operator+=(ptrdiff_t __n) { + if (__n >= 0) { + _M_incr(__n); + } else { + _M_decr(-__n); + } + return *this; } - __rope_const_iterator& operator--() { - decr(1); - return *this; + _Rope_const_iterator& operator--() { + _M_decr(1); + return *this; } - __rope_const_iterator& operator-=(ptrdiff_t n) { - if (n >= 0) { - decr(n); - } else { - incr(-n); - } - return *this; + _Rope_const_iterator& operator-=(ptrdiff_t __n) { + if (__n >= 0) { + _M_decr(__n); + } else { + _M_incr(-__n); + } + return *this; } - __rope_const_iterator operator++(int) { - size_t old_pos = current_pos; - incr(1); - return __rope_const_iterator(root, old_pos); - // This makes a subsequent dereference expensive. - // Perhaps we should instead copy the iterator - // if it has a valid cache? + _Rope_const_iterator operator++(int) { + size_t __old_pos = _M_current_pos; + _M_incr(1); + return _Rope_const_iterator<_CharT,_Alloc>(_M_root, __old_pos); + // This makes a subsequent dereference expensive. + // Perhaps we should instead copy the iterator + // if it has a valid cache? } - __rope_const_iterator operator--(int) { - size_t old_pos = current_pos; - decr(1); - return __rope_const_iterator(root, old_pos); + _Rope_const_iterator operator--(int) { + size_t __old_pos = _M_current_pos; + _M_decr(1); + return _Rope_const_iterator<_CharT,_Alloc>(_M_root, __old_pos); } - friend __rope_const_iterator operator- __STL_NULL_TMPL_ARGS - (const __rope_const_iterator & x, - ptrdiff_t n); - friend __rope_const_iterator operator+ __STL_NULL_TMPL_ARGS - (const __rope_const_iterator & x, - ptrdiff_t n); - friend __rope_const_iterator operator+ __STL_NULL_TMPL_ARGS - (ptrdiff_t n, - const __rope_const_iterator & x); - reference operator[](size_t n) { - return rope::fetch(root, current_pos + n); + friend _Rope_const_iterator<_CharT,_Alloc> operator- __STL_NULL_TMPL_ARGS + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_const_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_const_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (ptrdiff_t __n, + const _Rope_const_iterator<_CharT,_Alloc>& __x); + reference operator[](size_t __n) { + return rope<_CharT,_Alloc>::_S_fetch(_M_root, _M_current_pos + __n); } friend bool operator== __STL_NULL_TMPL_ARGS - (const __rope_const_iterator & x, - const __rope_const_iterator & y); + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); friend bool operator< __STL_NULL_TMPL_ARGS - (const __rope_const_iterator & x, - const __rope_const_iterator & y); + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); friend ptrdiff_t operator- __STL_NULL_TMPL_ARGS - (const __rope_const_iterator & x, - const __rope_const_iterator & y); + (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y); }; -template -class __rope_iterator : public __rope_iterator_base { - friend class rope; +template +class _Rope_iterator : public _Rope_iterator_base<_CharT,_Alloc> { + friend class rope<_CharT,_Alloc>; protected: - rope * root_rope; - // root is treated as a cached version of this, - // and is used to detect changes to the underlying - // rope. - // Root is included in the reference count. - // This is necessary so that we can detect changes reliably. - // Unfortunately, it requires careful bookkeeping for the - // nonGC case. - __rope_iterator(rope * r, size_t pos): - __rope_iterator_base(r -> tree_ptr, pos), - root_rope(r) { - RopeBase::ref(root); - } - void check(); + rope<_CharT,_Alloc>* _M_root_rope; + // root is treated as a cached version of this, + // and is used to detect changes to the underlying + // rope. + // Root is included in the reference count. + // This is necessary so that we can detect changes reliably. + // Unfortunately, it requires careful bookkeeping for the + // nonGC case. + _Rope_iterator(rope<_CharT,_Alloc>* __r, size_t __pos) + : _Rope_iterator_base<_CharT,_Alloc>(__r->_M_tree_ptr, __pos), + _M_root_rope(__r) + { _RopeRep::_S_ref(_M_root); } + + void _M_check(); public: - typedef __rope_charT_ref_proxy reference; - typedef __rope_charT_ref_proxy* pointer; + typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference; + typedef _Rope_char_ref_proxy<_CharT,_Alloc>* pointer; public: - rope& container() { return *root_rope; } - __rope_iterator() { - root = 0; // Needed for reference counting. + rope<_CharT,_Alloc>& container() { return *_M_root_rope; } + _Rope_iterator() { + _M_root = 0; // Needed for reference counting. }; - __rope_iterator(const __rope_iterator & x) : - __rope_iterator_base(x) { - root_rope = x.root_rope; - RopeBase::ref(root); + _Rope_iterator(const _Rope_iterator& __x) : + _Rope_iterator_base<_CharT,_Alloc>(__x) { + _M_root_rope = __x._M_root_rope; + _RopeRep::_S_ref(_M_root); } - __rope_iterator(rope& r, size_t pos); - ~__rope_iterator() { - RopeBase::unref(root); + _Rope_iterator(rope<_CharT,_Alloc>& __r, size_t __pos); + ~_Rope_iterator() { + _RopeRep::_S_unref(_M_root); } - __rope_iterator& operator= (const __rope_iterator & x) { - RopeBase *old = root; - - RopeBase::ref(x.root); - if (0 != x.buf_ptr) { - *this = x; - } else { - current_pos = x.current_pos; - root = x.root; - root_rope = x.root_rope; - buf_ptr = 0; - } - RopeBase::unref(old); - return(*this); + _Rope_iterator& operator= (const _Rope_iterator& __x) { + _RopeRep* __old = _M_root; + + _RopeRep::_S_ref(__x._M_root); + if (0 != __x._M_buf_ptr) { + _M_root_rope = __x._M_root_rope; + *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x; + } else { + _M_current_pos = __x._M_current_pos; + _M_root = __x._M_root; + _M_root_rope = __x._M_root_rope; + _M_buf_ptr = 0; + } + _RopeRep::_S_unref(__old); + return(*this); } reference operator*() { - check(); - if (0 == buf_ptr) { - return __rope_charT_ref_proxy(root_rope, current_pos); - } else { - return __rope_charT_ref_proxy(root_rope, - current_pos, *buf_ptr); - } + _M_check(); + if (0 == _M_buf_ptr) { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, _M_current_pos); + } else { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, _M_current_pos, *_M_buf_ptr); + } } - __rope_iterator& operator++() { - incr(1); - return *this; + _Rope_iterator& operator++() { + _M_incr(1); + return *this; } - __rope_iterator& operator+=(difference_type n) { - if (n >= 0) { - incr(n); - } else { - decr(-n); - } - return *this; + _Rope_iterator& operator+=(difference_type __n) { + if (__n >= 0) { + _M_incr(__n); + } else { + _M_decr(-__n); + } + return *this; } - __rope_iterator& operator--() { - decr(1); - return *this; + _Rope_iterator& operator--() { + _M_decr(1); + return *this; } - __rope_iterator& operator-=(difference_type n) { - if (n >= 0) { - decr(n); - } else { - incr(-n); - } - return *this; + _Rope_iterator& operator-=(difference_type __n) { + if (__n >= 0) { + _M_decr(__n); + } else { + _M_incr(-__n); + } + return *this; } - __rope_iterator operator++(int) { - size_t old_pos = current_pos; - incr(1); - return __rope_iterator(root_rope, old_pos); + _Rope_iterator operator++(int) { + size_t __old_pos = _M_current_pos; + _M_incr(1); + return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); } - __rope_iterator operator--(int) { - size_t old_pos = current_pos; - decr(1); - return __rope_iterator(root_rope, old_pos); + _Rope_iterator operator--(int) { + size_t __old_pos = _M_current_pos; + _M_decr(1); + return _Rope_iterator<_CharT,_Alloc>(_M_root_rope, __old_pos); } - reference operator[](ptrdiff_t n) { - return __rope_charT_ref_proxy(root_rope, current_pos + n); + reference operator[](ptrdiff_t __n) { + return _Rope_char_ref_proxy<_CharT,_Alloc>( + _M_root_rope, _M_current_pos + __n); } friend bool operator== __STL_NULL_TMPL_ARGS - (const __rope_iterator & x, - const __rope_iterator & y); + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); friend bool operator< __STL_NULL_TMPL_ARGS - (const __rope_iterator & x, - const __rope_iterator & y); + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); friend ptrdiff_t operator- __STL_NULL_TMPL_ARGS - (const __rope_iterator & x, - const __rope_iterator & y); - friend __rope_iterator operator- __STL_NULL_TMPL_ARGS - (const __rope_iterator & x, - ptrdiff_t n); - friend __rope_iterator operator+ __STL_NULL_TMPL_ARGS - (const __rope_iterator & x, - ptrdiff_t n); - friend __rope_iterator operator+ __STL_NULL_TMPL_ARGS - (ptrdiff_t n, - const __rope_iterator & x); + (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y); + friend _Rope_iterator<_CharT,_Alloc> operator- __STL_NULL_TMPL_ARGS + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n); + friend _Rope_iterator<_CharT,_Alloc> operator+ __STL_NULL_TMPL_ARGS + (ptrdiff_t __n, + const _Rope_iterator<_CharT,_Alloc>& __x); }; @@ -902,1199 +1153,1376 @@ class __rope_iterator : public __rope_iterator_base { #pragma reset woff 1375 #endif -template -class rope { +// The rope base class encapsulates +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template +class _Rope_alloc_base { +public: + typedef _Rope_RopeRep<_CharT,_Allocator> _RopeRep; + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + _Rope_alloc_base(_RopeRep *__t, const allocator_type& __a) + : _M_tree_ptr(__t), _M_data_allocator(__a) {} + _Rope_alloc_base(const allocator_type& __a) + : _M_data_allocator(__a) {} + +protected: + // The only data members of a rope: + allocator_type _M_data_allocator; + _RopeRep* _M_tree_ptr; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + _Tp* __name##_allocate(size_t __n) const \ + { return __name##Allocator(_M_data_allocator).allocate(__n); } \ + void __name##_deallocate(_Tp *__p, size_t __n) const \ + { __name##Allocator(_M_data_allocator).deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator) +# undef __ROPE_DEFINE_ALLOC +}; + +// Specialization for allocators that have the property that we don't +// actually have to store an allocator object. +template +class _Rope_alloc_base<_CharT,_Allocator,true> { +public: + typedef _Rope_RopeRep<_CharT,_Allocator> _RopeRep; + typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + _Rope_alloc_base(_RopeRep *__t, const allocator_type&) + : _M_tree_ptr(__t) {} + _Rope_alloc_base(const allocator_type&) {} + +protected: + // The only data member of a rope: + _RopeRep *_M_tree_ptr; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::_Alloc_type __name##Alloc; \ + typedef typename \ + _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + static void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Allocator) +# undef __ROPE_DEFINE_ALLOC +}; + +template +struct _Rope_base + : public _Rope_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> +{ + typedef _Rope_alloc_base<_CharT,_Alloc, + _Alloc_traits<_CharT,_Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + _Rope_base(_RopeRep* __t, const allocator_type& __a) : _Base(__t, __a) {} + _Rope_base(const allocator_type& __a) : _Base(__a) {} +}; + +#else /* !__STL_USE_STD_ALLOCATORS */ + +template +class _Rope_base { +public: + typedef _Rope_RopeRep<_CharT, _Alloc> _RopeRep; + typedef _Alloc allocator_type; + static allocator_type get_allocator() { return allocator_type(); } + _Rope_base(_RopeRep * __t, const allocator_type&) : _M_tree_ptr(__t) {} + _Rope_base(const allocator_type&) {} + +protected: + // The only data member of a rope: + _RopeRep* _M_tree_ptr; + +# define __ROPE_DEFINE_ALLOC(_Tp, __name) \ + typedef simple_alloc<_Tp, _Alloc> __name##Alloc; \ + static _Tp* __name##_allocate(size_t __n) \ + { return __name##Alloc::allocate(__n); } \ + static void __name##_deallocate(_Tp *__p, size_t __n) \ + { __name##Alloc::deallocate(__p, __n); } + __ROPE_DEFINE_ALLOCS(_Alloc) +# undef __ROPE_DEFINE_ALLOC +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + + +template +class rope : public _Rope_base<_CharT,_Alloc> { public: - typedef charT value_type; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - typedef charT const_reference; - typedef const charT* const_pointer; - typedef __rope_iterator iterator; - typedef __rope_const_iterator const_iterator; - typedef __rope_charT_ref_proxy reference; - typedef __rope_charT_ptr_proxy pointer; - - friend class __rope_iterator; - friend class __rope_const_iterator; - friend struct __rope_RopeBase; - friend class __rope_iterator_base; - friend class __rope_charT_ptr_proxy; - friend class __rope_charT_ref_proxy; - friend struct __rope_RopeSubstring; + typedef _CharT value_type; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef _CharT const_reference; + typedef const _CharT* const_pointer; + typedef _Rope_iterator<_CharT,_Alloc> iterator; + typedef _Rope_const_iterator<_CharT,_Alloc> const_iterator; + typedef _Rope_char_ref_proxy<_CharT,_Alloc> reference; + typedef _Rope_char_ptr_proxy<_CharT,_Alloc> pointer; + + friend class _Rope_iterator<_CharT,_Alloc>; + friend class _Rope_const_iterator<_CharT,_Alloc>; + friend struct _Rope_RopeRep<_CharT,_Alloc>; + friend class _Rope_iterator_base<_CharT,_Alloc>; + friend class _Rope_char_ptr_proxy<_CharT,_Alloc>; + friend class _Rope_char_ref_proxy<_CharT,_Alloc>; + friend struct _Rope_RopeSubstring<_CharT,_Alloc>; protected: - typedef __GC_CONST charT * cstrptr; + typedef _Rope_base<_CharT,_Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; +# ifdef __STL_USE_NAMESPACES + using _Base::_M_tree_ptr; +# endif + typedef __GC_CONST _CharT* _Cstrptr; # ifdef __STL_SGI_THREADS - static cstrptr atomic_swap(cstrptr *p, cstrptr q) { + static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) { # if __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) - return (cstrptr) test_and_set((unsigned long *)p, - (unsigned long)q); -# else - return (cstrptr) __test_and_set((unsigned long *)p, - (unsigned long)q); -# endif + return (_Cstrptr) test_and_set((unsigned long*)__p, + (unsigned long)__q); +# else + return (_Cstrptr) __test_and_set((unsigned long*)__p, + (unsigned long)__q); +# endif } # elif defined(__STL_WIN32THREADS) - static cstrptr atomic_swap(cstrptr *p, cstrptr q) { - return (cstrptr) InterlockedExchange((LPLONG)p, (LONG)q); - } -# elif defined(__STL_PTHREADS) - // This should be portable, but performance is expected - // to be quite awful. This really needs platform specific - // code. - static pthread_mutex_t swap_lock; - static cstrptr atomic_swap(cstrptr *p, cstrptr q) { - pthread_mutex_lock(&swap_lock); - cstrptr result = *p; - *p = q; - pthread_mutex_unlock(&swap_lock); - return result; + static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) { + return (_Cstrptr) InterlockedExchange( + (LPLONG)__p, (LONG)__q); + } +# elif defined(__STL_PTHREADS) + // This should be portable, but performance is expected + // to be quite awful. This really needs platform specific + // code. + static pthread_mutex_t _S_swap_lock; + static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) { + pthread_mutex_lock(&_S_swap_lock); + _Cstrptr __result = *__p; + *__p = __q; + pthread_mutex_unlock(&_S_swap_lock); + return __result; + } +# else + static _Cstrptr _S_atomic_swap(_Cstrptr* __p, _Cstrptr __q) { + _Cstrptr __result = *__p; + *__p = __q; + return __result; } -# else - static cstrptr atomic_swap(cstrptr *p, cstrptr q) { - cstrptr result = *p; - *p = q; - return result; - } # endif - static charT empty_c_str[1]; - - typedef simple_alloc DataAlloc; - typedef simple_alloc<__rope_RopeConcatenation, Alloc> CAlloc; - typedef simple_alloc<__rope_RopeLeaf, Alloc> LAlloc; - typedef simple_alloc<__rope_RopeFunction, Alloc> FAlloc; - typedef simple_alloc<__rope_RopeSubstring, Alloc> SAlloc; - static bool is0(charT c) { return c == __eos((charT *)0); } - enum { copy_max = 23 }; - // For strings shorter than copy_max, we copy to - // concatenate. - - typedef __rope_RopeBase RopeBase; - typedef __rope_RopeConcatenation RopeConcatenation; - typedef __rope_RopeLeaf RopeLeaf; - typedef __rope_RopeFunction RopeFunction; - typedef __rope_RopeSubstring RopeSubstring; - - // The only data member of a rope: - RopeBase *tree_ptr; - - // Retrieve a character at the indicated position. - static charT fetch(RopeBase * r, size_type pos); - -# ifndef __GC - // Obtain a pointer to the character at the indicated position. - // The pointer can be used to change the character. - // If such a pointer cannot be produced, as is frequently the - // case, 0 is returned instead. - // (Returns nonzero only if all nodes in the path have a refcount - // of 1.) - static charT * fetch_ptr(RopeBase * r, size_type pos); -# endif - - static bool apply_to_pieces( - // should be template parameter - __rope_char_consumer& c, - const RopeBase * r, - size_t begin, size_t end); - // begin and end are assumed to be in range. - -# ifndef __GC - static void unref(RopeBase* t) - { - RopeBase::unref(t); - } - static void ref(RopeBase* t) - { - RopeBase::ref(t); - } + static _CharT _S_empty_c_str[1]; + + static bool _S_is0(_CharT __c) { return __c == _S_eos((_CharT*)0); } + enum { _S_copy_max = 23 }; + // For strings shorter than _S_copy_max, we copy to + // concatenate. + + typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep; + typedef _Rope_RopeConcatenation<_CharT,_Alloc> _RopeConcatenation; + typedef _Rope_RopeLeaf<_CharT,_Alloc> _RopeLeaf; + typedef _Rope_RopeFunction<_CharT,_Alloc> _RopeFunction; + typedef _Rope_RopeSubstring<_CharT,_Alloc> _RopeSubstring; + + // Retrieve a character at the indicated position. + static _CharT _S_fetch(_RopeRep* __r, size_type __pos); + +# ifndef __GC + // Obtain a pointer to the character at the indicated position. + // The pointer can be used to change the character. + // If such a pointer cannot be produced, as is frequently the + // case, 0 is returned instead. + // (Returns nonzero only if all nodes in the path have a refcount + // of 1.) + static _CharT* _S_fetch_ptr(_RopeRep* __r, size_type __pos); +# endif + + static bool _S_apply_to_pieces( + // should be template parameter + _Rope_char_consumer<_CharT>& __c, + const _RopeRep* __r, + size_t __begin, size_t __end); + // begin and end are assumed to be in range. + +# ifndef __GC + static void _S_unref(_RopeRep* __t) + { + _RopeRep::_S_unref(__t); + } + static void _S_ref(_RopeRep* __t) + { + _RopeRep::_S_ref(__t); + } # else /* __GC */ - static void unref(RopeBase* t) {} - static void ref(RopeBase* t) {} + static void _S_unref(_RopeRep*) {} + static void _S_ref(_RopeRep*) {} # endif # ifdef __GC - typedef __rope_RopeBase * self_destruct_ptr; -# else - typedef __rope_self_destruct_ptr self_destruct_ptr; -# endif - - // Result is counted in refcount. - static RopeBase * substring(RopeBase * base, - size_t start, size_t endp1); - - static RopeBase * concat_char_iter(RopeBase * r, - const charT *iter, size_t slen); - // Concatenate rope and char ptr, copying s. - // Should really take an arbitrary iterator. - // Result is counted in refcount. - static RopeBase * destr_concat_char_iter(RopeBase * r, - const charT *iter, size_t slen) - // As above, but one reference to r is about to be - // destroyed. Thus the pieces may be recycled if all - // relevent reference counts are 1. -# ifdef __GC - // We can't really do anything since refcounts are unavailable. - { return concat_char_iter(r, iter, slen); } -# else - ; -# endif - - static RopeBase * concat(RopeBase *left, RopeBase *right); - // General concatenation on RopeBase. Result - // has refcount of 1. Adjusts argument refcounts. + typedef _Rope_RopeRep<_CharT,_Alloc>* _Self_destruct_ptr; +# else + typedef _Rope_self_destruct_ptr<_CharT,_Alloc> _Self_destruct_ptr; +# endif + + // _Result is counted in refcount. + static _RopeRep* _S_substring(_RopeRep* __base, + size_t __start, size_t __endp1); + + static _RopeRep* _S_concat_char_iter(_RopeRep* __r, + const _CharT* __iter, size_t __slen); + // Concatenate rope and char ptr, copying __s. + // Should really take an arbitrary iterator. + // Result is counted in refcount. + static _RopeRep* _S_destr_concat_char_iter(_RopeRep* __r, + const _CharT* __iter, size_t __slen) + // As above, but one reference to __r is about to be + // destroyed. Thus the pieces may be recycled if all + // relevent reference counts are 1. +# ifdef __GC + // We can't really do anything since refcounts are unavailable. + { return _S_concat_char_iter(__r, __iter, __slen); } +# else + ; +# endif + + static _RopeRep* _S_concat(_RopeRep* __left, _RopeRep* __right); + // General concatenation on _RopeRep. _Result + // has refcount of 1. Adjusts argument refcounts. public: - void apply_to_pieces( size_t begin, size_t end, - __rope_char_consumer& c) const { - apply_to_pieces(c, tree_ptr, begin, end); - } + void apply_to_pieces( size_t __begin, size_t __end, + _Rope_char_consumer<_CharT>& __c) const { + _S_apply_to_pieces(__c, _M_tree_ptr, __begin, __end); + } protected: - static size_t rounded_up_size(size_t n) { - return RopeBase::rounded_up_size(n); - } - - static size_t allocated_capacity(size_t n) { - if (__is_basic_char_type((charT *)0)) { - return rounded_up_size(n) - 1; - } else { - return rounded_up_size(n); - } - } - - // s should really be an arbitrary input iterator. - // Adds a trailing NULL for basic char types. - static charT * alloc_copy(const charT *s, size_t size) - { - charT * result = DataAlloc::allocate(rounded_up_size(size)); - - uninitialized_copy_n(s, size, result); - __cond_store_eos(result[size]); - return(result); - } - - // Basic constructors for rope tree nodes. - // These return tree nodes with a 0 reference count. - static RopeLeaf * RopeLeaf_from_char_ptr(__GC_CONST charT *s, - size_t size); - // Takes ownership of its argument. - // Result has refcount 1. - // In the nonGC, basic_char_type case it assumes that s - // is eos-terminated. - // In the nonGC case, it was allocated from Alloc with - // rounded_up_size(size). - - static RopeLeaf * RopeLeaf_from_unowned_char_ptr(const charT *s, - size_t size) { - charT * buf = alloc_copy(s, size); + static size_t _S_rounded_up_size(size_t __n) { + return _RopeLeaf::_S_rounded_up_size(__n); + } + + static size_t _S_allocated_capacity(size_t __n) { + if (_S_is_basic_char_type((_CharT*)0)) { + return _S_rounded_up_size(__n) - 1; + } else { + return _S_rounded_up_size(__n); + } + } + + // Allocate and construct a RopeLeaf using the supplied allocator + // Takes ownership of s instead of copying. + static _RopeLeaf* _S_new_RopeLeaf(__GC_CONST _CharT *__s, + size_t __size, allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeLeaf* __space = _LAllocator(__a).allocate(1); +# else + _RopeLeaf* __space = _L_allocate(1); +# endif + return new(__space) _RopeLeaf(__s, __size, __a); + } + + static _RopeConcatenation* _S_new_RopeConcatenation( + _RopeRep* __left, _RopeRep* __right, + allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeConcatenation* __space = _CAllocator(__a).allocate(1); +# else + _RopeConcatenation* __space = _C_allocate(1); +# endif + return new(__space) _RopeConcatenation(__left, __right, __a); + } + + static _RopeFunction* _S_new_RopeFunction(char_producer<_CharT>* __f, + size_t __size, bool __d, allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeFunction* __space = _FAllocator(__a).allocate(1); +# else + _RopeFunction* __space = _F_allocate(1); +# endif + return new(__space) _RopeFunction(__f, __size, __d, __a); + } + + static _RopeSubstring* _S_new_RopeSubstring( + _Rope_RopeRep<_CharT,_Alloc>* __b, size_t __s, + size_t __l, allocator_type __a) + { +# ifdef __STL_USE_STD_ALLOCATORS + _RopeSubstring* __space = _SAllocator(__a).allocate(1); +# else + _RopeSubstring* __space = _S_allocate(1); +# endif + return new(__space) _RopeSubstring(__b, __s, __l, __a); + } + +# ifdef __STL_USE_STD_ALLOCATORS + static + _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr(const _CharT *__s, + size_t __size, allocator_type __a) +# define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \ + _S_RopeLeaf_from_unowned_char_ptr(__s, __size, __a) +# else + static + _RopeLeaf* _S_RopeLeaf_from_unowned_char_ptr2(const _CharT* __s, + size_t __size) +# define __STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __size, __a) \ + _S_RopeLeaf_from_unowned_char_ptr2(__s, __size) +# endif + { + if (0 == __size) return 0; +# ifdef __STL_USE_STD_ALLOCATORS + _CharT* __buf = __a.allocate(_S_rounded_up_size(__size)); +# else + _CharT* __buf = _Data_allocate(_S_rounded_up_size(__size)); + allocator_type __a = allocator_type(); +# endif + + uninitialized_copy_n(__s, __size, __buf); + _S_cond_store_eos(__buf[__size]); __STL_TRY { - return RopeLeaf_from_char_ptr(buf, size); + return _S_new_RopeLeaf(__buf, __size, __a); } - __STL_UNWIND(RopeBase::free_string(buf, size)) - } - - - // Concatenation of nonempty strings. - // Always builds a concatenation node. - // Rebalances if the result is too deep. - // Result has refcount 1. - // Does not increment left and right ref counts even though - // they are referenced. - static RopeBase * tree_concat(RopeBase * left, RopeBase * right); - - // Result has refcount 1. - // If delete_fn is true, then fn is deleted when the rope - // becomes inaccessible. - static RopeFunction * RopeFunction_from_fn - (char_producer *fn, size_t size, - bool delete_fn); - - // Concatenation helper functions - static RopeLeaf * leaf_concat_char_iter - (RopeLeaf * r, const charT * iter, size_t slen); - // Concatenate by copying leaf. - // should take an arbitrary iterator - // result has refcount 1. -# ifndef __GC - static RopeLeaf * destr_leaf_concat_char_iter - (RopeLeaf * r, const charT * iter, size_t slen); - // A version that potentially clobbers r if r -> refcount == 1. + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__buf, __size, __a)) + } + + + // Concatenation of nonempty strings. + // Always builds a concatenation node. + // Rebalances if the result is too deep. + // Result has refcount 1. + // Does not increment left and right ref counts even though + // they are referenced. + static _RopeRep* + _S_tree_concat(_RopeRep* __left, _RopeRep* __right); + + // Concatenation helper functions + static _RopeLeaf* + _S_leaf_concat_char_iter(_RopeLeaf* __r, + const _CharT* __iter, size_t __slen); + // Concatenate by copying leaf. + // should take an arbitrary iterator + // result has refcount 1. +# ifndef __GC + static _RopeLeaf* _S_destr_leaf_concat_char_iter + (_RopeLeaf* __r, const _CharT* __iter, size_t __slen); + // A version that potentially clobbers __r if __r->_M_refcount == 1. # endif - // A helper function for exponentiating strings. - // This uses a nonstandard refcount convention. - // The result has refcount 0. - struct concat_fn; - friend struct rope::concat_fn; - - struct concat_fn - : public binary_function, rope, - rope > { - rope operator() (const rope& x, const rope& y) { - return x + y; - } - }; - - friend rope identity_element(concat_fn) { return rope(); } - - static size_t char_ptr_len(const charT * s); - // slightly generalized strlen - - rope(RopeBase *t) : tree_ptr(t) { } - - - // Copy r to the CharT buffer. - // Returns buffer + r -> size. - // Assumes that buffer is uninitialized. - static charT * flatten(RopeBase * r, charT * buffer); - - // Again, with explicit starting position and length. - // Assumes that buffer is uninitialized. - static charT * flatten(RopeBase * r, - size_t start, size_t len, - charT * buffer); - - static const unsigned long min_len[RopeBase::max_rope_depth + 1]; - - static bool is_balanced(RopeBase *r) - { return (r -> size >= min_len[r -> depth]); } - - static bool is_almost_balanced(RopeBase *r) - { return (r -> depth == 0 || - r -> size >= min_len[r -> depth - 1]); } - - static bool is_roughly_balanced(RopeBase *r) - { return (r -> depth <= 1 || - r -> size >= min_len[r -> depth - 2]); } - - // Assumes the result is not empty. - static RopeBase * concat_and_set_balanced(RopeBase *left, - RopeBase *right) - { - RopeBase * result = concat(left, right); - if (is_balanced(result)) result -> is_balanced = true; - return result; - } - - // The basic rebalancing operation. Logically copies the - // rope. The result has refcount of 1. The client will - // usually decrement the reference count of r. - // The result isd within height 2 of balanced by the above - // definition. - static RopeBase * balance(RopeBase * r); - - // Add all unbalanced subtrees to the forest of balanceed trees. - // Used only by balance. - static void add_to_forest(RopeBase *r, RopeBase **forest); - - // Add r to forest, assuming r is already balanced. - static void add_leaf_to_forest(RopeBase *r, RopeBase **forest); - - // Print to stdout, exposing structure - static void dump(RopeBase * r, int indent = 0); - - // Return -1, 0, or 1 if x < y, x == y, or x > y resp. - static int compare(const RopeBase *x, const RopeBase *y); + // A helper function for exponentiating strings. + // This uses a nonstandard refcount convention. + // The result has refcount 0. + struct _Concat_fn + : public binary_function, + rope<_CharT,_Alloc>, + rope<_CharT,_Alloc> > { + rope operator() (const rope& __x, const rope& __y) { + return __x + __y; + } + }; + + // Needed by the call to "power" used to build ropes + // consisting of n copies of a character. + friend rope identity_element(_Concat_fn) + { return rope<_CharT,_Alloc>(); } + + static size_t _S_char_ptr_len(const _CharT* __s); + // slightly generalized strlen + + rope(_RopeRep* __t, const allocator_type& __a = allocator_type()) + : _Base(__t,__a) { } + + + // Copy __r to the _CharT buffer. + // Returns __buffer + __r->_M_size. + // Assumes that buffer is uninitialized. + static _CharT* _S_flatten(_RopeRep* __r, _CharT* __buffer); + + // Again, with explicit starting position and length. + // Assumes that buffer is uninitialized. + static _CharT* _S_flatten(_RopeRep* __r, + size_t __start, size_t __len, + _CharT* __buffer); + + static const unsigned long + _S_min_len[_RopeRep::_S_max_rope_depth + 1]; + + static bool _S_is_balanced(_RopeRep* __r) + { return (__r->_M_size >= _S_min_len[__r->_M_depth]); } + + static bool _S_is_almost_balanced(_RopeRep* __r) + { return (__r->_M_depth == 0 || + __r->_M_size >= _S_min_len[__r->_M_depth - 1]); } + + static bool _S_is_roughly_balanced(_RopeRep* __r) + { return (__r->_M_depth <= 1 || + __r->_M_size >= _S_min_len[__r->_M_depth - 2]); } + + // Assumes the result is not empty. + static _RopeRep* _S_concat_and_set_balanced(_RopeRep* __left, + _RopeRep* __right) + { + _RopeRep* __result = _S_concat(__left, __right); + if (_S_is_balanced(__result)) __result->_M_is_balanced = true; + return __result; + } + + // The basic rebalancing operation. Logically copies the + // rope. The result has refcount of 1. The client will + // usually decrement the reference count of __r. + // The result is within height 2 of balanced by the above + // definition. + static _RopeRep* _S_balance(_RopeRep* __r); + + // Add all unbalanced subtrees to the forest of balanceed trees. + // Used only by balance. + static void _S_add_to_forest(_RopeRep*__r, _RopeRep** __forest); + + // Add __r to forest, assuming __r is already balanced. + static void _S_add_leaf_to_forest(_RopeRep* __r, _RopeRep** __forest); + + // Print to stdout, exposing structure + static void _S_dump(_RopeRep* __r, int __indent = 0); + + // Return -1, 0, or 1 if __x < __y, __x == __y, or __x > __y resp. + static int _S_compare(const _RopeRep* __x, const _RopeRep* __y); public: - bool empty() const { return 0 == tree_ptr; } - - // Comparison member function. This is public only for those - // clients that need a ternary comparison. Others - // should use the comparison operators below. - int compare(const rope &y) const { - return compare(tree_ptr, y.tree_ptr); - } - - rope(const charT *s) - { - size_t len = char_ptr_len(s); - - if (0 == len) { - tree_ptr = 0; - } else { - tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len); -# ifndef __GC - __stl_assert(1 == tree_ptr -> refcount); -# endif - } - } - - rope(const charT *s, size_t len) - { - if (0 == len) { - tree_ptr = 0; - } else { - tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len); - } - } - - rope(const charT *s, charT *e) - { - size_t len = e - s; - - if (0 == len) { - tree_ptr = 0; - } else { - tree_ptr = RopeLeaf_from_unowned_char_ptr(s, len); - } - } - - rope(const const_iterator& s, const const_iterator& e) - { - tree_ptr = substring(s.root, s.current_pos, e.current_pos); - } - - rope(const iterator& s, const iterator& e) - { - tree_ptr = substring(s.root, s.current_pos, e.current_pos); - } - - rope(charT c) - { - charT * buf = DataAlloc::allocate(rounded_up_size(1)); - - construct(buf, c); - __STL_TRY { - tree_ptr = RopeLeaf_from_char_ptr(buf, 1); + bool empty() const { return 0 == _M_tree_ptr; } + + // Comparison member function. This is public only for those + // clients that need a ternary comparison. Others + // should use the comparison operators below. + int compare(const rope& __y) const { + return _S_compare(_M_tree_ptr, __y._M_tree_ptr); + } + + rope(const _CharT* __s, const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, _S_char_ptr_len(__s), + __a),__a) + { } + + rope(const _CharT* __s, size_t __len, + const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __len, __a), __a) + { } + + // Should perhaps be templatized with respect to the iterator type + // and use Sequence_buffer. (It should perhaps use sequence_buffer + // even now.) + rope(const _CharT *__s, const _CharT *__e, + const allocator_type& __a = allocator_type()) + : _Base(__STL_ROPE_FROM_UNOWNED_CHAR_PTR(__s, __e - __s, __a), __a) + { } + + rope(const const_iterator& __s, const const_iterator& __e, + const allocator_type& __a = allocator_type()) + : _Base(_S_substring(__s._M_root, __s._M_current_pos, + __e._M_current_pos), __a) + { } + + rope(const iterator& __s, const iterator& __e, + const allocator_type& __a = allocator_type()) + : _Base(_S_substring(__s._M_root, __s._M_current_pos, + __e._M_current_pos), __a) + { } + + rope(_CharT __c, const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _CharT* __buf = _Data_allocate(_S_rounded_up_size(1)); + + construct(__buf, __c); + __STL_TRY { + _M_tree_ptr = _S_new_RopeLeaf(__buf, 1, __a); } - __STL_UNWIND(RopeBase::free_string(buf, 1)) - } - - rope(size_t n, charT c); - - // Should really be templatized with respect to the iterator type - // and use sequence_buffer. (It should perhaps use sequence_buffer - // even now.) - rope(const charT *i, const charT *j) - { - if (i == j) { - tree_ptr = 0; - } else { - size_t len = j - i; - tree_ptr = RopeLeaf_from_unowned_char_ptr(i, len); - } - } - - rope() - { - tree_ptr = 0; - } - - // Construct a rope from a function that can compute its members - rope(char_producer *fn, size_t len, bool delete_fn) - { - tree_ptr = RopeFunction_from_fn(fn, len, delete_fn); - } - - rope(const rope &x) - { - tree_ptr = x.tree_ptr; - ref(tree_ptr); - } - - ~rope() - { - unref(tree_ptr); - } - - rope& operator=(const rope& x) - { - RopeBase *old = tree_ptr; - tree_ptr = x.tree_ptr; - ref(tree_ptr); - unref(old); - return(*this); - } - - void push_back(charT x) - { - RopeBase *old = tree_ptr; - tree_ptr = concat_char_iter(tree_ptr, &x, 1); - unref(old); - } - - void pop_back() - { - RopeBase *old = tree_ptr; - tree_ptr = substring(tree_ptr, 0, tree_ptr -> size - 1); - unref(old); - } - - charT back() const - { - return fetch(tree_ptr, tree_ptr -> size - 1); - } - - void push_front(charT x) - { - RopeBase *old = tree_ptr; - RopeBase *left; - - left = RopeLeaf_from_unowned_char_ptr(&x, 1); - __STL_TRY { - tree_ptr = concat(left, tree_ptr); - unref(old); - unref(left); + __STL_UNWIND(_RopeRep::__STL_FREE_STRING(__buf, 1, __a)) + } + + rope(size_t __n, _CharT __c, + const allocator_type& __a = allocator_type()); + + rope(const allocator_type& __a = allocator_type()) + : _Base(0, __a) {} + + // Construct a rope from a function that can compute its members + rope(char_producer<_CharT> *__fn, size_t __len, bool __delete_fn, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + _M_tree_ptr = (0 == __len) ? + 0 : _S_new_RopeFunction(__fn, __len, __delete_fn, __a); + } + + rope(const rope& __x, const allocator_type& __a = allocator_type()) + : _Base(__x._M_tree_ptr, __a) + { + _S_ref(_M_tree_ptr); + } + + ~rope() + { + _S_unref(_M_tree_ptr); + } + + rope& operator=(const rope& __x) + { + _RopeRep* __old = _M_tree_ptr; +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __x.get_allocator()); +# endif + _M_tree_ptr = __x._M_tree_ptr; + _S_ref(_M_tree_ptr); + _S_unref(__old); + return(*this); + } + + void push_back(_CharT __x) + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = _S_concat_char_iter(_M_tree_ptr, &__x, 1); + _S_unref(__old); + } + + void pop_back() + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = + _S_substring(_M_tree_ptr, 0, _M_tree_ptr->_M_size - 1); + _S_unref(__old); + } + + _CharT back() const + { + return _S_fetch(_M_tree_ptr, _M_tree_ptr->_M_size - 1); + } + + void push_front(_CharT __x) + { + _RopeRep* __old = _M_tree_ptr; + _RopeRep* __left = + __STL_ROPE_FROM_UNOWNED_CHAR_PTR(&__x, 1, get_allocator()); + __STL_TRY { + _M_tree_ptr = _S_concat(__left, _M_tree_ptr); + _S_unref(__old); + _S_unref(__left); } - __STL_UNWIND(unref(left)) - } - - void pop_front() - { - RopeBase *old = tree_ptr; - tree_ptr = substring(tree_ptr, 1, tree_ptr -> size); - unref(old); - } - - charT front() const - { - return fetch(tree_ptr, 0); - } - - void balance() - { - RopeBase *old = tree_ptr; - tree_ptr = balance(tree_ptr); - unref(old); - } - - void copy(charT * buffer) const { - destroy(buffer, buffer + size()); - flatten(tree_ptr, buffer); - } - - // This is the copy function from the standard, but - // with the arguments reordered to make it consistent with the - // rest of the interface. - // Note that this guaranteed not to compile if the draft standard - // order is assumed. - size_type copy(size_type pos, size_type n, charT *buffer) const { - size_t sz = size(); - size_t len = (pos + n > sz? sz - pos : n); - - destroy(buffer, buffer + len); - flatten(tree_ptr, pos, len, buffer); - return len; - } - - // Print to stdout, exposing structure. May be useful for - // performance debugging. - void dump() { - dump(tree_ptr); - } - - // Convert to 0 terminated string in new allocated memory. - // Embedded 0s in the input do not terminate the copy. - const charT * c_str() const; - - // As above, but lso use the flattened representation as the - // the new rope representation. - const charT * replace_with_c_str(); - - // Reclaim memory for the c_str generated flattened string. - // Intentionally undocumented, since it's hard to say when this - // is safe for multiple threads. - void delete_c_str () { - if (0 == tree_ptr) return; - if (RopeBase::leaf == tree_ptr -> tag - && ((RopeLeaf *)tree_ptr) -> data == tree_ptr -> c_string) { - // Representation shared - return; - } -# ifndef __GC - tree_ptr -> free_c_string(); -# endif - tree_ptr -> c_string = 0; - } - - charT operator[] (size_type pos) const { - return fetch(tree_ptr, pos); - } - - charT at(size_type pos) const { - // if (pos >= size()) throw out_of_range; - return (*this)[pos]; - } - - const_iterator begin() const { - return(const_iterator(tree_ptr, 0)); - } - - // An easy way to get a const iterator from a non-const container. - const_iterator const_begin() const { - return(const_iterator(tree_ptr, 0)); - } - - const_iterator end() const { - return(const_iterator(tree_ptr, size())); - } - - const_iterator const_end() const { - return(const_iterator(tree_ptr, size())); - } - - size_type size() const { - return(0 == tree_ptr? 0 : tree_ptr -> size); - } - - size_type length() const { - return size(); - } - - size_type max_size() const { - return min_len[RopeBase::max_rope_depth-1] - 1; - // Guarantees that the result can be sufficirntly - // balanced. Longer ropes will probably still work, - // but it's harder to make guarantees. - } + __STL_UNWIND(_S_unref(__left)) + } + + void pop_front() + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = _S_substring(_M_tree_ptr, 1, _M_tree_ptr->_M_size); + _S_unref(__old); + } + + _CharT front() const + { + return _S_fetch(_M_tree_ptr, 0); + } + + void balance() + { + _RopeRep* __old = _M_tree_ptr; + _M_tree_ptr = _S_balance(_M_tree_ptr); + _S_unref(__old); + } + + void copy(_CharT* __buffer) const { + destroy(__buffer, __buffer + size()); + _S_flatten(_M_tree_ptr, __buffer); + } + + // This is the copy function from the standard, but + // with the arguments reordered to make it consistent with the + // rest of the interface. + // Note that this guaranteed not to compile if the draft standard + // order is assumed. + size_type copy(size_type __pos, size_type __n, _CharT* __buffer) const + { + size_t __size = size(); + size_t __len = (__pos + __n > __size? __size - __pos : __n); + + destroy(__buffer, __buffer + __len); + _S_flatten(_M_tree_ptr, __pos, __len, __buffer); + return __len; + } + + // Print to stdout, exposing structure. May be useful for + // performance debugging. + void dump() { + _S_dump(_M_tree_ptr); + } + + // Convert to 0 terminated string in new allocated memory. + // Embedded 0s in the input do not terminate the copy. + const _CharT* c_str() const; + + // As above, but lso use the flattened representation as the + // the new rope representation. + const _CharT* replace_with_c_str(); + + // Reclaim memory for the c_str generated flattened string. + // Intentionally undocumented, since it's hard to say when this + // is safe for multiple threads. + void delete_c_str () { + if (0 == _M_tree_ptr) return; + if (_RopeRep::_S_leaf == _M_tree_ptr->_M_tag && + ((_RopeLeaf*)_M_tree_ptr)->_M_data == + _M_tree_ptr->_M_c_string) { + // Representation shared + return; + } +# ifndef __GC + _M_tree_ptr->_M_free_c_string(); +# endif + _M_tree_ptr->_M_c_string = 0; + } + + _CharT operator[] (size_type __pos) const { + return _S_fetch(_M_tree_ptr, __pos); + } + + _CharT at(size_type __pos) const { + // if (__pos >= size()) throw out_of_range; // XXX + return (*this)[__pos]; + } + + const_iterator begin() const { + return(const_iterator(_M_tree_ptr, 0)); + } + + // An easy way to get a const iterator from a non-const container. + const_iterator const_begin() const { + return(const_iterator(_M_tree_ptr, 0)); + } + + const_iterator end() const { + return(const_iterator(_M_tree_ptr, size())); + } + + const_iterator const_end() const { + return(const_iterator(_M_tree_ptr, size())); + } + + size_type size() const { + return(0 == _M_tree_ptr? 0 : _M_tree_ptr->_M_size); + } + + size_type length() const { + return size(); + } + + size_type max_size() const { + return _S_min_len[_RopeRep::_S_max_rope_depth-1] - 1; + // Guarantees that the result can be sufficirntly + // balanced. Longer ropes will probably still work, + // but it's harder to make guarantees. + } # ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; # else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - typedef reverse_iterator const_reverse_iterator; + typedef reverse_iterator const_reverse_iterator; # endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - const_reverse_iterator rbegin() const { - return const_reverse_iterator(end()); - } - - const_reverse_iterator const_rbegin() const { - return const_reverse_iterator(end()); - } - - const_reverse_iterator rend() const { - return const_reverse_iterator(begin()); - } - - const_reverse_iterator const_rend() const { - return const_reverse_iterator(begin()); - } - - friend rope - operator+ __STL_NULL_TMPL_ARGS (const rope &left, - const rope &right); - - friend rope - operator+ __STL_NULL_TMPL_ARGS (const rope &left, - const charT* right); - - friend rope - operator+ __STL_NULL_TMPL_ARGS (const rope &left, - charT right); - - // The symmetric cases are intentionally omitted, since they're presumed - // to be less common, and we don't handle them as well. - - // The following should really be templatized. - // The first argument should be an input iterator or - // forward iterator with value_type charT. - rope& append(const charT* iter, size_t n) { - RopeBase* result = destr_concat_char_iter(tree_ptr, iter, n); - unref(tree_ptr); - tree_ptr = result; - return *this; - } - - rope& append(const charT* c_string) { - size_t len = char_ptr_len(c_string); - append(c_string, len); - return(*this); - } - - rope& append(const charT* s, const charT* e) { - RopeBase* result = - destr_concat_char_iter(tree_ptr, s, e - s); - unref(tree_ptr); - tree_ptr = result; - return *this; - } - - rope& append(const_iterator s, const_iterator e) { - __stl_assert(s.root == e.root); - self_destruct_ptr appendee(substring(s.root, s.current_pos, - e.current_pos)); - RopeBase* result = concat(tree_ptr, (RopeBase *)appendee); - unref(tree_ptr); - tree_ptr = result; - return *this; - } - - rope& append(charT c) { - RopeBase* result = destr_concat_char_iter(tree_ptr, &c, 1); - unref(tree_ptr); - tree_ptr = result; - return *this; - } - - rope& append() { return append(charT()); } - - rope& append(const rope& y) { - RopeBase* result = concat(tree_ptr, y.tree_ptr); - unref(tree_ptr); - tree_ptr = result; - return *this; - } - - rope& append(size_t n, charT c) { - rope last(n, c); - return append(last); - } - - void swap(rope& b) { - RopeBase * tmp = tree_ptr; - tree_ptr = b.tree_ptr; - b.tree_ptr = tmp; - } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + + const_reverse_iterator const_rbegin() const { + return const_reverse_iterator(end()); + } + + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + const_reverse_iterator const_rend() const { + return const_reverse_iterator(begin()); + } + + friend rope<_CharT,_Alloc> + operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right); + + friend rope<_CharT,_Alloc> + operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left, + const _CharT* __right); + + friend rope<_CharT,_Alloc> + operator+ __STL_NULL_TMPL_ARGS (const rope<_CharT,_Alloc>& __left, + _CharT __right); + + // The symmetric cases are intentionally omitted, since they're presumed + // to be less common, and we don't handle them as well. + + // The following should really be templatized. + // The first argument should be an input iterator or + // forward iterator with value_type _CharT. + rope& append(const _CharT* __iter, size_t __n) { + _RopeRep* __result = + _S_destr_concat_char_iter(_M_tree_ptr, __iter, __n); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(const _CharT* __c_string) { + size_t __len = _S_char_ptr_len(__c_string); + append(__c_string, __len); + return(*this); + } + + rope& append(const _CharT* __s, const _CharT* __e) { + _RopeRep* __result = + _S_destr_concat_char_iter(_M_tree_ptr, __s, __e - __s); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(const_iterator __s, const_iterator __e) { + __stl_assert(__s._M_root == __e._M_root); +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __s._M_root->get_allocator()); +# endif + _Self_destruct_ptr __appendee(_S_substring( + __s._M_root, __s._M_current_pos, __e._M_current_pos)); + _RopeRep* __result = + _S_concat(_M_tree_ptr, (_RopeRep*)__appendee); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(_CharT __c) { + _RopeRep* __result = + _S_destr_concat_char_iter(_M_tree_ptr, &__c, 1); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append() { return append(_CharT()); } // XXX why? + + rope& append(const rope& __y) { +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__y.get_allocator() == get_allocator()); +# endif + _RopeRep* __result = _S_concat(_M_tree_ptr, __y._M_tree_ptr); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + return *this; + } + + rope& append(size_t __n, _CharT __c) { + rope<_CharT,_Alloc> __last(__n, __c); + return append(__last); + } + + void swap(rope& __b) { +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __b.get_allocator()); +# endif + _RopeRep* __tmp = _M_tree_ptr; + _M_tree_ptr = __b._M_tree_ptr; + __b._M_tree_ptr = __tmp; + } protected: - // Result is included in refcount. - static RopeBase * replace(RopeBase *old, size_t pos1, - size_t pos2, RopeBase *r) { - if (0 == old) { ref(r); return r; } - self_destruct_ptr left(substring(old, 0, pos1)); - self_destruct_ptr right(substring(old, pos2, old -> size)); - RopeBase * result; - - if (0 == r) { - result = concat(left, right); - } else { - self_destruct_ptr left_result(concat(left, r)); - result = concat(left_result, right); - } - return result; - } + // Result is included in refcount. + static _RopeRep* replace(_RopeRep* __old, size_t __pos1, + size_t __pos2, _RopeRep* __r) { + if (0 == __old) { _S_ref(__r); return __r; } + _Self_destruct_ptr __left( + _S_substring(__old, 0, __pos1)); + _Self_destruct_ptr __right( + _S_substring(__old, __pos2, __old->_M_size)); + _RopeRep* __result; + +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__old->get_allocator() == __r->get_allocator()); +# endif + if (0 == __r) { + __result = _S_concat(__left, __right); + } else { + _Self_destruct_ptr __left_result(_S_concat(__left, __r)); + __result = _S_concat(__left_result, __right); + } + return __result; + } public: - void insert(size_t p, const rope& r) { - RopeBase * result = replace(tree_ptr, p, p, - r.tree_ptr); - unref(tree_ptr); - tree_ptr = result; - } - - void insert(size_t p, size_t n, charT c) { - rope r(n,c); - insert(p, r); - } - - void insert(size_t p, const charT * i, size_t n) { - self_destruct_ptr left(substring(tree_ptr, 0, p)); - self_destruct_ptr right(substring(tree_ptr, p, size())); - self_destruct_ptr left_result(concat_char_iter(left, i, n)); - RopeBase * result = - concat(left_result, right); - unref(tree_ptr); - tree_ptr = result; - } - - void insert(size_t p, const charT * c_string) { - insert(p, c_string, char_ptr_len(c_string)); - } - - void insert(size_t p, charT c) { - insert(p, &c, 1); - } - - void insert(size_t p) { - charT c = charT(); - insert(p, &c, 1); - } - - void insert(size_t p, const charT *i, const charT *j) { - rope r(i, j); - insert(p, r); - } - - void insert(size_t p, const const_iterator& i, - const const_iterator& j) { - rope r(i, j); - insert(p, r); - } - - void insert(size_t p, const iterator& i, - const iterator& j) { - rope r(i, j); - insert(p, r); - } - - // (position, length) versions of replace operations: - - void replace(size_t p, size_t n, const rope& r) { - RopeBase * result = replace(tree_ptr, p, p + n, - r.tree_ptr); - unref(tree_ptr); - tree_ptr = result; - } - - void replace(size_t p, size_t n, const charT *i, size_t i_len) { - rope r(i, i_len); - replace(p, n, r); - } - - void replace(size_t p, size_t n, charT c) { - rope r(c); - replace(p, n, r); - } - - void replace(size_t p, size_t n, const charT *c_string) { - rope r(c_string); - replace(p, n, r); - } - - void replace(size_t p, size_t n, const charT *i, const charT *j) { - rope r(i, j); - replace(p, n, r); - } - - void replace(size_t p, size_t n, - const const_iterator& i, const const_iterator& j) { - rope r(i, j); - replace(p, n, r); - } - - void replace(size_t p, size_t n, - const iterator& i, const iterator& j) { - rope r(i, j); - replace(p, n, r); - } - - // Single character variants: - void replace(size_t p, charT c) { - iterator i(this, p); - *i = c; - } - - void replace(size_t p, const rope& r) { - replace(p, 1, r); - } - - void replace(size_t p, const charT *i, size_t i_len) { - replace(p, 1, i, i_len); - } - - void replace(size_t p, const charT *c_string) { - replace(p, 1, c_string); - } - - void replace(size_t p, const charT *i, const charT *j) { - replace(p, 1, i, j); - } - - void replace(size_t p, const const_iterator& i, - const const_iterator& j) { - replace(p, 1, i, j); - } - - void replace(size_t p, const iterator& i, - const iterator& j) { - replace(p, 1, i, j); - } - - // Erase, (position, size) variant. - void erase(size_t p, size_t n) { - RopeBase * result = replace(tree_ptr, p, p + n, 0); - unref(tree_ptr); - tree_ptr = result; - } - - // Erase, single character - void erase(size_t p) { - erase(p, p + 1); - } - - // Insert, iterator variants. - iterator insert(const iterator& p, const rope& r) - { insert(p.index(), r); return p; } - iterator insert(const iterator& p, size_t n, charT c) - { insert(p.index(), n, c); return p; } - iterator insert(const iterator& p, charT c) - { insert(p.index(), c); return p; } - iterator insert(const iterator& p ) - { insert(p.index()); return p; } - iterator insert(const iterator& p, const charT *c_string) - { insert(p.index(), c_string); return p; } - iterator insert(const iterator& p, const charT *i, size_t n) - { insert(p.index(), i, n); return p; } - iterator insert(const iterator& p, const charT *i, const charT *j) - { insert(p.index(), i, j); return p; } - iterator insert(const iterator& p, - const const_iterator& i, const const_iterator& j) - { insert(p.index(), i, j); return p; } - iterator insert(const iterator& p, - const iterator& i, const iterator& j) - { insert(p.index(), i, j); return p; } - - // Replace, range variants. - void replace(const iterator& p, const iterator& q, - const rope& r) - { replace(p.index(), q.index() - p.index(), r); } - void replace(const iterator& p, const iterator& q, charT c) - { replace(p.index(), q.index() - p.index(), c); } - void replace(const iterator& p, const iterator& q, - const charT * c_string) - { replace(p.index(), q.index() - p.index(), c_string); } - void replace(const iterator& p, const iterator& q, - const charT *i, size_t n) - { replace(p.index(), q.index() - p.index(), i, n); } - void replace(const iterator& p, const iterator& q, - const charT *i, const charT *j) - { replace(p.index(), q.index() - p.index(), i, j); } - void replace(const iterator& p, const iterator& q, - const const_iterator& i, const const_iterator& j) - { replace(p.index(), q.index() - p.index(), i, j); } - void replace(const iterator& p, const iterator& q, - const iterator& i, const iterator& j) - { replace(p.index(), q.index() - p.index(), i, j); } - - // Replace, iterator variants. - void replace(const iterator& p, const rope& r) - { replace(p.index(), r); } - void replace(const iterator& p, charT c) - { replace(p.index(), c); } - void replace(const iterator& p, const charT * c_string) - { replace(p.index(), c_string); } - void replace(const iterator& p, const charT *i, size_t n) - { replace(p.index(), i, n); } - void replace(const iterator& p, const charT *i, const charT *j) - { replace(p.index(), i, j); } - void replace(const iterator& p, const_iterator i, const_iterator j) - { replace(p.index(), i, j); } - void replace(const iterator& p, iterator i, iterator j) - { replace(p.index(), i, j); } - - // Iterator and range variants of erase - iterator erase(const iterator &p, const iterator &q) { - size_t p_index = p.index(); - erase(p_index, q.index() - p_index); - return iterator(this, p_index); - } - iterator erase(const iterator &p) { - size_t p_index = p.index(); - erase(p_index, 1); - return iterator(this, p_index); - } - - rope substr(size_t start, size_t len = 1) const { - return rope( - substring(tree_ptr, start, start + len)); - } - - rope substr(iterator start, iterator end) const { - return rope( - substring(tree_ptr, start.index(), end.index())); - } - - rope substr(iterator start) const { - size_t pos = start.index(); - return rope( - substring(tree_ptr, pos, pos + 1)); - } - - rope substr(const_iterator start, const_iterator end) const { - // This might eventually take advantage of the cache in the - // iterator. - return rope - (substring(tree_ptr, start.index(), end.index())); - } - - rope substr(const_iterator start) { - size_t pos = start.index(); - return rope(substring(tree_ptr, pos, pos + 1)); - } - - size_type find(charT c, size_type pos = 0) const; - size_type find(charT *s, size_type pos = 0) const { - const_iterator result = search(const_begin() + pos, const_end(), - s, s + char_ptr_len(s)); - return result.index(); - } - - iterator mutable_begin() { - return(iterator(this, 0)); - } - - iterator mutable_end() { - return(iterator(this, size())); - } + void insert(size_t __p, const rope& __r) { + _RopeRep* __result = + replace(_M_tree_ptr, __p, __p, __r._M_tree_ptr); +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(get_allocator() == __r.get_allocator()); +# endif + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + void insert(size_t __p, size_t __n, _CharT __c) { + rope<_CharT,_Alloc> __r(__n,__c); + insert(__p, __r); + } + + void insert(size_t __p, const _CharT* __i, size_t __n) { + _Self_destruct_ptr __left(_S_substring(_M_tree_ptr, 0, __p)); + _Self_destruct_ptr __right(_S_substring(_M_tree_ptr, __p, size())); + _Self_destruct_ptr __left_result( + _S_concat_char_iter(__left, __i, __n)); + _RopeRep* __result = _S_concat(__left_result, __right); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + void insert(size_t __p, const _CharT* __c_string) { + insert(__p, __c_string, _S_char_ptr_len(__c_string)); + } + + void insert(size_t __p, _CharT __c) { + insert(__p, &__c, 1); + } + + void insert(size_t __p) { + _CharT __c = _CharT(); + insert(__p, &__c, 1); + } + + void insert(size_t __p, const _CharT* __i, const _CharT* __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + void insert(size_t __p, const const_iterator& __i, + const const_iterator& __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + void insert(size_t __p, const iterator& __i, + const iterator& __j) { + rope __r(__i, __j); + insert(__p, __r); + } + + // (position, length) versions of replace operations: + + void replace(size_t __p, size_t __n, const rope& __r) { + _RopeRep* __result = + replace(_M_tree_ptr, __p, __p + __n, __r._M_tree_ptr); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + void replace(size_t __p, size_t __n, + const _CharT* __i, size_t __i_len) { + rope __r(__i, __i_len); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, _CharT __c) { + rope __r(__c); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, const _CharT* __c_string) { + rope __r(__c_string); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const _CharT* __i, const _CharT* __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const const_iterator& __i, const const_iterator& __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + void replace(size_t __p, size_t __n, + const iterator& __i, const iterator& __j) { + rope __r(__i, __j); + replace(__p, __n, __r); + } + + // Single character variants: + void replace(size_t __p, _CharT __c) { + iterator __i(this, __p); + *__i = __c; + } + + void replace(size_t __p, const rope& __r) { + replace(__p, 1, __r); + } + + void replace(size_t __p, const _CharT* __i, size_t __i_len) { + replace(__p, 1, __i, __i_len); + } + + void replace(size_t __p, const _CharT* __c_string) { + replace(__p, 1, __c_string); + } + + void replace(size_t __p, const _CharT* __i, const _CharT* __j) { + replace(__p, 1, __i, __j); + } + + void replace(size_t __p, const const_iterator& __i, + const const_iterator& __j) { + replace(__p, 1, __i, __j); + } + + void replace(size_t __p, const iterator& __i, + const iterator& __j) { + replace(__p, 1, __i, __j); + } + + // Erase, (position, size) variant. + void erase(size_t __p, size_t __n) { + _RopeRep* __result = replace(_M_tree_ptr, __p, __p + __n, 0); + _S_unref(_M_tree_ptr); + _M_tree_ptr = __result; + } + + // Erase, single character + void erase(size_t __p) { + erase(__p, __p + 1); + } + + // Insert, iterator variants. + iterator insert(const iterator& __p, const rope& __r) + { insert(__p.index(), __r); return __p; } + iterator insert(const iterator& __p, size_t __n, _CharT __c) + { insert(__p.index(), __n, __c); return __p; } + iterator insert(const iterator& __p, _CharT __c) + { insert(__p.index(), __c); return __p; } + iterator insert(const iterator& __p ) + { insert(__p.index()); return __p; } + iterator insert(const iterator& __p, const _CharT* c_string) + { insert(__p.index(), c_string); return __p; } + iterator insert(const iterator& __p, const _CharT* __i, size_t __n) + { insert(__p.index(), __i, __n); return __p; } + iterator insert(const iterator& __p, const _CharT* __i, + const _CharT* __j) + { insert(__p.index(), __i, __j); return __p; } + iterator insert(const iterator& __p, + const const_iterator& __i, const const_iterator& __j) + { insert(__p.index(), __i, __j); return __p; } + iterator insert(const iterator& __p, + const iterator& __i, const iterator& __j) + { insert(__p.index(), __i, __j); return __p; } + + // Replace, range variants. + void replace(const iterator& __p, const iterator& __q, + const rope& __r) + { replace(__p.index(), __q.index() - __p.index(), __r); } + void replace(const iterator& __p, const iterator& __q, _CharT __c) + { replace(__p.index(), __q.index() - __p.index(), __c); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __c_string) + { replace(__p.index(), __q.index() - __p.index(), __c_string); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __i, size_t __n) + { replace(__p.index(), __q.index() - __p.index(), __i, __n); } + void replace(const iterator& __p, const iterator& __q, + const _CharT* __i, const _CharT* __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + void replace(const iterator& __p, const iterator& __q, + const const_iterator& __i, const const_iterator& __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + void replace(const iterator& __p, const iterator& __q, + const iterator& __i, const iterator& __j) + { replace(__p.index(), __q.index() - __p.index(), __i, __j); } + + // Replace, iterator variants. + void replace(const iterator& __p, const rope& __r) + { replace(__p.index(), __r); } + void replace(const iterator& __p, _CharT __c) + { replace(__p.index(), __c); } + void replace(const iterator& __p, const _CharT* __c_string) + { replace(__p.index(), __c_string); } + void replace(const iterator& __p, const _CharT* __i, size_t __n) + { replace(__p.index(), __i, __n); } + void replace(const iterator& __p, const _CharT* __i, const _CharT* __j) + { replace(__p.index(), __i, __j); } + void replace(const iterator& __p, const_iterator __i, + const_iterator __j) + { replace(__p.index(), __i, __j); } + void replace(const iterator& __p, iterator __i, iterator __j) + { replace(__p.index(), __i, __j); } + + // Iterator and range variants of erase + iterator erase(const iterator& __p, const iterator& __q) { + size_t __p_index = __p.index(); + erase(__p_index, __q.index() - __p_index); + return iterator(this, __p_index); + } + iterator erase(const iterator& __p) { + size_t __p_index = __p.index(); + erase(__p_index, 1); + return iterator(this, __p_index); + } + + rope substr(size_t __start, size_t __len = 1) const { + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __start, __start + __len)); + } + + rope substr(iterator __start, iterator __end) const { + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __start.index(), __end.index())); + } + + rope substr(iterator __start) const { + size_t __pos = __start.index(); + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __pos, __pos + 1)); + } + + rope substr(const_iterator __start, const_iterator __end) const { + // This might eventually take advantage of the cache in the + // iterator. + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __start.index(), __end.index())); + } + + rope<_CharT,_Alloc> substr(const_iterator __start) { + size_t __pos = __start.index(); + return rope<_CharT,_Alloc>( + _S_substring(_M_tree_ptr, __pos, __pos + 1)); + } + + static const size_type npos; + + size_type find(_CharT __c, size_type __pos = 0) const; + size_type find(_CharT* __s, size_type __pos = 0) const { + size_type __result_pos; + const_iterator __result = search(const_begin() + __pos, const_end(), + __s, __s + _S_char_ptr_len(__s)); + __result_pos = __result.index(); +# ifndef __STL_OLD_ROPE_SEMANTICS + if (__result_pos == size()) __result_pos = npos; +# endif + return __result_pos; + } + + iterator mutable_begin() { + return(iterator(this, 0)); + } + + iterator mutable_end() { + return(iterator(this, size())); + } # ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator reverse_iterator; # else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - typedef reverse_iterator reverse_iterator; + typedef reverse_iterator reverse_iterator; # endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - reverse_iterator mutable_rbegin() { - return reverse_iterator(mutable_end()); - } + reverse_iterator mutable_rbegin() { + return reverse_iterator(mutable_end()); + } - reverse_iterator mutable_rend() { - return reverse_iterator(mutable_begin()); - } + reverse_iterator mutable_rend() { + return reverse_iterator(mutable_begin()); + } - reference mutable_reference_at(size_type pos) { - return reference(this, pos); - } + reference mutable_reference_at(size_type __pos) { + return reference(this, __pos); + } -# ifdef __STD_STUFF - reference operator[] (size_type pos) { - return charT_ref_proxy(this, pos); - } +# ifdef __STD_STUFF + reference operator[] (size_type __pos) { + return _char_ref_proxy(this, __pos); + } - reference at(size_type pos) { - // if (pos >= size()) throw out_of_range; - return (*this)[pos]; - } + reference at(size_type __pos) { + // if (__pos >= size()) throw out_of_range; // XXX + return (*this)[__pos]; + } - void resize(size_type n, charT c) {} - void resize(size_type n) {} - void reserve(size_type res_arg = 0) {} - size_type capacity() const { - return max_size(); - } + void resize(size_type __n, _CharT __c) {} + void resize(size_type __n) {} + void reserve(size_type __res_arg = 0) {} + size_type capacity() const { + return max_size(); + } - // Stuff below this line is dangerous because it's error prone. - // I would really like to get rid of it. - // copy function with funny arg ordering. - size_type copy(charT *buffer, size_type n, size_type pos = 0) - const { - return copy(pos, n, buffer); - } + // Stuff below this line is dangerous because it's error prone. + // I would really like to get rid of it. + // copy function with funny arg ordering. + size_type copy(_CharT* __buffer, size_type __n, + size_type __pos = 0) const { + return copy(__pos, __n, __buffer); + } - iterator end() { return mutable_end(); } + iterator end() { return mutable_end(); } - iterator begin() { return mutable_begin(); } + iterator begin() { return mutable_begin(); } - reverse_iterator rend() { return mutable_rend(); } + reverse_iterator rend() { return mutable_rend(); } - reverse_iterator rbegin() { return mutable_rbegin(); } + reverse_iterator rbegin() { return mutable_rbegin(); } -# else +# else - const_iterator end() { return const_end(); } + const_iterator end() { return const_end(); } - const_iterator begin() { return const_begin(); } + const_iterator begin() { return const_begin(); } - const_reverse_iterator rend() { return const_rend(); } + const_reverse_iterator rend() { return const_rend(); } - const_reverse_iterator rbegin() { return const_rbegin(); } + const_reverse_iterator rbegin() { return const_rbegin(); } -# endif - +# endif + }; -template -inline bool operator== (const __rope_const_iterator & x, - const __rope_const_iterator & y) { - return (x.current_pos == y.current_pos && x.root == y.root); +template +const rope<_CharT, _Alloc>::size_type rope<_CharT, _Alloc>::npos = + (size_type)(-1); + +template +inline bool operator== (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos == __y._M_current_pos && + __x._M_root == __y._M_root); } -template -inline bool operator< (const __rope_const_iterator & x, - const __rope_const_iterator & y) { - return (x.current_pos < y.current_pos); +template +inline bool operator< (const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos < __y._M_current_pos); } -template -inline ptrdiff_t operator-(const __rope_const_iterator & x, - const __rope_const_iterator & y) { - return x.current_pos - y.current_pos; +template +inline ptrdiff_t operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, + const _Rope_const_iterator<_CharT,_Alloc>& __y) { + return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; } -template -inline __rope_const_iterator -operator-(const __rope_const_iterator & x, - ptrdiff_t n) { - return __rope_const_iterator(x.root, x.current_pos - n); +template +inline _Rope_const_iterator<_CharT,_Alloc> +operator-(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos - __n); } -template -inline __rope_const_iterator -operator+(const __rope_const_iterator & x, - ptrdiff_t n) { - return __rope_const_iterator(x.root, x.current_pos + n); +template +inline _Rope_const_iterator<_CharT,_Alloc> +operator+(const _Rope_const_iterator<_CharT,_Alloc>& __x, ptrdiff_t __n) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos + __n); } -template -inline __rope_const_iterator -operator+(ptrdiff_t n, - const __rope_const_iterator & x) { - return __rope_const_iterator(x.root, x.current_pos + n); +template +inline _Rope_const_iterator<_CharT,_Alloc> +operator+(ptrdiff_t __n, const _Rope_const_iterator<_CharT,_Alloc>& __x) { + return _Rope_const_iterator<_CharT,_Alloc>( + __x._M_root, __x._M_current_pos + __n); } -template -inline bool operator== (const __rope_iterator & x, - const __rope_iterator & y) { - return (x.current_pos == y.current_pos && x.root_rope == y.root_rope); +template +inline bool operator== (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos == __y._M_current_pos && + __x._M_root_rope == __y._M_root_rope); } -template -inline bool operator< (const __rope_iterator & x, - const __rope_iterator & y) { - return (x.current_pos < y.current_pos); +template +inline bool operator< (const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (__x._M_current_pos < __y._M_current_pos); } -template -inline ptrdiff_t operator-(const __rope_iterator & x, - const __rope_iterator & y) { - return x.current_pos - y.current_pos; +template +inline ptrdiff_t operator-(const _Rope_iterator<_CharT,_Alloc>& __x, + const _Rope_iterator<_CharT,_Alloc>& __y) { + return (ptrdiff_t)__x._M_current_pos - (ptrdiff_t)__y._M_current_pos; } -template -inline __rope_iterator -operator-(const __rope_iterator & x, - ptrdiff_t n) { - return __rope_iterator(x.root_rope, x.current_pos - n); +template +inline _Rope_iterator<_CharT,_Alloc> +operator-(const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos - __n); } -template -inline __rope_iterator -operator+(const __rope_iterator & x, - ptrdiff_t n) { - return __rope_iterator(x.root_rope, x.current_pos + n); +template +inline _Rope_iterator<_CharT,_Alloc> +operator+(const _Rope_iterator<_CharT,_Alloc>& __x, + ptrdiff_t __n) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos + __n); } -template -inline __rope_iterator -operator+(ptrdiff_t n, - const __rope_iterator & x) { - return __rope_iterator(x.root_rope, x.current_pos + n); +template +inline _Rope_iterator<_CharT,_Alloc> +operator+(ptrdiff_t __n, const _Rope_iterator<_CharT,_Alloc>& __x) { + return _Rope_iterator<_CharT,_Alloc>( + __x._M_root_rope, __x._M_current_pos + __n); } -template +template inline -rope -operator+ (const rope &left, - const rope &right) +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { - return rope - (rope::concat(left.tree_ptr, right.tree_ptr)); - // Inlining this should make it possible to keep left and - // right in registers. +# ifdef __STL_USE_STD_ALLOCATORS + __stl_assert(__left.get_allocator() == __right.get_allocator()); +# endif + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat(__left._M_tree_ptr, __right._M_tree_ptr)); + // Inlining this should make it possible to keep __left and + // __right in registers. } -template +template inline -rope& -operator+= (rope &left, - const rope &right) +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { - left.append(right); - return left; + __left.append(__right); + return __left; } -template +template inline -rope -operator+ (const rope &left, - const charT* right) { - size_t rlen = rope::char_ptr_len(right); - return rope - (rope::concat_char_iter(left.tree_ptr, right, rlen)); +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, + const _CharT* __right) { + size_t __rlen = rope<_CharT,_Alloc>::_S_char_ptr_len(__right); + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat_char_iter( + __left._M_tree_ptr, __right, __rlen)); } -template +template inline -rope& -operator+= (rope &left, - const charT* right) { - left.append(right); - return left; +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, + const _CharT* __right) { + __left.append(__right); + return __left; } -template +template inline -rope -operator+ (const rope &left, charT right) { - return rope - (rope::concat_char_iter(left.tree_ptr, &right, 1)); +rope<_CharT,_Alloc> +operator+ (const rope<_CharT,_Alloc>& __left, _CharT __right) { + return rope<_CharT,_Alloc>( + rope<_CharT,_Alloc>::_S_concat_char_iter( + __left._M_tree_ptr, &__right, 1)); } -template +template inline -rope& -operator+= (rope &left, charT right) { - left.append(right); - return left; +rope<_CharT,_Alloc>& +operator+= (rope<_CharT,_Alloc>& __left, _CharT __right) { + __left.append(__right); + return __left; } -template +template bool -operator< (const rope &left, const rope &right) { - return left.compare(right) < 0; +operator< (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { + return __left.compare(__right) < 0; } - -template + +template bool -operator== (const rope &left, const rope &right) { - return left.compare(right) == 0; +operator== (const rope<_CharT,_Alloc>& __left, + const rope<_CharT,_Alloc>& __right) { + return __left.compare(__right) == 0; } -template -inline bool operator== (const __rope_charT_ptr_proxy & x, - const __rope_charT_ptr_proxy & y) { - return (x.pos == y.pos && x.root == y.root); +template +inline bool operator== (const _Rope_char_ptr_proxy<_CharT,_Alloc>& __x, + const _Rope_char_ptr_proxy<_CharT,_Alloc>& __y) { + return (__x._M_pos == __y._M_pos && __x._M_root == __y._M_root); } -template -ostream& operator<< (ostream& o, const rope& r); - -typedef rope crope; -typedef rope wrope; +template +ostream& operator<< (ostream& __o, const rope<_CharT,_Alloc>& __r); + +typedef rope crope; +typedef rope wrope; -inline crope::reference __mutable_reference_at(crope& c, size_t i) +inline crope::reference __mutable_reference_at(crope& __c, size_t __i) { - return c.mutable_reference_at(i); + return __c.mutable_reference_at(__i); } -inline wrope::reference __mutable_reference_at(wrope& c, size_t i) +inline wrope::reference __mutable_reference_at(wrope& __c, size_t __i) { - return c.mutable_reference_at(i); + return __c.mutable_reference_at(__i); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template -inline void swap(rope& x, rope& y) { - x.swap(y); +template +inline void swap(rope<_CharT,_Alloc>& __x, rope<_CharT,_Alloc>& __y) { + __x.swap(__y); } #else -inline void swap(crope x, crope y) { x.swap(y); } -inline void swap(wrope x, wrope y) { x.swap(y); } +inline void swap(crope __x, crope __y) { __x.swap(__y); } +inline void swap(wrope __x, wrope __y) { __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ // Hash functions should probably be revisited later: __STL_TEMPLATE_NULL struct hash { - size_t operator()(const crope& str) const + size_t operator()(const crope& __str) const { - size_t sz = str.size(); + size_t __size = __str.size(); - if (0 == sz) return 0; - return 13*str[0] + 5*str[sz - 1] + sz; + if (0 == __size) return 0; + return 13*__str[0] + 5*__str[__size - 1] + __size; } }; __STL_TEMPLATE_NULL struct hash { - size_t operator()(const wrope& str) const + size_t operator()(const wrope& __str) const { - size_t sz = str.size(); + size_t __size = __str.size(); - if (0 == sz) return 0; - return 13*str[0] + 5*str[sz - 1] + sz; + if (0 == __size) return 0; + return 13*__str[0] + 5*__str[__size - 1] + __size; } }; @@ -2105,6 +2533,7 @@ __STL_TEMPLATE_NULL struct hash __STL_END_NAMESPACE # include + # endif /* __SGI_STL_INTERNAL_ROPE_H */ // Local Variables: diff --git a/libstdc++/stl/stl_set.h b/libstdc++/stl/stl_set.h index 9ffeaa799a7..003069cb074 100644 --- a/libstdc++/stl/stl_set.h +++ b/libstdc++/stl/stl_set.h @@ -35,158 +35,176 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template , class Alloc = alloc> +template , + class _Alloc = __STL_DEFAULT_ALLOCATOR(_Key) > #else -template +template #endif class set { public: // typedefs: - typedef Key key_type; - typedef Key value_type; - typedef Compare key_compare; - typedef Compare value_compare; + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; private: - typedef rb_tree, key_compare, Alloc> rep_type; - rep_type t; // red-black tree representing set + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + _Rep_type _M_t; // red-black tree representing set public: - typedef typename rep_type::const_pointer pointer; - typedef typename rep_type::const_pointer const_pointer; - typedef typename rep_type::const_reference reference; - typedef typename rep_type::const_reference const_reference; - typedef typename rep_type::const_iterator iterator; - typedef typename rep_type::const_iterator const_iterator; - typedef typename rep_type::const_reverse_iterator reverse_iterator; - typedef typename rep_type::const_reverse_iterator const_reverse_iterator; - typedef typename rep_type::size_type size_type; - typedef typename rep_type::difference_type difference_type; + typedef typename _Rep_type::const_pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::const_reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation - set() : t(Compare()) {} - explicit set(const Compare& comp) : t(comp) {} + set() : _M_t(_Compare(), allocator_type()) {} + explicit set(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) {} #ifdef __STL_MEMBER_TEMPLATES - template - set(InputIterator first, InputIterator last) - : t(Compare()) { t.insert_unique(first, last); } - - template - set(InputIterator first, InputIterator last, const Compare& comp) - : t(comp) { t.insert_unique(first, last); } + template + set(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + template + set(_InputIterator __first, _InputIterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_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); } + set(const value_type* __first, const value_type* __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + set(const value_type* __first, + const value_type* __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } + + set(const_iterator __first, const_iterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + set(const_iterator __first, const_iterator __last, const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { _M_t.insert_unique(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ - set(const set& x) : t(x.t) {} - set& operator=(const set& x) { - t = x.t; + set(const set<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} + set<_Key,_Compare,_Alloc>& operator=(const set<_Key, _Compare, _Alloc>& __x) + { + _M_t = __x._M_t; return *this; } // accessors: - key_compare key_comp() const { return t.key_comp(); } - value_compare value_comp() const { return t.key_comp(); } - iterator begin() const { return t.begin(); } - iterator end() const { return t.end(); } - reverse_iterator rbegin() const { return t.rbegin(); } - reverse_iterator rend() const { return t.rend(); } - bool empty() const { return t.empty(); } - size_type size() const { return t.size(); } - size_type max_size() const { return t.max_size(); } - void swap(set& x) { t.swap(x.t); } + key_compare key_comp() const { return _M_t.key_comp(); } + value_compare value_comp() const { return _M_t.key_comp(); } + allocator_type get_allocator() const { return _M_t.get_allocator(); } + + iterator begin() const { return _M_t.begin(); } + iterator end() const { return _M_t.end(); } + reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator rend() const { return _M_t.rend(); } + bool empty() const { return _M_t.empty(); } + size_type size() const { return _M_t.size(); } + size_type max_size() const { return _M_t.max_size(); } + void swap(set<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } // insert/erase - typedef pair pair_iterator_bool; - pair insert(const value_type& x) { - pair p = t.insert_unique(x); - return pair(p.first, p.second); + pair insert(const value_type& __x) { + pair __p = _M_t.insert_unique(__x); + return pair(__p.first, __p.second); } - iterator insert(iterator position, const value_type& x) { - typedef typename rep_type::iterator rep_iterator; - return t.insert_unique((rep_iterator&)position, x); + iterator insert(iterator __position, const value_type& __x) { + typedef typename _Rep_type::iterator _Rep_iterator; + return _M_t.insert_unique((_Rep_iterator&)__position, __x); } #ifdef __STL_MEMBER_TEMPLATES - template - void insert(InputIterator first, InputIterator last) { - t.insert_unique(first, last); + template + void insert(_InputIterator __first, _InputIterator __last) { + _M_t.insert_unique(__first, __last); } #else - void insert(const_iterator first, const_iterator last) { - t.insert_unique(first, last); + void insert(const_iterator __first, const_iterator __last) { + _M_t.insert_unique(__first, __last); } - void insert(const value_type* first, const value_type* last) { - t.insert_unique(first, last); + void insert(const value_type* __first, const value_type* __last) { + _M_t.insert_unique(__first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ - void erase(iterator position) { - typedef typename rep_type::iterator rep_iterator; - t.erase((rep_iterator&)position); + void erase(iterator __position) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__position); } - size_type erase(const key_type& x) { - return t.erase(x); + size_type erase(const key_type& __x) { + return _M_t.erase(__x); } - void erase(iterator first, iterator last) { - typedef typename rep_type::iterator rep_iterator; - t.erase((rep_iterator&)first, (rep_iterator&)last); + void erase(iterator __first, iterator __last) { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); } - void clear() { t.clear(); } + void clear() { _M_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 find(const key_type& __x) const { return _M_t.find(__x); } + size_type count(const key_type& __x) const { return _M_t.count(__x); } + iterator lower_bound(const key_type& __x) const { + return _M_t.lower_bound(__x); } - iterator upper_bound(const key_type& x) const { - return t.upper_bound(x); + iterator upper_bound(const key_type& __x) const { + return _M_t.upper_bound(__x); } - pair equal_range(const key_type& x) const { - return t.equal_range(x); + pair equal_range(const key_type& __x) const { + return _M_t.equal_range(__x); } friend bool operator== __STL_NULL_TMPL_ARGS (const set&, const set&); friend bool operator< __STL_NULL_TMPL_ARGS (const set&, const set&); }; -template -inline bool operator==(const set& x, - const set& y) { - return x.t == y.t; +template +inline bool operator==(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return __x._M_t == __y._M_t; } -template -inline bool operator<(const set& x, - const set& y) { - return x.t < y.t; +template +inline bool operator<(const set<_Key,_Compare,_Alloc>& __x, + const set<_Key,_Compare,_Alloc>& __y) { + return __x._M_t < __y._M_t; } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template -inline void swap(set& x, - set& y) { - x.swap(y); +template +inline void swap(set<_Key,_Compare,_Alloc>& __x, + set<_Key,_Compare,_Alloc>& __y) { + __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/libstdc++/stl/stl_slist.h b/libstdc++/stl/stl_slist.h index f31ea9e15e5..6da234d92c2 100644 --- a/libstdc++/stl/stl_slist.h +++ b/libstdc++/stl/stl_slist.h @@ -24,704 +24,908 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif -struct __slist_node_base +struct _Slist_node_base { - __slist_node_base* next; + _Slist_node_base* _M_next; }; -inline __slist_node_base* __slist_make_link(__slist_node_base* prev_node, - __slist_node_base* new_node) +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; + __new_node->_M_next = __prev_node->_M_next; + __prev_node->_M_next = __new_node; + return __new_node; } -inline __slist_node_base* __slist_previous(__slist_node_base* head, - const __slist_node_base* 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; + while (__head && __head->_M_next != __node) + __head = __head->_M_next; + return __head; } -inline const __slist_node_base* __slist_previous(const __slist_node_base* head, - const __slist_node_base* node) +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; + while (__head && __head->_M_next != __node) + __head = __head->_M_next; + return __head; } -inline void __slist_splice_after(__slist_node_base* pos, - __slist_node_base* before_first, - __slist_node_base* before_last) +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; + if (__pos != __before_first && __pos != __before_last) { + _Slist_node_base* __first = __before_first->_M_next; + _Slist_node_base* __after = __pos->_M_next; + __before_first->_M_next = __before_last->_M_next; + __pos->_M_next = __first; + __before_last->_M_next = __after; } } -inline __slist_node_base* __slist_reverse(__slist_node_base* node) +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; + _Slist_node_base* __result = __node; + __node = __node->_M_next; + __result->_M_next = 0; + while(__node) { + _Slist_node_base* __next = __node->_M_next; + __node->_M_next = __result; + __result = __node; + __node = __next; + } + return __result; } -template -struct __slist_node : public __slist_node_base +inline size_t __slist_size(_Slist_node_base* __node) { - T data; + size_t __result = 0; + for ( ; __node != 0; __node = __node->_M_next) + ++__result; + return __result; +} + +template +struct _Slist_node : public _Slist_node_base +{ + _Tp _M_data; }; -struct __slist_iterator_base +struct _Slist_iterator_base { - typedef size_t size_type; - typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; typedef forward_iterator_tag iterator_category; - __slist_node_base* node; + _Slist_node_base* _M_node; - __slist_iterator_base(__slist_node_base* x) : node(x) {} - void incr() { node = node->next; } + _Slist_iterator_base(_Slist_node_base* __x) : _M_node(__x) {} + void _M_incr() { _M_node = _M_node->_M_next; } - bool operator==(const __slist_iterator_base& x) const { - return node == x.node; + bool operator==(const _Slist_iterator_base& __x) const { + return _M_node == __x._M_node; } - bool operator!=(const __slist_iterator_base& x) const { - return node != x.node; + bool operator!=(const _Slist_iterator_base& __x) const { + return _M_node != __x._M_node; } }; -template -struct __slist_iterator : public __slist_iterator_base +template +struct _Slist_iterator : public _Slist_iterator_base { - typedef __slist_iterator iterator; - typedef __slist_iterator const_iterator; - typedef __slist_iterator self; + typedef _Slist_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + typedef _Slist_iterator<_Tp, _Ref, _Ptr> _Self; - typedef T value_type; - typedef Ptr pointer; - typedef Ref reference; - typedef __slist_node list_node; + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef _Slist_node<_Tp> _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) {} + _Slist_iterator(_Node* __x) : _Slist_iterator_base(__x) {} + _Slist_iterator() : _Slist_iterator_base(0) {} + _Slist_iterator(const iterator& __x) : _Slist_iterator_base(__x._M_node) {} - reference operator*() const { return ((list_node*) node)->data; } + reference operator*() const { return ((_Node*) _M_node)->_M_data; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ - self& operator++() + _Self& operator++() { - incr(); + _M_incr(); return *this; } - self operator++(int) + _Self operator++(int) { - self tmp = *this; - incr(); - return tmp; + _Self __tmp = *this; + _M_incr(); + return __tmp; } }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION -inline ptrdiff_t* -distance_type(const __slist_iterator_base&) -{ +inline ptrdiff_t* distance_type(const _Slist_iterator_base&) { return 0; } -inline forward_iterator_tag -iterator_category(const __slist_iterator_base&) -{ +inline forward_iterator_tag iterator_category(const _Slist_iterator_base&) { return forward_iterator_tag(); } -template -inline T* -value_type(const __slist_iterator&) { +template +inline _Tp* value_type(const _Slist_iterator<_Tp, _Ref, _Ptr>&) { return 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -inline size_t __slist_size(__slist_node_base* node) +// Base class that encapsulates details of allocators. Three cases: +// an ordinary standard-conforming allocator, a standard-conforming +// allocator with no non-static data, and an SGI-style allocator. +// This complexity is necessary only because we're worrying about backward +// compatibility and because we want to avoid wasting storage on an +// allocator instance if it isn't necessary. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base for general standard-conforming allocators. +template +class _Slist_alloc_base { +public: + typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } + + _Slist_alloc_base(const allocator_type& __a) : _M_node_allocator(__a) {} + +protected: + _Slist_node<_Tp>* _M_get_node() + { return _M_node_allocator.allocate(1); } + void _M_put_node(_Slist_node<_Tp>* __p) + { _M_node_allocator.deallocate(__p, 1); } + +protected: + typename _Alloc_traits<_Slist_node<_Tp>,_Allocator>::allocator_type + _M_node_allocator; + _Slist_node_base _M_head; +}; + +// Specialization for instanceless allocators. +template +class _Slist_alloc_base<_Tp,_Allocator, true> { +public: + typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Slist_alloc_base(const allocator_type&) {} + +protected: + typedef typename _Alloc_traits<_Slist_node<_Tp>, _Allocator>::_Alloc_type + _Alloc_type; + _Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + +protected: + _Slist_node_base _M_head; +}; + + +template +struct _Slist_base + : public _Slist_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> { - size_t result = 0; - for ( ; node != 0; node = node->next) - ++result; - return result; + typedef _Slist_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _Slist_base(const allocator_type& __a) : _Base(__a) { _M_head._M_next = 0; } + ~_Slist_base() { _M_erase_after(&_M_head, 0); } + +protected: + + _Slist_node_base* _M_erase_after(_Slist_node_base* __pos) + { + _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next); + _Slist_node_base* __next_next = __next->_M_next; + __pos->_M_next = __next_next; + destroy(&__next->_M_data); + _M_put_node(__next); + return __next_next; + } + _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +struct _Slist_base { + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Slist_base(const allocator_type&) { _M_head._M_next = 0; } + ~_Slist_base() { _M_erase_after(&_M_head, 0); } + +protected: + typedef simple_alloc<_Slist_node<_Tp>, _Alloc> _Alloc_type; + _Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); } + void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } + + _Slist_node_base* _M_erase_after(_Slist_node_base* __pos) + { + _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next); + _Slist_node_base* __next_next = __next->_M_next; + __pos->_M_next = __next_next; + destroy(&__next->_M_data); + _M_put_node(__next); + return __next_next; + } + _Slist_node_base* _M_erase_after(_Slist_node_base*, _Slist_node_base*); + +protected: + _Slist_node_base _M_head; +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template +_Slist_node_base* +_Slist_base<_Tp,_Alloc>::_M_erase_after(_Slist_node_base* __before_first, + _Slist_node_base* __last_node) { + _Slist_node<_Tp>* __cur = (_Slist_node<_Tp>*) (__before_first->_M_next); + while (__cur != __last_node) { + _Slist_node<_Tp>* __tmp = __cur; + __cur = (_Slist_node<_Tp>*) __cur->_M_next; + destroy(&__tmp->_M_data); + _M_put_node(__tmp); + } + __before_first->_M_next = __last_node; + return __last_node; } -template -class slist +template +class slist : private _Slist_base<_Tp,_Alloc> { +private: + typedef _Slist_base<_Tp,_Alloc> _Base; public: - typedef T value_type; - typedef value_type* pointer; + typedef _Tp value_type; + typedef value_type* pointer; typedef const value_type* const_pointer; - typedef value_type& reference; + typedef value_type& reference; typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + typedef _Slist_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Slist_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; - typedef __slist_iterator iterator; - typedef __slist_iterator const_iterator; + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } private: - typedef __slist_node list_node; - typedef __slist_node_base list_node_base; - typedef __slist_iterator_base iterator_base; - typedef simple_alloc list_node_allocator; + typedef _Slist_node<_Tp> _Node; + typedef _Slist_node_base _Node_base; + typedef _Slist_iterator_base _Iterator_base; - static list_node* create_node(const value_type& x) { - list_node* node = list_node_allocator::allocate(); + _Node* _M_create_node(const value_type& __x) { + _Node* __node = _M_get_node(); __STL_TRY { - construct(&node->data, x); - node->next = 0; + construct(&__node->_M_data, __x); + __node->_M_next = 0; } - __STL_UNWIND(list_node_allocator::deallocate(node)); - return node; + __STL_UNWIND(_M_put_node(__node)); + return __node; } - static void destroy_node(list_node* node) { - destroy(&node->data); - list_node_allocator::deallocate(node); - } - - void fill_initialize(size_type n, const value_type& x) { - head.next = 0; + _Node* _M_create_node() { + _Node* __node = _M_get_node(); __STL_TRY { - _insert_after_fill(&head, n, x); + construct(&__node->_M_data); + __node->_M_next = 0; } - __STL_UNWIND(clear()); - } + __STL_UNWIND(_M_put_node(__node)); + return __node; + } + +private: +#ifdef __STL_USE_NAMESPACES + using _Base::_M_get_node; + using _Base::_M_put_node; + using _Base::_M_erase_after; + using _Base::_M_head; +#endif /* __STL_USE_NAMESPACES */ + +public: + explicit slist(const allocator_type& __a = allocator_type()) : _Base(__a) {} + + slist(size_type __n, const value_type& __x, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_fill(&_M_head, __n, __x); } + + explicit slist(size_type __n) : _Base(allocator_type()) + { _M_insert_after_fill(&_M_head, __n, value_type()); } #ifdef __STL_MEMBER_TEMPLATES - template - void range_initialize(InputIterator first, InputIterator last) { - head.next = 0; - __STL_TRY { - _insert_after_range(&head, first, last); - } - __STL_UNWIND(clear()); - } + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template + slist(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_range(&_M_head, __first, __last); } + #else /* __STL_MEMBER_TEMPLATES */ - void range_initialize(const value_type* first, const value_type* last) { - head.next = 0; - __STL_TRY { - _insert_after_range(&head, first, last); - } - __STL_UNWIND(clear()); - } - void range_initialize(const_iterator first, const_iterator last) { - head.next = 0; - __STL_TRY { - _insert_after_range(&head, first, last); - } - __STL_UNWIND(clear()); - } + slist(const_iterator __first, const_iterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_range(&_M_head, __first, __last); } + slist(const value_type* __first, const value_type* __last, + const allocator_type& __a = allocator_type()) : _Base(__a) + { _M_insert_after_range(&_M_head, __first, __last); } #endif /* __STL_MEMBER_TEMPLATES */ -private: - list_node_base head; + slist(const slist& __x) : _Base(__x.get_allocator()) + { _M_insert_after_range(&_M_head, __x.begin(), __x.end()); } + + slist& operator= (const slist& __x); + + ~slist() {} public: - slist() { head.next = 0; } + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. - 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()); } + void assign(size_type __n, const _Tp& __val); #ifdef __STL_MEMBER_TEMPLATES - template - slist(InputIterator first, InputIterator last) { - range_initialize(first, last); - } -#else /* __STL_MEMBER_TEMPLATES */ - slist(const_iterator first, const_iterator last) { - range_initialize(first, last); + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); } - 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()); } + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { assign((size_type) __n, (_Tp) __val); } - slist& operator= (const slist& L); + template + void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); - ~slist() { clear(); } +#endif /* __STL_MEMBER_TEMPLATES */ public: - iterator begin() { return iterator((list_node*)head.next); } - const_iterator begin() const { return const_iterator((list_node*)head.next);} + iterator begin() { return iterator((_Node*)_M_head._M_next); } + const_iterator begin() const + { return const_iterator((_Node*)_M_head._M_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 size() const { return __slist_size(_M_head._M_next); } size_type max_size() const { return size_type(-1); } - bool empty() const { return head.next == 0; } + bool empty() const { return _M_head._M_next == 0; } - void swap(slist& L) - { - list_node_base* tmp = head.next; - head.next = L.head.next; - L.head.next = tmp; - } + void swap(slist& __x) { __STD::swap(_M_head._M_next, __x._M_head._M_next); } public: - friend bool operator== __STL_NULL_TMPL_ARGS(const slist& L1, - const slist& L2); + friend bool operator== __STL_NULL_TMPL_ARGS (const slist<_Tp,_Alloc>& _SL1, + const slist<_Tp,_Alloc>& _SL2); 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)); + reference front() { return ((_Node*) _M_head._M_next)->_M_data; } + const_reference front() const + { return ((_Node*) _M_head._M_next)->_M_data; } + void push_front(const value_type& __x) { + __slist_make_link(&_M_head, _M_create_node(__x)); } + void push_front() { __slist_make_link(&_M_head, _M_create_node());} void pop_front() { - list_node* node = (list_node*) head.next; - head.next = node->next; - destroy_node(node); + _Node* __node = (_Node*) _M_head._M_next; + _M_head._M_next = __node->_M_next; + destroy(&__node->_M_data); + _M_put_node(__node); } - iterator previous(const_iterator pos) { - return iterator((list_node*) __slist_previous(&head, pos.node)); + iterator previous(const_iterator __pos) { + return iterator((_Node*) __slist_previous(&_M_head, __pos._M_node)); } - const_iterator previous(const_iterator pos) const { - return const_iterator((list_node*) __slist_previous(&head, pos.node)); + const_iterator previous(const_iterator __pos) const { + return const_iterator((_Node*) __slist_previous(&_M_head, __pos._M_node)); } private: - list_node* _insert_after(list_node_base* pos, const value_type& x) { - return (list_node*) (__slist_make_link(pos, create_node(x))); + _Node* _M_insert_after(_Node_base* __pos, const value_type& __x) { + return (_Node*) (__slist_make_link(__pos, _M_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)); + _Node* _M_insert_after(_Node_base* __pos) { + return (_Node*) (__slist_make_link(__pos, _M_create_node())); + } + + void _M_insert_after_fill(_Node_base* __pos, + size_type __n, const value_type& __x) { + for (size_type __i = 0; __i < __n; ++__i) + __pos = __slist_make_link(__pos, _M_create_node(__x)); } #ifdef __STL_MEMBER_TEMPLATES - template - void _insert_after_range(list_node_base* pos, InIter first, InIter last) { - while (first != last) { - pos = __slist_make_link(pos, create_node(*first)); - ++first; - } + + // Check whether it's an integral type. If so, it's not an iterator. + template + void _M_insert_after_range(_Node_base* __pos, + _InIter __first, _InIter __last) { + typedef typename _Is_integer<_InIter>::_Integral _Integral; + _M_insert_after_range(__pos, __first, __last, _Integral()); } -#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; - } + + template + void _M_insert_after_range(_Node_base* __pos, _Integer __n, _Integer __x, + __true_type) { + _M_insert_after_fill(__pos, __n, __x); } - 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; + + template + void _M_insert_after_range(_Node_base* __pos, + _InIter __first, _InIter __last, + __false_type) { + while (__first != __last) { + __pos = __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; } } -#endif /* __STL_MEMBER_TEMPLATES */ - list_node_base* erase_after(list_node_base* pos) { - list_node* next = (list_node*) (pos->next); - list_node_base* next_next = next->next; - pos->next = next_next; - destroy_node(next); - return next_next; - } - - list_node_base* erase_after(list_node_base* before_first, - list_node_base* last_node) { - list_node* cur = (list_node*) (before_first->next); - while (cur != last_node) { - list_node* tmp = cur; - cur = (list_node*) cur->next; - destroy_node(tmp); +#else /* __STL_MEMBER_TEMPLATES */ + + void _M_insert_after_range(_Node_base* __pos, + const_iterator __first, const_iterator __last) { + while (__first != __last) { + __pos = __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; + } + } + void _M_insert_after_range(_Node_base* __pos, + const value_type* __first, + const value_type* __last) { + while (__first != __last) { + __pos = __slist_make_link(__pos, _M_create_node(*__first)); + ++__first; } - before_first->next = last_node; - return last_node; } +#endif /* __STL_MEMBER_TEMPLATES */ public: - iterator insert_after(iterator pos, const value_type& x) { - return iterator(_insert_after(pos.node, x)); + iterator insert_after(iterator __pos, const value_type& __x) { + return iterator(_M_insert_after(__pos._M_node, __x)); } - iterator insert_after(iterator pos) { - return insert_after(pos, value_type()); + 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); + void insert_after(iterator __pos, size_type __n, const value_type& __x) { + _M_insert_after_fill(__pos._M_node, __n, __x); } #ifdef __STL_MEMBER_TEMPLATES - template - void insert_after(iterator pos, InIter first, InIter last) { - _insert_after_range(pos.node, first, last); + + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template + void insert_after(iterator __pos, _InIter __first, _InIter __last) { + _M_insert_after_range(__pos._M_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_iterator __first, const_iterator __last) { + _M_insert_after_range(__pos._M_node, __first, __last); } - void insert_after(iterator pos, - const value_type* first, const value_type* last) { - _insert_after_range(pos.node, first, last); + void insert_after(iterator __pos, + const value_type* __first, const value_type* __last) { + _M_insert_after_range(__pos._M_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, const value_type& __x) { + return iterator(_M_insert_after(__slist_previous(&_M_head, __pos._M_node), + __x)); } - iterator insert(iterator pos) { - return iterator(_insert_after(__slist_previous(&head, pos.node), - value_type())); + iterator insert(iterator __pos) { + return iterator(_M_insert_after(__slist_previous(&_M_head, __pos._M_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); + void insert(iterator __pos, size_type __n, const value_type& __x) { + _M_insert_after_fill(__slist_previous(&_M_head, __pos._M_node), __n, __x); } #ifdef __STL_MEMBER_TEMPLATES - template - void insert(iterator pos, InIter first, InIter last) { - _insert_after_range(__slist_previous(&head, pos.node), first, last); + + // We don't need any dispatching tricks here, because _M_insert_after_range + // already does them. + template + void insert(iterator __pos, _InIter __first, _InIter __last) { + _M_insert_after_range(__slist_previous(&_M_head, __pos._M_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_iterator __first, const_iterator __last) { + _M_insert_after_range(__slist_previous(&_M_head, __pos._M_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); + void insert(iterator __pos, const value_type* __first, + const value_type* __last) { + _M_insert_after_range(__slist_previous(&_M_head, __pos._M_node), + __first, __last); } + #endif /* __STL_MEMBER_TEMPLATES */ public: - iterator erase_after(iterator pos) { - return iterator((list_node*)erase_after(pos.node)); - } - iterator erase_after(iterator before_first, iterator last) { - return iterator((list_node*)erase_after(before_first.node, last.node)); + iterator erase_after(iterator __pos) { + return iterator((_Node*) _M_erase_after(__pos._M_node)); } + iterator erase_after(iterator __before_first, iterator __last) { + return iterator((_Node*) _M_erase_after(__before_first._M_node, + __last._M_node)); + } - iterator erase(iterator pos) { - return (list_node*) erase_after(__slist_previous(&head, pos.node)); + iterator erase(iterator __pos) { + return (_Node*) _M_erase_after(__slist_previous(&_M_head, + __pos._M_node)); } - iterator erase(iterator first, iterator last) { - return (list_node*) erase_after(__slist_previous(&head, first.node), - last.node); + iterator erase(iterator __first, iterator __last) { + return (_Node*) _M_erase_after( + __slist_previous(&_M_head, __first._M_node), __last._M_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); } + void resize(size_type new_size, const _Tp& __x); + void resize(size_type new_size) { resize(new_size, _Tp()); } + void clear() { _M_erase_after(&_M_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) + // 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); + if (__before_first != __before_last) + __slist_splice_after(__pos._M_node, __before_first._M_node, + __before_last._M_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) + // 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); + __slist_splice_after(__pos._M_node, + __prev._M_node, __prev._M_node->_M_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 linear in __x.size(). + void splice(iterator __pos, slist& __x) { + if (__x._M_head._M_next) + __slist_splice_after(__slist_previous(&_M_head, __pos._M_node), + &__x._M_head, __slist_previous(&__x._M_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), and in distance(__x.begin(), __i). + void splice(iterator __pos, slist& __x, iterator __i) { + __slist_splice_after(__slist_previous(&_M_head, __pos._M_node), + __slist_previous(&__x._M_head, __i._M_node), + __i._M_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) + // Linear in distance(begin(), __pos), in distance(__x.begin(), __first), + // and in distance(__first, __last). + void splice(iterator __pos, slist& __x, 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)); + if (__first != __last) + __slist_splice_after(__slist_previous(&_M_head, __pos._M_node), + __slist_previous(&__x._M_head, __first._M_node), + __slist_previous(__first._M_node, __last._M_node)); } public: - void reverse() { if (head.next) head.next = __slist_reverse(head.next); } + void reverse() { + if (_M_head._M_next) + _M_head._M_next = __slist_reverse(_M_head._M_next); + } - void remove(const T& val); + void remove(const _Tp& __val); void unique(); - void merge(slist& L); + void merge(slist& __x); void sort(); #ifdef __STL_MEMBER_TEMPLATES - template void remove_if(Predicate pred); - template void unique(BinaryPredicate pred); - template void merge(slist&, StrictWeakOrdering); - template void sort(StrictWeakOrdering comp); + template + void remove_if(_Predicate __pred); + + template + void unique(_BinaryPredicate __pred); + + template + void merge(slist&, _StrictWeakOrdering); + + template + void sort(_StrictWeakOrdering __comp); #endif /* __STL_MEMBER_TEMPLATES */ }; -template -slist& slist::operator=(const slist& L) +template +slist<_Tp,_Alloc>& slist<_Tp,_Alloc>::operator=(const slist<_Tp,_Alloc>& __x) { - 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 (&__x != this) { + _Node_base* __p1 = &_M_head; + _Node* __n1 = (_Node*) _M_head._M_next; + const _Node* __n2 = (const _Node*) __x._M_head._M_next; + while (__n1 && __n2) { + __n1->_M_data = __n2->_M_data; + __p1 = __n1; + __n1 = (_Node*) __n1->_M_next; + __n2 = (const _Node*) __n2->_M_next; } - if (n2 == 0) - erase_after(p1, 0); + if (__n2 == 0) + _M_erase_after(__p1, 0); else - _insert_after_range(p1, - const_iterator((list_node*)n2), const_iterator(0)); + _M_insert_after_range(__p1, const_iterator((_Node*)__n2), + const_iterator(0)); } return *this; -} +} + +template +void slist<_Tp, _Alloc>::assign(size_type __n, const _Tp& __val) { + _Node_base* __prev = &_M_head; + _Node* __node = (_Node*) _M_head._M_next; + for ( ; __node != 0 && __n > 0 ; --__n) { + __node->_M_data = __val; + __prev = __node; + __node = (_Node*) __node->_M_next; + } + if (__n > 0) + _M_insert_after_fill(__prev, __n, __val); + else + _M_erase_after(__prev, 0); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void +slist<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first, _InputIter __last, + __false_type) +{ + _Node_base* __prev = &_M_head; + _Node* __node = (_Node*) _M_head._M_next; + while (__node != 0 && __first != __last) { + __node->_M_data = *__first; + __prev = __node; + __node = (_Node*) __node->_M_next; + ++__first; + } + if (__first != __last) + _M_insert_after_range(__prev, __first, __last); + else + _M_erase_after(__prev, 0); +} + +#endif /* __STL_MEMBER_TEMPLATES */ -template -bool operator==(const slist& L1, const slist& L2) +template +inline bool +operator==(const slist<_Tp,_Alloc>& _SL1, const slist<_Tp,_Alloc>& _SL2) { - typedef typename slist::list_node list_node; - list_node* n1 = (list_node*) L1.head.next; - list_node* n2 = (list_node*) L2.head.next; - while (n1 && n2 && n1->data == n2->data) { - n1 = (list_node*) n1->next; - n2 = (list_node*) n2->next; - } - return n1 == 0 && n2 == 0; + typedef typename slist<_Tp,_Alloc>::_Node _Node; + _Node* __n1 = (_Node*) _SL1._M_head._M_next; + _Node* __n2 = (_Node*) _SL2._M_head._M_next; + while (__n1 && __n2 && __n1->_M_data == __n2->_M_data) { + __n1 = (_Node*) __n1->_M_next; + __n2 = (_Node*) __n2->_M_next; + } + return __n1 == 0 && __n2 == 0; } -template -inline bool operator<(const slist& L1, const slist& L2) +template +inline bool operator<(const slist<_Tp,_Alloc>& _SL1, + const slist<_Tp,_Alloc>& _SL2) { - return lexicographical_compare(L1.begin(), L1.end(), L2.begin(), L2.end()); + return lexicographical_compare(_SL1.begin(), _SL1.end(), + _SL2.begin(), _SL2.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template -inline void swap(slist& x, slist& y) { - x.swap(y); +template +inline void swap(slist<_Tp,_Alloc>& __x, slist<_Tp,_Alloc>& __y) { + __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ -template -void slist::resize(size_type len, const T& x) +template +void slist<_Tp,_Alloc>::resize(size_type __len, const _Tp& __x) { - list_node_base* cur = &head; - while (cur->next != 0 && len > 0) { - --len; - cur = cur->next; + _Node_base* __cur = &_M_head; + while (__cur->_M_next != 0 && __len > 0) { + --__len; + __cur = __cur->_M_next; } - if (cur->next) - erase_after(cur, 0); + if (__cur->_M_next) + _M_erase_after(__cur, 0); else - _insert_after_fill(cur, len, x); + _M_insert_after_fill(__cur, __len, __x); } -template -void slist::remove(const T& val) +template +void slist<_Tp,_Alloc>::remove(const _Tp& __val) { - list_node_base* cur = &head; - while (cur && cur->next) { - if (((list_node*) cur->next)->data == val) - erase_after(cur); + _Node_base* __cur = &_M_head; + while (__cur && __cur->_M_next) { + if (((_Node*) __cur->_M_next)->_M_data == __val) + _M_erase_after(__cur); else - cur = cur->next; + __cur = __cur->_M_next; } } -template -void slist::unique() +template +void slist<_Tp,_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); + _Node_base* __cur = _M_head._M_next; + if (__cur) { + while (__cur->_M_next) { + if (((_Node*)__cur)->_M_data == + ((_Node*)(__cur->_M_next))->_M_data) + _M_erase_after(__cur); else - cur = cur->next; + __cur = __cur->_M_next; } } } -template -void slist::merge(slist& L) +template +void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x) { - 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; + _Node_base* __n1 = &_M_head; + while (__n1->_M_next && __x._M_head._M_next) { + if (((_Node*) __x._M_head._M_next)->_M_data < + ((_Node*) __n1->_M_next)->_M_data) + __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); + __n1 = __n1->_M_next; } - if (L.head.next) { - n1->next = L.head.next; - L.head.next = 0; + if (__x._M_head._M_next) { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; } } -template -void slist::sort() +template +void slist<_Tp,_Alloc>::sort() { - if (head.next && head.next->next) { - slist carry; - slist counter[64]; - int fill = 0; + if (_M_head._M_next && _M_head._M_next->_M_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; + __slist_splice_after(&__carry._M_head, &_M_head, _M_head._M_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; + __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]); + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1]); + this->swap(__counter[__fill-1]); } } #ifdef __STL_MEMBER_TEMPLATES -template -template void slist::remove_if(Predicate pred) +template +template +void slist<_Tp,_Alloc>::remove_if(_Predicate __pred) { - list_node_base* cur = &head; - while (cur->next) { - if (pred(((list_node*) cur->next)->data)) - erase_after(cur); + _Node_base* __cur = &_M_head; + while (__cur->_M_next) { + if (__pred(((_Node*) __cur->_M_next)->_M_data)) + _M_erase_after(__cur); else - cur = cur->next; + __cur = __cur->_M_next; } } -template template -void slist::unique(BinaryPredicate pred) +template template +void slist<_Tp,_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); + _Node* __cur = (_Node*) _M_head._M_next; + if (__cur) { + while (__cur->_M_next) { + if (__pred(((_Node*)__cur)->_M_data, + ((_Node*)(__cur->_M_next))->_M_data)) + _M_erase_after(__cur); else - cur = (list_node*) cur->next; + __cur = (_Node*) __cur->_M_next; } } } -template template -void slist::merge(slist& L, StrictWeakOrdering comp) +template template +void slist<_Tp,_Alloc>::merge(slist<_Tp,_Alloc>& __x, + _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; + _Node_base* __n1 = &_M_head; + while (__n1->_M_next && __x._M_head._M_next) { + if (__comp(((_Node*) __x._M_head._M_next)->_M_data, + ((_Node*) __n1->_M_next)->_M_data)) + __slist_splice_after(__n1, &__x._M_head, __x._M_head._M_next); + __n1 = __n1->_M_next; } - if (L.head.next) { - n1->next = L.head.next; - L.head.next = 0; + if (__x._M_head._M_next) { + __n1->_M_next = __x._M_head._M_next; + __x._M_head._M_next = 0; } } -template template -void slist::sort(StrictWeakOrdering comp) +template template +void slist<_Tp,_Alloc>::sort(_StrictWeakOrdering __comp) { - if (head.next && head.next->next) { - slist carry; - slist counter[64]; - int fill = 0; + if (_M_head._M_next && _M_head._M_next->_M_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; + __slist_splice_after(&__carry._M_head, &_M_head, _M_head._M_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; + __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]); + for (int __i = 1; __i < __fill; ++__i) + __counter[__i].merge(__counter[__i-1], __comp); + this->swap(__counter[__fill-1]); } } @@ -729,6 +933,7 @@ void slist::sort(StrictWeakOrdering comp) #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/libstdc++/stl/stl_stack.h b/libstdc++/stl/stl_stack.h index d380e81dd1f..2a04b21e507 100644 --- a/libstdc++/stl/stl_stack.h +++ b/libstdc++/stl/stl_stack.h @@ -34,39 +34,74 @@ __STL_BEGIN_NAMESPACE #ifndef __STL_LIMITED_DEFAULT_TEMPLATES -template > +template > #else -template +template #endif class stack { friend bool operator== __STL_NULL_TMPL_ARGS (const stack&, const stack&); friend bool operator< __STL_NULL_TMPL_ARGS (const stack&, const stack&); public: - typedef typename Sequence::value_type value_type; - typedef typename Sequence::size_type size_type; - typedef typename Sequence::reference reference; - typedef typename Sequence::const_reference const_reference; + typedef typename _Sequence::value_type value_type; + typedef typename _Sequence::size_type size_type; + typedef _Sequence container_type; + + typedef typename _Sequence::reference reference; + typedef typename _Sequence::const_reference const_reference; protected: - Sequence c; + _Sequence _M_c; public: - bool empty() const { return c.empty(); } - size_type size() const { return c.size(); } - reference top() { return c.back(); } - const_reference top() const { return c.back(); } - void push(const value_type& x) { c.push_back(x); } - void pop() { c.pop_back(); } + stack() : _M_c() {} + explicit stack(const _Sequence& __s) : _M_c(__s) {} + + bool empty() const { return _M_c.empty(); } + size_type size() const { return _M_c.size(); } + reference top() { return _M_c.back(); } + const_reference top() const { return _M_c.back(); } + void push(const value_type& __x) { _M_c.push_back(__x); } + void pop() { _M_c.pop_back(); } }; -template -bool operator==(const stack& x, const stack& y) { - return x.c == y.c; +template +bool operator==(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return __x._M_c == __y._M_c; +} + +template +bool operator<(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return __x._M_c < __y._M_c; +} + +#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER + +template +bool operator!=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return !(__x == __y); +} + +template +bool operator>(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return __y < __x; } -template -bool operator<(const stack& x, const stack& y) { - return x.c < y.c; +template +bool operator<=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return !(__y < __x); } +template +bool operator>=(const stack<_Tp,_Seq>& __x, const stack<_Tp,_Seq>& __y) +{ + return !(__x < __y); +} + +#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ + __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_STACK_H */ diff --git a/libstdc++/stl/stl_tempbuf.h b/libstdc++/stl/stl_tempbuf.h index 9dbc238eaee..e1b2eadafcb 100644 --- a/libstdc++/stl/stl_tempbuf.h +++ b/libstdc++/stl/stl_tempbuf.h @@ -34,86 +34,119 @@ __STL_BEGIN_NAMESPACE -template -pair get_temporary_buffer(ptrdiff_t len, T*) { - if (len > ptrdiff_t(INT_MAX / sizeof(T))) - len = INT_MAX / sizeof(T); - - while (len > 0) { - T* tmp = (T*) malloc((size_t)len * sizeof(T)); - if (tmp != 0) - return pair(tmp, len); - len /= 2; +template +pair<_Tp*, ptrdiff_t> +__get_temporary_buffer(ptrdiff_t __len, _Tp*) +{ + if (__len > ptrdiff_t(INT_MAX / sizeof(_Tp))) + __len = INT_MAX / sizeof(_Tp); + + while (__len > 0) { + _Tp* __tmp = (_Tp*) malloc((size_t)__len * sizeof(_Tp)); + if (__tmp != 0) + return pair<_Tp*, ptrdiff_t>(__tmp, __len); + __len /= 2; } - return pair((T*)0, 0); + return pair<_Tp*, ptrdiff_t>((_Tp*)0, 0); } -template -void return_temporary_buffer(T* p) { - free(p); +#ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS + +template +inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len) { + return __get_temporary_buffer(__len, (_Tp*) 0); } -template ::value_type -#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ - > -class temporary_buffer { +#endif /* __STL_EXPLICIT_FUNCTION_TMPL_ARGS */ + +// This overload is not required by the standard; it is an extension. +// It is supported for backward compatibility with the HP STL, and +// because not all compilers support the language feature (explicit +// function template arguments) that is required for the standard +// version of get_temporary_buffer. +template +inline pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __len, _Tp*) { + return __get_temporary_buffer(__len, (_Tp*) 0); +} + +template +void return_temporary_buffer(_Tp* __p) { + free(__p); +} + +template +class _Temporary_buffer { private: - ptrdiff_t original_len; - ptrdiff_t len; - T* buffer; + ptrdiff_t _M_original_len; + ptrdiff_t _M_len; + _Tp* _M_buffer; - void allocate_buffer() { - original_len = len; - buffer = 0; + void _M_allocate_buffer() { + _M_original_len = _M_len; + _M_buffer = 0; - if (len > (ptrdiff_t)(INT_MAX / sizeof(T))) - len = INT_MAX / sizeof(T); + if (_M_len > (ptrdiff_t)(INT_MAX / sizeof(_Tp))) + _M_len = INT_MAX / sizeof(_Tp); - while (len > 0) { - buffer = (T*) malloc(len * sizeof(T)); - if (buffer) + while (_M_len > 0) { + _M_buffer = (_Tp*) malloc(_M_len * sizeof(_Tp)); + if (_M_buffer) break; - len /= 2; + _M_len /= 2; } } - void initialize_buffer(const T&, __true_type) {} - void initialize_buffer(const T& val, __false_type) { - uninitialized_fill_n(buffer, len, val); + void _M_initialize_buffer(const _Tp&, __true_type) {} + void _M_initialize_buffer(const _Tp& val, __false_type) { + uninitialized_fill_n(_M_buffer, _M_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) { + ptrdiff_t size() const { return _M_len; } + ptrdiff_t requested_size() const { return _M_original_len; } + _Tp* begin() { return _M_buffer; } + _Tp* end() { return _M_buffer + _M_len; } + + _Temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) { + typedef typename __type_traits<_Tp>::has_trivial_default_constructor + _Trivial; __STL_TRY { - len = 0; - distance(first, last, len); - allocate_buffer(); - if (len > 0) - initialize_buffer(*first, - typename __type_traits::has_trivial_default_constructor()); + _M_len = 0; + distance(__first, __last, _M_len); + _M_allocate_buffer(); + if (_M_len > 0) + _M_initialize_buffer(*__first, _Trivial()); } - __STL_UNWIND(free(buffer); buffer = 0; len = 0); + __STL_UNWIND(free(_M_buffer); _M_buffer = 0; _M_len = 0); } - ~temporary_buffer() { - destroy(buffer, buffer + len); - free(buffer); + ~_Temporary_buffer() { + destroy(_M_buffer, _M_buffer + _M_len); + free(_M_buffer); } private: - temporary_buffer(const temporary_buffer&) {} - void operator=(const temporary_buffer&) {} + // Disable copy constructor and assignment operator. + _Temporary_buffer(const _Temporary_buffer&) {} + void operator=(const _Temporary_buffer&) {} }; +// Class temporary_buffer is not part of the standard. It is an extension. + +template ::value_type +#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + > +struct temporary_buffer : public _Temporary_buffer<_ForwardIterator, _Tp> +{ + temporary_buffer(_ForwardIterator __first, _ForwardIterator __last) + : _Temporary_buffer<_ForwardIterator, _Tp>(__first, __last) {} + ~temporary_buffer() {} +}; + __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_TEMPBUF_H */ diff --git a/libstdc++/stl/stl_tree.h b/libstdc++/stl/stl_tree.h index 55a6c0e53b2..c82943f568a 100644 --- a/libstdc++/stl/stl_tree.h +++ b/libstdc++/stl/stl_tree.h @@ -60,439 +60,566 @@ iterators invalidated are those referring to the deleted node. __STL_BEGIN_NAMESPACE -typedef bool __rb_tree_color_type; -const __rb_tree_color_type __rb_tree_red = false; -const __rb_tree_color_type __rb_tree_black = true; +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma set woff 1375 +#endif -struct __rb_tree_node_base +typedef bool _Rb_tree_Color_type; +const _Rb_tree_Color_type _S_rb_tree_red = false; +const _Rb_tree_Color_type _S_rb_tree_black = true; + +struct _Rb_tree_node_base { - typedef __rb_tree_color_type color_type; - typedef __rb_tree_node_base* base_ptr; + typedef _Rb_tree_Color_type _Color_type; + typedef _Rb_tree_node_base* _Base_ptr; - color_type color; - base_ptr parent; - base_ptr left; - base_ptr right; + _Color_type _M_color; + _Base_ptr _M_parent; + _Base_ptr _M_left; + _Base_ptr _M_right; - static base_ptr minimum(base_ptr x) + static _Base_ptr _S_minimum(_Base_ptr __x) { - while (x->left != 0) x = x->left; - return x; + while (__x->_M_left != 0) __x = __x->_M_left; + return __x; } - static base_ptr maximum(base_ptr x) + static _Base_ptr _S_maximum(_Base_ptr __x) { - while (x->right != 0) x = x->right; - return x; + while (__x->_M_right != 0) __x = __x->_M_right; + return __x; } }; -template -struct __rb_tree_node : public __rb_tree_node_base +template +struct _Rb_tree_node : public _Rb_tree_node_base { - typedef __rb_tree_node* link_type; - Value value_field; + typedef _Rb_tree_node<_Value>* _Link_type; + _Value _M_value_field; }; -struct __rb_tree_base_iterator +struct _Rb_tree_base_iterator { - typedef __rb_tree_node_base::base_ptr base_ptr; + typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; typedef bidirectional_iterator_tag iterator_category; typedef ptrdiff_t difference_type; - base_ptr node; + _Base_ptr _M_node; - void increment() + void _M_increment() { - if (node->right != 0) { - node = node->right; - while (node->left != 0) - node = node->left; + if (_M_node->_M_right != 0) { + _M_node = _M_node->_M_right; + while (_M_node->_M_left != 0) + _M_node = _M_node->_M_left; } else { - base_ptr y = node->parent; - while (node == y->right) { - node = y; - y = y->parent; + _Base_ptr __y = _M_node->_M_parent; + while (_M_node == __y->_M_right) { + _M_node = __y; + __y = __y->_M_parent; } - if (node->right != y) - node = y; + if (_M_node->_M_right != __y) + _M_node = __y; } } - void decrement() + void _M_decrement() { - if (node->color == __rb_tree_red && - node->parent->parent == node) - node = node->right; - else if (node->left != 0) { - base_ptr y = node->left; - while (y->right != 0) - y = y->right; - node = y; + if (_M_node->_M_color == _S_rb_tree_red && + _M_node->_M_parent->_M_parent == _M_node) + _M_node = _M_node->_M_right; + else if (_M_node->_M_left != 0) { + _Base_ptr __y = _M_node->_M_left; + while (__y->_M_right != 0) + __y = __y->_M_right; + _M_node = __y; } else { - base_ptr y = node->parent; - while (node == y->left) { - node = y; - y = y->parent; + _Base_ptr __y = _M_node->_M_parent; + while (_M_node == __y->_M_left) { + _M_node = __y; + __y = __y->_M_parent; } - node = y; + _M_node = __y; } } }; -template -struct __rb_tree_iterator : public __rb_tree_base_iterator +template +struct _Rb_tree_iterator : public _Rb_tree_base_iterator { - typedef Value value_type; - typedef Ref reference; - typedef Ptr pointer; - typedef __rb_tree_iterator iterator; - typedef __rb_tree_iterator const_iterator; - typedef __rb_tree_iterator self; - typedef __rb_tree_node* link_type; - - __rb_tree_iterator() {} - __rb_tree_iterator(link_type x) { node = x; } - __rb_tree_iterator(const iterator& it) { node = it.node; } - - reference operator*() const { return link_type(node)->value_field; } + typedef _Value value_type; + typedef _Ref reference; + typedef _Ptr pointer; + typedef _Rb_tree_iterator<_Value, _Value&, _Value*> + iterator; + typedef _Rb_tree_iterator<_Value, const _Value&, const _Value*> + const_iterator; + typedef _Rb_tree_iterator<_Value, _Ref, _Ptr> + _Self; + typedef _Rb_tree_node<_Value>* _Link_type; + + _Rb_tree_iterator() {} + _Rb_tree_iterator(_Link_type __x) { _M_node = __x; } + _Rb_tree_iterator(const iterator& __it) { _M_node = __it._M_node; } + + reference operator*() const { return _Link_type(_M_node)->_M_value_field; } #ifndef __SGI_STL_NO_ARROW_OPERATOR pointer operator->() const { return &(operator*()); } #endif /* __SGI_STL_NO_ARROW_OPERATOR */ - self& operator++() { increment(); return *this; } - self operator++(int) { - self tmp = *this; - increment(); - return tmp; + _Self& operator++() { _M_increment(); return *this; } + _Self operator++(int) { + _Self __tmp = *this; + _M_increment(); + return __tmp; } - self& operator--() { decrement(); return *this; } - self operator--(int) { - self tmp = *this; - decrement(); - return tmp; + _Self& operator--() { _M_decrement(); return *this; } + _Self operator--(int) { + _Self __tmp = *this; + _M_decrement(); + return __tmp; } }; -inline bool operator==(const __rb_tree_base_iterator& x, - const __rb_tree_base_iterator& y) { - return x.node == y.node; +inline bool operator==(const _Rb_tree_base_iterator& __x, + const _Rb_tree_base_iterator& __y) { + return __x._M_node == __y._M_node; } -inline bool operator!=(const __rb_tree_base_iterator& x, - const __rb_tree_base_iterator& y) { - return x.node != y.node; +inline bool operator!=(const _Rb_tree_base_iterator& __x, + const _Rb_tree_base_iterator& __y) { + return __x._M_node != __y._M_node; } #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION inline bidirectional_iterator_tag -iterator_category(const __rb_tree_base_iterator&) { +iterator_category(const _Rb_tree_base_iterator&) { return bidirectional_iterator_tag(); } -inline __rb_tree_base_iterator::difference_type* -distance_type(const __rb_tree_base_iterator&) { - return (__rb_tree_base_iterator::difference_type*) 0; +inline _Rb_tree_base_iterator::difference_type* +distance_type(const _Rb_tree_base_iterator&) { + return (_Rb_tree_base_iterator::difference_type*) 0; } -template -inline Value* value_type(const __rb_tree_iterator&) { - return (Value*) 0; +template +inline _Value* value_type(const _Rb_tree_iterator<_Value, _Ref, _Ptr>&) { + return (_Value*) 0; } #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ inline void -__rb_tree_rotate_left(__rb_tree_node_base* x, __rb_tree_node_base*& root) +_Rb_tree_rotate_left(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) { - __rb_tree_node_base* y = x->right; - x->right = y->left; - if (y->left !=0) - y->left->parent = x; - y->parent = x->parent; - - if (x == root) - root = y; - else if (x == x->parent->left) - x->parent->left = y; + _Rb_tree_node_base* __y = __x->_M_right; + __x->_M_right = __y->_M_left; + if (__y->_M_left !=0) + __y->_M_left->_M_parent = __x; + __y->_M_parent = __x->_M_parent; + + if (__x == __root) + __root = __y; + else if (__x == __x->_M_parent->_M_left) + __x->_M_parent->_M_left = __y; else - x->parent->right = y; - y->left = x; - x->parent = y; + __x->_M_parent->_M_right = __y; + __y->_M_left = __x; + __x->_M_parent = __y; } inline void -__rb_tree_rotate_right(__rb_tree_node_base* x, __rb_tree_node_base*& root) +_Rb_tree_rotate_right(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) { - __rb_tree_node_base* y = x->left; - x->left = y->right; - if (y->right != 0) - y->right->parent = x; - y->parent = x->parent; - - if (x == root) - root = y; - else if (x == x->parent->right) - x->parent->right = y; + _Rb_tree_node_base* __y = __x->_M_left; + __x->_M_left = __y->_M_right; + if (__y->_M_right != 0) + __y->_M_right->_M_parent = __x; + __y->_M_parent = __x->_M_parent; + + if (__x == __root) + __root = __y; + else if (__x == __x->_M_parent->_M_right) + __x->_M_parent->_M_right = __y; else - x->parent->left = y; - y->right = x; - x->parent = y; + __x->_M_parent->_M_left = __y; + __y->_M_right = __x; + __x->_M_parent = __y; } inline void -__rb_tree_rebalance(__rb_tree_node_base* x, __rb_tree_node_base*& root) +_Rb_tree_rebalance(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) { - x->color = __rb_tree_red; - while (x != root && x->parent->color == __rb_tree_red) { - if (x->parent == x->parent->parent->left) { - __rb_tree_node_base* y = x->parent->parent->right; - if (y && y->color == __rb_tree_red) { - x->parent->color = __rb_tree_black; - y->color = __rb_tree_black; - x->parent->parent->color = __rb_tree_red; - x = x->parent->parent; + __x->_M_color = _S_rb_tree_red; + while (__x != __root && __x->_M_parent->_M_color == _S_rb_tree_red) { + if (__x->_M_parent == __x->_M_parent->_M_parent->_M_left) { + _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_right; + if (__y && __y->_M_color == _S_rb_tree_red) { + __x->_M_parent->_M_color = _S_rb_tree_black; + __y->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + __x = __x->_M_parent->_M_parent; } else { - if (x == x->parent->right) { - x = x->parent; - __rb_tree_rotate_left(x, root); + if (__x == __x->_M_parent->_M_right) { + __x = __x->_M_parent; + _Rb_tree_rotate_left(__x, __root); } - x->parent->color = __rb_tree_black; - x->parent->parent->color = __rb_tree_red; - __rb_tree_rotate_right(x->parent->parent, root); + __x->_M_parent->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_right(__x->_M_parent->_M_parent, __root); } } else { - __rb_tree_node_base* y = x->parent->parent->left; - if (y && y->color == __rb_tree_red) { - x->parent->color = __rb_tree_black; - y->color = __rb_tree_black; - x->parent->parent->color = __rb_tree_red; - x = x->parent->parent; + _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_left; + if (__y && __y->_M_color == _S_rb_tree_red) { + __x->_M_parent->_M_color = _S_rb_tree_black; + __y->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + __x = __x->_M_parent->_M_parent; } else { - if (x == x->parent->left) { - x = x->parent; - __rb_tree_rotate_right(x, root); + if (__x == __x->_M_parent->_M_left) { + __x = __x->_M_parent; + _Rb_tree_rotate_right(__x, __root); } - x->parent->color = __rb_tree_black; - x->parent->parent->color = __rb_tree_red; - __rb_tree_rotate_left(x->parent->parent, root); + __x->_M_parent->_M_color = _S_rb_tree_black; + __x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_left(__x->_M_parent->_M_parent, __root); } } } - root->color = __rb_tree_black; + __root->_M_color = _S_rb_tree_black; } -inline __rb_tree_node_base* -__rb_tree_rebalance_for_erase(__rb_tree_node_base* z, - __rb_tree_node_base*& root, - __rb_tree_node_base*& leftmost, - __rb_tree_node_base*& rightmost) +inline _Rb_tree_node_base* +_Rb_tree_rebalance_for_erase(_Rb_tree_node_base* __z, + _Rb_tree_node_base*& __root, + _Rb_tree_node_base*& __leftmost, + _Rb_tree_node_base*& __rightmost) { - __rb_tree_node_base* y = z; - __rb_tree_node_base* x = 0; - __rb_tree_node_base* x_parent = 0; - if (y->left == 0) // z has at most one non-null child. y == z. - x = y->right; // x might be null. + _Rb_tree_node_base* __y = __z; + _Rb_tree_node_base* __x = 0; + _Rb_tree_node_base* __x_parent = 0; + if (__y->_M_left == 0) // __z has at most one non-null child. y == z. + __x = __y->_M_right; // __x might be null. else - if (y->right == 0) // z has exactly one non-null child. y == z. - x = y->left; // x is not null. - else { // z has two non-null children. Set y to - y = y->right; // z's successor. x might be null. - while (y->left != 0) - y = y->left; - x = y->right; + if (__y->_M_right == 0) // __z has exactly one non-null child. y == z. + __x = __y->_M_left; // __x is not null. + else { // __z has two non-null children. Set __y to + __y = __y->_M_right; // __z's successor. __x might be null. + while (__y->_M_left != 0) + __y = __y->_M_left; + __x = __y->_M_right; } - if (y != z) { // relink y in place of z. y is z's successor - z->left->parent = y; - y->left = z->left; - if (y != z->right) { - x_parent = y->parent; - if (x) x->parent = y->parent; - y->parent->left = x; // y must be a left child - y->right = z->right; - z->right->parent = y; + if (__y != __z) { // relink y in place of z. y is z's successor + __z->_M_left->_M_parent = __y; + __y->_M_left = __z->_M_left; + if (__y != __z->_M_right) { + __x_parent = __y->_M_parent; + if (__x) __x->_M_parent = __y->_M_parent; + __y->_M_parent->_M_left = __x; // __y must be a child of _M_left + __y->_M_right = __z->_M_right; + __z->_M_right->_M_parent = __y; } else - x_parent = y; - if (root == z) - root = y; - else if (z->parent->left == z) - z->parent->left = y; + __x_parent = __y; + if (__root == __z) + __root = __y; + else if (__z->_M_parent->_M_left == __z) + __z->_M_parent->_M_left = __y; else - z->parent->right = y; - y->parent = z->parent; - __STD::swap(y->color, z->color); - y = z; - // y now points to node to be actually deleted + __z->_M_parent->_M_right = __y; + __y->_M_parent = __z->_M_parent; + __STD::swap(__y->_M_color, __z->_M_color); + __y = __z; + // __y now points to node to be actually deleted } - else { // y == z - x_parent = y->parent; - if (x) x->parent = y->parent; - if (root == z) - root = x; + else { // __y == __z + __x_parent = __y->_M_parent; + if (__x) __x->_M_parent = __y->_M_parent; + if (__root == __z) + __root = __x; else - if (z->parent->left == z) - z->parent->left = x; + if (__z->_M_parent->_M_left == __z) + __z->_M_parent->_M_left = __x; else - z->parent->right = x; - if (leftmost == z) - if (z->right == 0) // z->left must be null also - leftmost = z->parent; - // makes leftmost == header if z == root + __z->_M_parent->_M_right = __x; + if (__leftmost == __z) + if (__z->_M_right == 0) // __z->_M_left must be null also + __leftmost = __z->_M_parent; + // makes __leftmost == _M_header if __z == __root else - leftmost = __rb_tree_node_base::minimum(x); - if (rightmost == z) - if (z->left == 0) // z->right must be null also - rightmost = z->parent; - // makes rightmost == header if z == root - else // x == z->left - rightmost = __rb_tree_node_base::maximum(x); + __leftmost = _Rb_tree_node_base::_S_minimum(__x); + if (__rightmost == __z) + if (__z->_M_left == 0) // __z->_M_right must be null also + __rightmost = __z->_M_parent; + // makes __rightmost == _M_header if __z == __root + else // __x == __z->_M_left + __rightmost = _Rb_tree_node_base::_S_maximum(__x); } - if (y->color != __rb_tree_red) { - while (x != root && (x == 0 || x->color == __rb_tree_black)) - if (x == x_parent->left) { - __rb_tree_node_base* w = x_parent->right; - if (w->color == __rb_tree_red) { - w->color = __rb_tree_black; - x_parent->color = __rb_tree_red; - __rb_tree_rotate_left(x_parent, root); - w = x_parent->right; + if (__y->_M_color != _S_rb_tree_red) { + while (__x != __root && (__x == 0 || __x->_M_color == _S_rb_tree_black)) + if (__x == __x_parent->_M_left) { + _Rb_tree_node_base* __w = __x_parent->_M_right; + if (__w->_M_color == _S_rb_tree_red) { + __w->_M_color = _S_rb_tree_black; + __x_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_left(__x_parent, __root); + __w = __x_parent->_M_right; } - if ((w->left == 0 || w->left->color == __rb_tree_black) && - (w->right == 0 || w->right->color == __rb_tree_black)) { - w->color = __rb_tree_red; - x = x_parent; - x_parent = x_parent->parent; + if ((__w->_M_left == 0 || + __w->_M_left->_M_color == _S_rb_tree_black) && + (__w->_M_right == 0 || + __w->_M_right->_M_color == _S_rb_tree_black)) { + __w->_M_color = _S_rb_tree_red; + __x = __x_parent; + __x_parent = __x_parent->_M_parent; } else { - if (w->right == 0 || w->right->color == __rb_tree_black) { - if (w->left) w->left->color = __rb_tree_black; - w->color = __rb_tree_red; - __rb_tree_rotate_right(w, root); - w = x_parent->right; + if (__w->_M_right == 0 || + __w->_M_right->_M_color == _S_rb_tree_black) { + if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black; + __w->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_right(__w, __root); + __w = __x_parent->_M_right; } - w->color = x_parent->color; - x_parent->color = __rb_tree_black; - if (w->right) w->right->color = __rb_tree_black; - __rb_tree_rotate_left(x_parent, root); + __w->_M_color = __x_parent->_M_color; + __x_parent->_M_color = _S_rb_tree_black; + if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black; + _Rb_tree_rotate_left(__x_parent, __root); break; } - } else { // same as above, with right <-> left. - __rb_tree_node_base* w = x_parent->left; - if (w->color == __rb_tree_red) { - w->color = __rb_tree_black; - x_parent->color = __rb_tree_red; - __rb_tree_rotate_right(x_parent, root); - w = x_parent->left; + } else { // same as above, with _M_right <-> _M_left. + _Rb_tree_node_base* __w = __x_parent->_M_left; + if (__w->_M_color == _S_rb_tree_red) { + __w->_M_color = _S_rb_tree_black; + __x_parent->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_right(__x_parent, __root); + __w = __x_parent->_M_left; } - if ((w->right == 0 || w->right->color == __rb_tree_black) && - (w->left == 0 || w->left->color == __rb_tree_black)) { - w->color = __rb_tree_red; - x = x_parent; - x_parent = x_parent->parent; + if ((__w->_M_right == 0 || + __w->_M_right->_M_color == _S_rb_tree_black) && + (__w->_M_left == 0 || + __w->_M_left->_M_color == _S_rb_tree_black)) { + __w->_M_color = _S_rb_tree_red; + __x = __x_parent; + __x_parent = __x_parent->_M_parent; } else { - if (w->left == 0 || w->left->color == __rb_tree_black) { - if (w->right) w->right->color = __rb_tree_black; - w->color = __rb_tree_red; - __rb_tree_rotate_left(w, root); - w = x_parent->left; + if (__w->_M_left == 0 || + __w->_M_left->_M_color == _S_rb_tree_black) { + if (__w->_M_right) __w->_M_right->_M_color = _S_rb_tree_black; + __w->_M_color = _S_rb_tree_red; + _Rb_tree_rotate_left(__w, __root); + __w = __x_parent->_M_left; } - w->color = x_parent->color; - x_parent->color = __rb_tree_black; - if (w->left) w->left->color = __rb_tree_black; - __rb_tree_rotate_right(x_parent, root); + __w->_M_color = __x_parent->_M_color; + __x_parent->_M_color = _S_rb_tree_black; + if (__w->_M_left) __w->_M_left->_M_color = _S_rb_tree_black; + _Rb_tree_rotate_right(__x_parent, __root); break; } } - if (x) x->color = __rb_tree_black; + if (__x) __x->_M_color = _S_rb_tree_black; } - return y; + return __y; } -template -class rb_tree { +// Base class to encapsulate the differences between old SGI-style +// allocators and standard-conforming allocators. In order to avoid +// having an empty base class, we arbitrarily move one of rb_tree's +// data members into the base class. + +#ifdef __STL_USE_STD_ALLOCATORS + +// _Base for general standard-conforming allocators. +template +class _Rb_tree_alloc_base { +public: + typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } + + _Rb_tree_alloc_base(const allocator_type& __a) + : _M_node_allocator(__a), _M_header(0) {} + protected: - typedef void* void_pointer; - typedef __rb_tree_node_base* base_ptr; - typedef __rb_tree_node rb_tree_node; - typedef simple_alloc rb_tree_node_allocator; - typedef __rb_tree_color_type color_type; + typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::allocator_type + _M_node_allocator; + _Rb_tree_node<_Tp>* _M_header; + + _Rb_tree_node<_Tp>* _M_get_node() + { return _M_node_allocator.allocate(1); } + void _M_put_node(_Rb_tree_node<_Tp>* __p) + { _M_node_allocator.deallocate(__p, 1); } +}; + +// Specialization for instanceless allocators. +template +class _Rb_tree_alloc_base<_Tp, _Alloc, true> { public: - typedef Key key_type; - typedef Value value_type; + typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Rb_tree_alloc_base(const allocator_type&) : _M_header(0) {} + +protected: + _Rb_tree_node<_Tp>* _M_header; + + typedef typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::_Alloc_type + _Alloc_type; + + _Rb_tree_node<_Tp>* _M_get_node() + { return _Alloc_type::allocate(1); } + void _M_put_node(_Rb_tree_node<_Tp>* __p) + { _Alloc_type::deallocate(__p, 1); } +}; + +template +struct _Rb_tree_base + : public _Rb_tree_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ + typedef _Rb_tree_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _Rb_tree_base(const allocator_type& __a) + : _Base(__a) { _M_header = _M_get_node(); } + ~_Rb_tree_base() { _M_put_node(_M_header); } + +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +struct _Rb_tree_base +{ + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Rb_tree_base(const allocator_type&) + : _M_header(0) { _M_header = _M_get_node(); } + ~_Rb_tree_base() { _M_put_node(_M_header); } + +protected: + _Rb_tree_node<_Tp>* _M_header; + + typedef simple_alloc<_Rb_tree_node<_Tp>, _Alloc> _Alloc_type; + + _Rb_tree_node<_Tp>* _M_get_node() + { return _Alloc_type::allocate(1); } + void _M_put_node(_Rb_tree_node<_Tp>* __p) + { _Alloc_type::deallocate(__p, 1); } +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template +class _Rb_tree : protected _Rb_tree_base<_Value, _Alloc> { + typedef _Rb_tree_base<_Value, _Alloc> _Base; +protected: + typedef _Rb_tree_node_base* _Base_ptr; + typedef _Rb_tree_node<_Value> _Rb_tree_node; + typedef _Rb_tree_Color_type _Color_type; +public: + typedef _Key key_type; + typedef _Value value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; - typedef rb_tree_node* link_type; + typedef _Rb_tree_node* _Link_type; typedef size_t size_type; typedef ptrdiff_t difference_type; + + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + +protected: +#ifdef __STL_USE_NAMESPACES + using _Base::_M_get_node; + using _Base::_M_put_node; + using _Base::_M_header; +#endif /* __STL_USE_NAMESPACES */ + protected: - link_type get_node() { return rb_tree_node_allocator::allocate(); } - void put_node(link_type p) { rb_tree_node_allocator::deallocate(p); } - link_type create_node(const value_type& x) { - link_type tmp = get_node(); + _Link_type _M_create_node(const value_type& __x) + { + _Link_type __tmp = _M_get_node(); __STL_TRY { - construct(&tmp->value_field, x); + construct(&__tmp->_M_value_field, __x); } - __STL_UNWIND(put_node(tmp)); - return tmp; + __STL_UNWIND(_M_put_node(__tmp)); + return __tmp; } - link_type clone_node(link_type x) { - link_type tmp = create_node(x->value_field); - tmp->color = x->color; - tmp->left = 0; - tmp->right = 0; - return tmp; + _Link_type _M_clone_node(_Link_type __x) + { + _Link_type __tmp = _M_create_node(__x->_M_value_field); + __tmp->_M_color = __x->_M_color; + __tmp->_M_left = 0; + __tmp->_M_right = 0; + return __tmp; } - void destroy_node(link_type p) { - destroy(&p->value_field); - put_node(p); + void destroy_node(_Link_type __p) + { + destroy(&__p->_M_value_field); + _M_put_node(__p); } protected: - size_type node_count; // keeps track of size of tree - link_type header; - Compare key_compare; - - link_type& root() const { return (link_type&) header->parent; } - link_type& leftmost() const { return (link_type&) header->left; } - link_type& rightmost() const { return (link_type&) header->right; } - - static link_type& left(link_type x) { return (link_type&)(x->left); } - static link_type& right(link_type x) { return (link_type&)(x->right); } - static link_type& parent(link_type x) { return (link_type&)(x->parent); } - static reference value(link_type x) { return x->value_field; } - static const Key& key(link_type x) { return KeyOfValue()(value(x)); } - static color_type& color(link_type x) { return (color_type&)(x->color); } - - static link_type& left(base_ptr x) { return (link_type&)(x->left); } - static link_type& right(base_ptr x) { return (link_type&)(x->right); } - static link_type& parent(base_ptr x) { return (link_type&)(x->parent); } - static reference value(base_ptr x) { return ((link_type)x)->value_field; } - static const Key& key(base_ptr x) { return KeyOfValue()(value(link_type(x)));} - static color_type& color(base_ptr x) { return (color_type&)(link_type(x)->color); } - - static link_type minimum(link_type x) { - return (link_type) __rb_tree_node_base::minimum(x); - } - static link_type maximum(link_type x) { - return (link_type) __rb_tree_node_base::maximum(x); - } + size_type _M_node_count; // keeps track of size of tree + _Compare _M_key_compare; + + _Link_type& _M_root() const + { return (_Link_type&) _M_header->_M_parent; } + _Link_type& _M_leftmost() const + { return (_Link_type&) _M_header->_M_left; } + _Link_type& _M_rightmost() const + { return (_Link_type&) _M_header->_M_right; } + + static _Link_type& _S_left(_Link_type __x) + { return (_Link_type&)(__x->_M_left); } + static _Link_type& _S_right(_Link_type __x) + { return (_Link_type&)(__x->_M_right); } + static _Link_type& _S_parent(_Link_type __x) + { return (_Link_type&)(__x->_M_parent); } + static reference _S_value(_Link_type __x) + { return __x->_M_value_field; } + static const _Key& _S_key(_Link_type __x) + { return _KeyOfValue()(_S_value(__x)); } + static _Color_type& _S_color(_Link_type __x) + { return (_Color_type&)(__x->_M_color); } + + static _Link_type& _S_left(_Base_ptr __x) + { return (_Link_type&)(__x->_M_left); } + static _Link_type& _S_right(_Base_ptr __x) + { return (_Link_type&)(__x->_M_right); } + static _Link_type& _S_parent(_Base_ptr __x) + { return (_Link_type&)(__x->_M_parent); } + static reference _S_value(_Base_ptr __x) + { return ((_Link_type)__x)->_M_value_field; } + static const _Key& _S_key(_Base_ptr __x) + { return _KeyOfValue()(_S_value(_Link_type(__x)));} + static _Color_type& _S_color(_Base_ptr __x) + { return (_Color_type&)(_Link_type(__x)->_M_color); } + + static _Link_type _S_minimum(_Link_type __x) + { return (_Link_type) _Rb_tree_node_base::_S_minimum(__x); } + + static _Link_type _S_maximum(_Link_type __x) + { return (_Link_type) _Rb_tree_node_base::_S_maximum(__x); } public: - typedef __rb_tree_iterator iterator; - typedef __rb_tree_iterator + typedef _Rb_tree_iterator iterator; + typedef _Rb_tree_iterator const_iterator; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION @@ -506,57 +633,60 @@ public: const_reference, difference_type> const_reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + private: - iterator __insert(base_ptr x, base_ptr y, const value_type& v); - link_type __copy(link_type x, link_type p); - void __erase(link_type x); - void init() { - header = get_node(); - color(header) = __rb_tree_red; // used to distinguish header from - // root, in iterator.operator++ - root() = 0; - leftmost() = header; - rightmost() = header; - } + iterator _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v); + _Link_type _M_copy(_Link_type __x, _Link_type __p); + void _M_erase(_Link_type __x); + public: // allocation/deallocation - rb_tree(const Compare& comp = Compare()) - : node_count(0), key_compare(comp) { init(); } + _Rb_tree() + : _Base(allocator_type()), _M_node_count(0), _M_key_compare() + { _M_empty_initialize(); } + + _Rb_tree(const _Compare& __comp) + : _Base(allocator_type()), _M_node_count(0), _M_key_compare(__comp) + { _M_empty_initialize(); } - rb_tree(const rb_tree& x) - : node_count(0), key_compare(x.key_compare) + _Rb_tree(const _Compare& __comp, const allocator_type& __a) + : _Base(__a), _M_node_count(0), _M_key_compare(__comp) + { _M_empty_initialize(); } + + _Rb_tree(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x) + : _Base(__x.get_allocator()), + _M_node_count(0), _M_key_compare(__x._M_key_compare) { - header = get_node(); - color(header) = __rb_tree_red; - if (x.root() == 0) { - root() = 0; - leftmost() = header; - rightmost() = header; - } + if (__x._M_root() == 0) + _M_empty_initialize(); else { - __STL_TRY { - root() = __copy(x.root(), header); - } - __STL_UNWIND(put_node(header)); - leftmost() = minimum(root()); - rightmost() = maximum(root()); + _S_color(_M_header) = _S_rb_tree_red; + _M_root() = _M_copy(__x._M_root(), _M_header); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); } - node_count = x.node_count; + _M_node_count = __x._M_node_count; } - ~rb_tree() { - clear(); - put_node(header); + ~_Rb_tree() { clear(); } + _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& + operator=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x); + +private: + void _M_empty_initialize() { + _S_color(_M_header) = _S_rb_tree_red; // used to distinguish header from + // __root, in iterator.operator++ + _M_root() = 0; + _M_leftmost() = _M_header; + _M_rightmost() = _M_header; } - rb_tree& - operator=(const rb_tree& x); public: // accessors: - Compare key_comp() const { return key_compare; } - iterator begin() { return leftmost(); } - const_iterator begin() const { return leftmost(); } - iterator end() { return header; } - const_iterator end() const { return header; } + _Compare key_comp() const { return _M_key_compare; } + iterator begin() { return _M_leftmost(); } + const_iterator begin() const { return _M_leftmost(); } + iterator end() { return _M_header; } + const_iterator end() const { return _M_header; } reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); @@ -565,531 +695,635 @@ public: const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } - bool empty() const { return node_count == 0; } - size_type size() const { return node_count; } + bool empty() const { return _M_node_count == 0; } + size_type size() const { return _M_node_count; } size_type max_size() const { return size_type(-1); } - void swap(rb_tree& t) { - __STD::swap(header, t.header); - __STD::swap(node_count, t.node_count); - __STD::swap(key_compare, t.key_compare); + void swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __t) { + __STD::swap(_M_header, __t._M_header); + __STD::swap(_M_node_count, __t._M_node_count); + __STD::swap(_M_key_compare, __t._M_key_compare); } public: // insert/erase - pair insert_unique(const value_type& x); - iterator insert_equal(const value_type& x); + pair insert_unique(const value_type& __x); + iterator insert_equal(const value_type& __x); - iterator insert_unique(iterator position, const value_type& x); - iterator insert_equal(iterator position, const value_type& x); + iterator insert_unique(iterator __position, const value_type& __x); + iterator insert_equal(iterator __position, const value_type& __x); #ifdef __STL_MEMBER_TEMPLATES - template - void insert_unique(InputIterator first, InputIterator last); - template - void insert_equal(InputIterator first, InputIterator last); + template + void insert_unique(_InputIterator __first, _InputIterator __last); + template + void insert_equal(_InputIterator __first, _InputIterator __last); #else /* __STL_MEMBER_TEMPLATES */ - void insert_unique(const_iterator first, const_iterator last); - void insert_unique(const value_type* first, const value_type* last); - void insert_equal(const_iterator first, const_iterator last); - void insert_equal(const value_type* first, const value_type* last); + void insert_unique(const_iterator __first, const_iterator __last); + void insert_unique(const value_type* __first, const value_type* __last); + void insert_equal(const_iterator __first, const_iterator __last); + void insert_equal(const value_type* __first, const value_type* __last); #endif /* __STL_MEMBER_TEMPLATES */ - void erase(iterator position); - size_type erase(const key_type& x); - void erase(iterator first, iterator last); - void erase(const key_type* first, const key_type* last); + void erase(iterator __position); + size_type erase(const key_type& __x); + void erase(iterator __first, iterator __last); + void erase(const key_type* __first, const key_type* __last); void clear() { - if (node_count != 0) { - __erase(root()); - leftmost() = header; - root() = 0; - rightmost() = header; - node_count = 0; + if (_M_node_count != 0) { + _M_erase(_M_root()); + _M_leftmost() = _M_header; + _M_root() = 0; + _M_rightmost() = _M_header; + _M_node_count = 0; } } public: // set operations: - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - size_type count(const key_type& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - pair equal_range(const key_type& x); - pair equal_range(const key_type& x) const; + iterator find(const key_type& __x); + const_iterator find(const key_type& __x) const; + size_type count(const key_type& __x) const; + iterator lower_bound(const key_type& __x); + const_iterator lower_bound(const key_type& __x) const; + iterator upper_bound(const key_type& __x); + const_iterator upper_bound(const key_type& __x) const; + pair equal_range(const key_type& __x); + pair equal_range(const key_type& __x) const; public: // Debugging. bool __rb_verify() const; }; -template -inline bool operator==(const rb_tree& x, - const rb_tree& y) { - return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); +template +inline bool +operator==(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) +{ + return __x.size() == __y.size() && + equal(__x.begin(), __x.end(), __y.begin()); } -template -inline bool operator<(const rb_tree& x, - const rb_tree& y) { - return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); +template +inline bool +operator<(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, + const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template -inline void swap(rb_tree& x, - rb_tree& y) { - x.swap(y); +template +inline void +swap(_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x, + _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __y) +{ + __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ -template -rb_tree& -rb_tree:: -operator=(const rb_tree& x) { - if (this != &x) { - // Note that Key may be a constant type. +template +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::operator=(const _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>& __x) +{ + if (this != &__x) { + // Note that _Key may be a constant type. clear(); - node_count = 0; - key_compare = x.key_compare; - if (x.root() == 0) { - root() = 0; - leftmost() = header; - rightmost() = header; + _M_node_count = 0; + _M_key_compare = __x._M_key_compare; + if (__x._M_root() == 0) { + _M_root() = 0; + _M_leftmost() = _M_header; + _M_rightmost() = _M_header; } else { - root() = __copy(x.root(), header); - leftmost() = minimum(root()); - rightmost() = maximum(root()); - node_count = x.node_count; + _M_root() = _M_copy(__x._M_root(), _M_header); + _M_leftmost() = _S_minimum(_M_root()); + _M_rightmost() = _S_maximum(_M_root()); + _M_node_count = __x._M_node_count; } } return *this; } -template -typename rb_tree::iterator -rb_tree:: -__insert(base_ptr x_, base_ptr y_, const Value& v) { - link_type x = (link_type) x_; - link_type y = (link_type) y_; - link_type z; - - if (y == header || x != 0 || key_compare(KeyOfValue()(v), key(y))) { - z = create_node(v); - left(y) = z; // also makes leftmost() = z when y == header - if (y == header) { - root() = z; - rightmost() = z; +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::_M_insert(_Base_ptr __x_, _Base_ptr __y_, const _Value& __v) +{ + _Link_type __x = (_Link_type) __x_; + _Link_type __y = (_Link_type) __y_; + _Link_type __z; + + if (__y == _M_header || __x != 0 || + _M_key_compare(_KeyOfValue()(__v), _S_key(__y))) { + __z = _M_create_node(__v); + _S_left(__y) = __z; // also makes _M_leftmost() = __z + // when __y == _M_header + if (__y == _M_header) { + _M_root() = __z; + _M_rightmost() = __z; } - else if (y == leftmost()) - leftmost() = z; // maintain leftmost() pointing to min node + else if (__y == _M_leftmost()) + _M_leftmost() = __z; // maintain _M_leftmost() pointing to min node } else { - z = create_node(v); - right(y) = z; - if (y == rightmost()) - rightmost() = z; // maintain rightmost() pointing to max node + __z = _M_create_node(__v); + _S_right(__y) = __z; + if (__y == _M_rightmost()) + _M_rightmost() = __z; // maintain _M_rightmost() pointing to max node } - parent(z) = y; - left(z) = 0; - right(z) = 0; - __rb_tree_rebalance(z, header->parent); - ++node_count; - return iterator(z); + _S_parent(__z) = __y; + _S_left(__z) = 0; + _S_right(__z) = 0; + _Rb_tree_rebalance(__z, _M_header->_M_parent); + ++_M_node_count; + return iterator(__z); } -template -typename rb_tree::iterator -rb_tree::insert_equal(const Value& v) +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::insert_equal(const _Value& __v) { - link_type y = header; - link_type x = root(); - while (x != 0) { - y = x; - x = key_compare(KeyOfValue()(v), key(x)) ? left(x) : right(x); + _Link_type __y = _M_header; + _Link_type __x = _M_root(); + while (__x != 0) { + __y = __x; + __x = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ? + _S_left(__x) : _S_right(__x); } - return __insert(x, y, v); + return _M_insert(__x, __y, __v); } -template -pair::iterator, bool> -rb_tree::insert_unique(const Value& v) +template +pair::iterator, + bool> +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::insert_unique(const _Value& __v) { - link_type y = header; - link_type x = root(); - bool comp = true; - while (x != 0) { - y = x; - comp = key_compare(KeyOfValue()(v), key(x)); - x = comp ? left(x) : right(x); + _Link_type __y = _M_header; + _Link_type __x = _M_root(); + bool __comp = true; + while (__x != 0) { + __y = __x; + __comp = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)); + __x = __comp ? _S_left(__x) : _S_right(__x); } - iterator j = iterator(y); - if (comp) - if (j == begin()) - return pair(__insert(x, y, v), true); + iterator __j = iterator(__y); + if (__comp) + if (__j == begin()) + return pair(_M_insert(__x, __y, __v), true); else - --j; - if (key_compare(key(j.node), KeyOfValue()(v))) - return pair(__insert(x, y, v), true); - return pair(j, false); + --__j; + if (_M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) + return pair(_M_insert(__x, __y, __v), true); + return pair(__j, false); } -template -typename rb_tree::iterator -rb_tree::insert_unique(iterator position, - const Val& v) { - if (position.node == header->left) // begin() - if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node))) - return __insert(position.node, position.node, v); - // first argument just needs to be non-null +template +typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator +_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc> + ::insert_unique(iterator __position, const _Val& __v) +{ + if (__position._M_node == _M_header->_M_left) { // begin() + if (size() > 0 && + _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null else - return insert_unique(v).first; - else if (position.node == header) // end() - if (key_compare(key(rightmost()), KeyOfValue()(v))) - return __insert(0, rightmost(), v); + return insert_unique(__v).first; + } else if (__position._M_node == _M_header) { // end() + if (_M_key_compare(_S_key(_M_rightmost()), _KeyOfValue()(__v))) + return _M_insert(0, _M_rightmost(), __v); else - return insert_unique(v).first; - else { - iterator before = position; - --before; - if (key_compare(key(before.node), KeyOfValue()(v)) - && key_compare(KeyOfValue()(v), key(position.node))) - if (right(before.node) == 0) - return __insert(0, before.node, v); + return insert_unique(__v).first; + } else { + iterator __before = __position; + --__before; + if (_M_key_compare(_S_key(__before._M_node), _KeyOfValue()(__v)) + && _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); else - return __insert(position.node, position.node, v); + return _M_insert(__position._M_node, __position._M_node, __v); // first argument just needs to be non-null - else - return insert_unique(v).first; + } else + return insert_unique(__v).first; } } -template -typename rb_tree::iterator -rb_tree::insert_equal(iterator position, - const Val& v) { - if (position.node == header->left) // begin() - if (size() > 0 && key_compare(KeyOfValue()(v), key(position.node))) - return __insert(position.node, position.node, v); - // first argument just needs to be non-null +template +typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc> + ::insert_equal(iterator __position, const _Val& __v) +{ + if (__position._M_node == _M_header->_M_left) { // begin() + if (size() > 0 && + _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null else - return insert_equal(v); - else if (position.node == header) // end() - if (!key_compare(KeyOfValue()(v), key(rightmost()))) - return __insert(0, rightmost(), v); + return insert_equal(__v); + } else if (__position._M_node == _M_header) {// end() + if (!_M_key_compare(_KeyOfValue()(__v), _S_key(_M_rightmost()))) + return _M_insert(0, _M_rightmost(), __v); else - return insert_equal(v); - else { - iterator before = position; - --before; - if (!key_compare(KeyOfValue()(v), key(before.node)) - && !key_compare(key(position.node), KeyOfValue()(v))) - if (right(before.node) == 0) - return __insert(0, before.node, v); + return insert_equal(__v); + } else { + iterator __before = __position; + --__before; + if (!_M_key_compare(_KeyOfValue()(__v), _S_key(__before._M_node)) + && !_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__v))) { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); else - return __insert(position.node, position.node, v); + return _M_insert(__position._M_node, __position._M_node, __v); // first argument just needs to be non-null - else - return insert_equal(v); + } else + return insert_equal(__v); } } #ifdef __STL_MEMBER_TEMPLATES -template template -void rb_tree::insert_equal(II first, II last) { - for ( ; first != last; ++first) - insert_equal(*first); +template + template +void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_equal(_II __first, _II __last) +{ + for ( ; __first != __last; ++__first) + insert_equal(*__first); } -template template -void rb_tree::insert_unique(II first, II last) { - for ( ; first != last; ++first) - insert_unique(*first); +template + template +void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_unique(_II __first, _II __last) { + for ( ; __first != __last; ++__first) + insert_unique(*__first); } #else /* __STL_MEMBER_TEMPLATES */ -template +template void -rb_tree::insert_equal(const V* first, const V* last) { - for ( ; first != last; ++first) - insert_equal(*first); +_Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_equal(const _Val* __first, const _Val* __last) +{ + for ( ; __first != __last; ++__first) + insert_equal(*__first); } -template +template void -rb_tree::insert_equal(const_iterator first, - const_iterator last) { - for ( ; first != last; ++first) - insert_equal(*first); +_Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_equal(const_iterator __first, const_iterator __last) +{ + for ( ; __first != __last; ++__first) + insert_equal(*__first); } -template +template void -rb_tree::insert_unique(const V* first, const V* last) { - for ( ; first != last; ++first) - insert_unique(*first); +_Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_unique(const _Val* __first, const _Val* __last) +{ + for ( ; __first != __last; ++__first) + insert_unique(*__first); } -template -void -rb_tree::insert_unique(const_iterator first, - const_iterator last) { - for ( ; first != last; ++first) - insert_unique(*first); +template +void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc> + ::insert_unique(const_iterator __first, const_iterator __last) +{ + for ( ; __first != __last; ++__first) + insert_unique(*__first); } #endif /* __STL_MEMBER_TEMPLATES */ -template -inline void -rb_tree::erase(iterator position) { - link_type y = (link_type) __rb_tree_rebalance_for_erase(position.node, - header->parent, - header->left, - header->right); - destroy_node(y); - --node_count; +template +inline void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::erase(iterator __position) +{ + _Link_type __y = + (_Link_type) _Rb_tree_rebalance_for_erase(__position._M_node, + _M_header->_M_parent, + _M_header->_M_left, + _M_header->_M_right); + destroy_node(__y); + --_M_node_count; } -template -typename rb_tree::size_type -rb_tree::erase(const Key& x) { - pair p = equal_range(x); - size_type n = 0; - distance(p.first, p.second, n); - erase(p.first, p.second); - return n; +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::erase(const _Key& __x) +{ + pair __p = equal_range(__x); + size_type __n = 0; + distance(__p.first, __p.second, __n); + erase(__p.first, __p.second); + return __n; } -template -typename rb_tree::link_type -rb_tree::__copy(link_type x, link_type p) { - // structural copy. x and p must be non-null. - link_type top = clone_node(x); - top->parent = p; +template +typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type +_Rb_tree<_Key,_Val,_KoV,_Compare,_Alloc> + ::_M_copy(_Link_type __x, _Link_type __p) +{ + // structural copy. __x and __p must be non-null. + _Link_type __top = _M_clone_node(__x); + __top->_M_parent = __p; __STL_TRY { - if (x->right) - top->right = __copy(right(x), top); - p = top; - x = left(x); - - while (x != 0) { - link_type y = clone_node(x); - p->left = y; - y->parent = p; - if (x->right) - y->right = __copy(right(x), y); - p = y; - x = left(x); + if (__x->_M_right) + __top->_M_right = _M_copy(_S_right(__x), __top); + __p = __top; + __x = _S_left(__x); + + while (__x != 0) { + _Link_type __y = _M_clone_node(__x); + __p->_M_left = __y; + __y->_M_parent = __p; + if (__x->_M_right) + __y->_M_right = _M_copy(_S_right(__x), __y); + __p = __y; + __x = _S_left(__x); } } - __STL_UNWIND(__erase(top)); + __STL_UNWIND(_M_erase(__top)); - return top; + return __top; } -template -void rb_tree::__erase(link_type x) { +template +void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::_M_erase(_Link_type __x) +{ // erase without rebalancing - while (x != 0) { - __erase(right(x)); - link_type y = left(x); - destroy_node(x); - x = y; + while (__x != 0) { + _M_erase(_S_right(__x)); + _Link_type __y = _S_left(__x); + destroy_node(__x); + __x = __y; } } -template -void rb_tree::erase(iterator first, - iterator last) { - if (first == begin() && last == end()) +template +void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::erase(iterator __first, iterator __last) +{ + if (__first == begin() && __last == end()) clear(); else - while (first != last) erase(first++); + while (__first != __last) erase(__first++); } -template -void rb_tree::erase(const Key* first, - const Key* last) { - while (first != last) erase(*first++); +template +void _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::erase(const _Key* __first, const _Key* __last) +{ + while (__first != __last) erase(*__first++); } -template -typename rb_tree::iterator -rb_tree::find(const Key& k) { - link_type y = header; // Last node which is not less than k. - link_type x = root(); // Current node. +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) +{ + _Link_type __y = _M_header; // Last node which is not less than __k. + _Link_type __x = _M_root(); // Current node. - while (x != 0) - if (!key_compare(key(x), k)) - y = x, x = left(x); + while (__x != 0) + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); else - x = right(x); + __x = _S_right(__x); - iterator j = iterator(y); - return (j == end() || key_compare(k, key(j.node))) ? end() : j; + iterator __j = iterator(__y); + return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? + end() : __j; } -template -typename rb_tree::const_iterator -rb_tree::find(const Key& k) const { - link_type y = header; /* Last node which is not less than k. */ - link_type x = root(); /* Current node. */ +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) const +{ + _Link_type __y = _M_header; /* Last node which is not less than __k. */ + _Link_type __x = _M_root(); /* Current node. */ - while (x != 0) { - if (!key_compare(key(x), k)) - y = x, x = left(x); + while (__x != 0) { + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); else - x = right(x); + __x = _S_right(__x); } - const_iterator j = const_iterator(y); - return (j == end() || key_compare(k, key(j.node))) ? end() : j; + const_iterator __j = const_iterator(__y); + return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? + end() : __j; } -template -typename rb_tree::size_type -rb_tree::count(const Key& k) const { - pair p = equal_range(k); - size_type n = 0; - distance(p.first, p.second, n); - return n; +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::size_type +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::count(const _Key& __k) const +{ + pair __p = equal_range(__k); + size_type __n = 0; + distance(__p.first, __p.second, __n); + return __n; } -template -typename rb_tree::iterator -rb_tree::lower_bound(const Key& k) { - link_type y = header; /* Last node which is not less than k. */ - link_type x = root(); /* Current node. */ +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::lower_bound(const _Key& __k) +{ + _Link_type __y = _M_header; /* Last node which is not less than __k. */ + _Link_type __x = _M_root(); /* Current node. */ - while (x != 0) - if (!key_compare(key(x), k)) - y = x, x = left(x); + while (__x != 0) + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); else - x = right(x); + __x = _S_right(__x); - return iterator(y); + return iterator(__y); } -template -typename rb_tree::const_iterator -rb_tree::lower_bound(const Key& k) const { - link_type y = header; /* Last node which is not less than k. */ - link_type x = root(); /* Current node. */ +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::lower_bound(const _Key& __k) const +{ + _Link_type __y = _M_header; /* Last node which is not less than __k. */ + _Link_type __x = _M_root(); /* Current node. */ - while (x != 0) - if (!key_compare(key(x), k)) - y = x, x = left(x); + while (__x != 0) + if (!_M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); else - x = right(x); + __x = _S_right(__x); - return const_iterator(y); + return const_iterator(__y); } -template -typename rb_tree::iterator -rb_tree::upper_bound(const Key& k) { - link_type y = header; /* Last node which is greater than k. */ - link_type x = root(); /* Current node. */ +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::upper_bound(const _Key& __k) +{ + _Link_type __y = _M_header; /* Last node which is greater than __k. */ + _Link_type __x = _M_root(); /* Current node. */ - while (x != 0) - if (key_compare(k, key(x))) - y = x, x = left(x); + while (__x != 0) + if (_M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); else - x = right(x); + __x = _S_right(__x); - return iterator(y); + return iterator(__y); } -template -typename rb_tree::const_iterator -rb_tree::upper_bound(const Key& k) const { - link_type y = header; /* Last node which is greater than k. */ - link_type x = root(); /* Current node. */ +template +typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::const_iterator +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::upper_bound(const _Key& __k) const +{ + _Link_type __y = _M_header; /* Last node which is greater than __k. */ + _Link_type __x = _M_root(); /* Current node. */ - while (x != 0) - if (key_compare(k, key(x))) - y = x, x = left(x); + while (__x != 0) + if (_M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); else - x = right(x); + __x = _S_right(__x); - return const_iterator(y); + return const_iterator(__y); } -template -inline pair::iterator, - typename rb_tree::iterator> -rb_tree::equal_range(const Key& k) { - return pair(lower_bound(k), upper_bound(k)); +template +inline +pair::iterator, + typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator> +_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc> + ::equal_range(const _Key& __k) +{ + return pair(lower_bound(__k), upper_bound(__k)); } -template -inline pair::const_iterator, - typename rb_tree::const_iterator> -rb_tree::equal_range(const Key& k) const { - return pair(lower_bound(k), upper_bound(k)); +template +inline +pair::const_iterator, + typename _Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc>::const_iterator> +_Rb_tree<_Key, _Value, _KoV, _Compare, _Alloc> + ::equal_range(const _Key& __k) const +{ + return pair(lower_bound(__k), + upper_bound(__k)); } -inline int __black_count(__rb_tree_node_base* node, __rb_tree_node_base* root) +inline int +__black_count(_Rb_tree_node_base* __node, _Rb_tree_node_base* __root) { - if (node == 0) + if (__node == 0) return 0; else { - int bc = node->color == __rb_tree_black ? 1 : 0; - if (node == root) - return bc; + int __bc = __node->_M_color == _S_rb_tree_black ? 1 : 0; + if (__node == __root) + return __bc; else - return bc + __black_count(node->parent, root); + return __bc + __black_count(__node->_M_parent, __root); } } -template -bool -rb_tree::__rb_verify() const +template +bool _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const { - if (node_count == 0 || begin() == end()) - return node_count == 0 && begin() == end() && - header->left == header && header->right == header; + if (_M_node_count == 0 || begin() == end()) + return _M_node_count == 0 && begin() == end() && + _M_header->_M_left == _M_header && _M_header->_M_right == _M_header; - int len = __black_count(leftmost(), root()); - for (const_iterator it = begin(); it != end(); ++it) { - link_type x = (link_type) it.node; - link_type L = left(x); - link_type R = right(x); - - if (x->color == __rb_tree_red) - if ((L && L->color == __rb_tree_red) || - (R && R->color == __rb_tree_red)) + int __len = __black_count(_M_leftmost(), _M_root()); + for (const_iterator __it = begin(); __it != end(); ++__it) { + _Link_type __x = (_Link_type) __it._M_node; + _Link_type __L = _S_left(__x); + _Link_type __R = _S_right(__x); + + if (__x->_M_color == _S_rb_tree_red) + if ((__L && __L->_M_color == _S_rb_tree_red) || + (__R && __R->_M_color == _S_rb_tree_red)) return false; - if (L && key_compare(key(x), key(L))) + if (__L && _M_key_compare(_S_key(__x), _S_key(__L))) return false; - if (R && key_compare(key(R), key(x))) + if (__R && _M_key_compare(_S_key(__R), _S_key(__x))) return false; - if (!L && !R && __black_count(x, root()) != len) + if (!__L && !__R && __black_count(__x, _M_root()) != __len) return false; } - if (leftmost() != __rb_tree_node_base::minimum(root())) + if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root())) return false; - if (rightmost() != __rb_tree_node_base::maximum(root())) + if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root())) return false; return true; } +// Class rb_tree is not part of the C++ standard. It is provided for +// compatibility with the HP STL. + +template +struct rb_tree : public _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> +{ + typedef _Rb_tree<_Key, _Value, _KeyOfValue, _Compare, _Alloc> _Base; + typedef typename _Base::allocator_type allocator_type; + + rb_tree(const _Compare& __comp = _Compare(), + const allocator_type& __a = allocator_type()) + : _Base(__comp, __a) {} + + ~rb_tree() {} +}; + +#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) +#pragma reset woff 1375 +#endif + __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_TREE_H */ diff --git a/libstdc++/stl/stl_uninitialized.h b/libstdc++/stl/stl_uninitialized.h index 661bbe998e4..3146c82a71c 100644 --- a/libstdc++/stl/stl_uninitialized.h +++ b/libstdc++/stl/stl_uninitialized.h @@ -33,204 +33,241 @@ __STL_BEGIN_NAMESPACE +// uninitialized_copy + // Valid if copy construction is equivalent to assignment, and if the // destructor is trivial. -template -inline ForwardIterator -__uninitialized_copy_aux(InputIterator first, InputIterator last, - ForwardIterator result, - __true_type) { - return copy(first, last, result); -} - -template -ForwardIterator -__uninitialized_copy_aux(InputIterator first, InputIterator last, - ForwardIterator result, - __false_type) { - ForwardIterator cur = result; +template +inline _ForwardIter +__uninitialized_copy_aux(_InputIter __first, _InputIter __last, + _ForwardIter __result, + __true_type) +{ + return copy(__first, __last, __result); +} + +template +_ForwardIter +__uninitialized_copy_aux(_InputIter __first, _InputIter __last, + _ForwardIter __result, + __false_type) +{ + _ForwardIter __cur = __result; __STL_TRY { - for ( ; first != last; ++first, ++cur) - construct(&*cur, *first); - return cur; + for ( ; __first != __last; ++__first, ++__cur) + construct(&*__cur, *__first); + return __cur; } - __STL_UNWIND(destroy(result, cur)); + __STL_UNWIND(destroy(__result, __cur)); } -template -inline ForwardIterator -__uninitialized_copy(InputIterator first, InputIterator last, - ForwardIterator result, T*) { - typedef typename __type_traits::is_POD_type is_POD; - return __uninitialized_copy_aux(first, last, result, is_POD()); +template +inline _ForwardIter +__uninitialized_copy(_InputIter __first, _InputIter __last, + _ForwardIter __result, _Tp*) +{ + typedef typename __type_traits<_Tp>::is_POD_type _Is_POD; + return __uninitialized_copy_aux(__first, __last, __result, _Is_POD()); } -template -inline ForwardIterator - uninitialized_copy(InputIterator first, InputIterator last, - ForwardIterator result) { - return __uninitialized_copy(first, last, result, value_type(result)); +template +inline _ForwardIter + uninitialized_copy(_InputIter __first, _InputIter __last, + _ForwardIter __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 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); +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 -pair -__uninitialized_copy_n(InputIterator first, Size count, - ForwardIterator result, - input_iterator_tag) { - ForwardIterator cur = result; +// uninitialized_copy_n (not part of the C++ standard) + +template +pair<_InputIter, _ForwardIter> +__uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result, + input_iterator_tag) +{ + _ForwardIter __cur = __result; __STL_TRY { - for ( ; count > 0 ; --count, ++first, ++cur) - construct(&*cur, *first); - return pair(first, cur); + for ( ; __count > 0 ; --__count, ++__first, ++__cur) + construct(&*__cur, *__first); + return pair<_InputIter, _ForwardIter>(__first, __cur); } - __STL_UNWIND(destroy(result, cur)); + __STL_UNWIND(destroy(__result, __cur)); } -template -inline pair -__uninitialized_copy_n(RandomAccessIterator first, Size count, - ForwardIterator result, +template +inline pair<_RandomAccessIter, _ForwardIter> +__uninitialized_copy_n(_RandomAccessIter __first, _Size __count, + _ForwardIter __result, random_access_iterator_tag) { - RandomAccessIterator last = first + count; - return make_pair(last, uninitialized_copy(first, last, result)); + _RandomAccessIter __last = __first + __count; + return pair<_RandomAccessIter, _ForwardIter>( + __last, + uninitialized_copy(__first, __last, __result)); } -template -inline pair -uninitialized_copy_n(InputIterator first, Size count, - ForwardIterator result) { - return __uninitialized_copy_n(first, count, result, - iterator_category(first)); +template +inline pair<_InputIter, _ForwardIter> +__uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __result) { + return __uninitialized_copy_n(__first, __count, __result, + __ITERATOR_CATEGORY(__first)); +} + +template +inline pair<_InputIter, _ForwardIter> +uninitialized_copy_n(_InputIter __first, _Size __count, + _ForwardIter __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 +// destructor is trivial. +template inline void -__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, - const T& x, __true_type) +__uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, + const _Tp& __x, __true_type) { - fill(first, last, x); + fill(__first, __last, __x); } -template +template void -__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last, - const T& x, __false_type) +__uninitialized_fill_aux(_ForwardIter __first, _ForwardIter __last, + const _Tp& __x, __false_type) { - ForwardIterator cur = first; + _ForwardIter __cur = __first; __STL_TRY { - for ( ; cur != last; ++cur) - construct(&*cur, x); + for ( ; __cur != __last; ++__cur) + construct(&*__cur, __x); } - __STL_UNWIND(destroy(first, cur)); + __STL_UNWIND(destroy(__first, __cur)); } -template -inline void __uninitialized_fill(ForwardIterator first, ForwardIterator last, - const T& x, T1*) { - typedef typename __type_traits::is_POD_type is_POD; - __uninitialized_fill_aux(first, last, x, is_POD()); +template +inline void __uninitialized_fill(_ForwardIter __first, + _ForwardIter __last, const _Tp& __x, _Tp1*) +{ + typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD; + __uninitialized_fill_aux(__first, __last, __x, _Is_POD()); } -template -inline void uninitialized_fill(ForwardIterator first, ForwardIterator last, - const T& x) { - __uninitialized_fill(first, last, x, value_type(first)); +template +inline void uninitialized_fill(_ForwardIter __first, + _ForwardIter __last, + const _Tp& __x) +{ + __uninitialized_fill(__first, __last, __x, __VALUE_TYPE(__first)); } // Valid if copy construction is equivalent to assignment, and if the // destructor is trivial. -template -inline ForwardIterator -__uninitialized_fill_n_aux(ForwardIterator first, Size n, - const T& x, __true_type) { - return fill_n(first, n, x); -} - -template -ForwardIterator -__uninitialized_fill_n_aux(ForwardIterator first, Size n, - const T& x, __false_type) { - ForwardIterator cur = first; +template +inline _ForwardIter +__uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, + const _Tp& __x, __true_type) +{ + return fill_n(__first, __n, __x); +} + +template +_ForwardIter +__uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, + const _Tp& __x, __false_type) +{ + _ForwardIter __cur = __first; __STL_TRY { - for ( ; n > 0; --n, ++cur) - construct(&*cur, x); - return cur; + for ( ; __n > 0; --__n, ++__cur) + construct(&*__cur, __x); + return __cur; } - __STL_UNWIND(destroy(first, cur)); + __STL_UNWIND(destroy(__first, __cur)); } -template -inline ForwardIterator __uninitialized_fill_n(ForwardIterator first, Size n, - const T& x, T1*) { - typedef typename __type_traits::is_POD_type is_POD; - return __uninitialized_fill_n_aux(first, n, x, is_POD()); - +template +inline _ForwardIter +__uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x, _Tp1*) +{ + typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD; + return __uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); } -template -inline ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, - const T& x) { - return __uninitialized_fill_n(first, n, x, value_type(first)); +template +inline _ForwardIter +uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x) +{ + return __uninitialized_fill_n(__first, __n, __x, __VALUE_TYPE(__first)); } +// Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, +// __uninitialized_fill_copy. + +// __uninitialized_copy_copy // Copies [first1, last1) into [result, result + (last1 - first1)), and // copies [first2, last2) into // [result, result + (last1 - first1) + (last2 - first2)). -template -inline ForwardIterator -__uninitialized_copy_copy(InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, - ForwardIterator result) { - ForwardIterator mid = uninitialized_copy(first1, last1, result); +template +inline _ForwardIter +__uninitialized_copy_copy(_InputIter1 __first1, _InputIter1 __last1, + _InputIter2 __first2, _InputIter2 __last2, + _ForwardIter __result) +{ + _ForwardIter __mid = uninitialized_copy(__first1, __last1, __result); __STL_TRY { - return uninitialized_copy(first2, last2, mid); + return uninitialized_copy(__first2, __last2, __mid); } - __STL_UNWIND(destroy(result, mid)); + __STL_UNWIND(destroy(__result, __mid)); } +// __uninitialized_fill_copy // Fills [result, mid) with x, and copies [first, last) into // [mid, mid + (last - first)). -template -inline ForwardIterator -__uninitialized_fill_copy(ForwardIterator result, ForwardIterator mid, - const T& x, - InputIterator first, InputIterator last) { - uninitialized_fill(result, mid, x); +template +inline _ForwardIter +__uninitialized_fill_copy(_ForwardIter __result, _ForwardIter __mid, + const _Tp& __x, + _InputIter __first, _InputIter __last) +{ + uninitialized_fill(__result, __mid, __x); __STL_TRY { - return uninitialized_copy(first, last, mid); + return uninitialized_copy(__first, __last, __mid); } - __STL_UNWIND(destroy(result, mid)); + __STL_UNWIND(destroy(__result, __mid)); } +// __uninitialized_copy_fill // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and // fills [first2 + (last1 - first1), last2) with x. -template +template inline void -__uninitialized_copy_fill(InputIterator first1, InputIterator last1, - ForwardIterator first2, ForwardIterator last2, - const T& x) { - ForwardIterator mid2 = uninitialized_copy(first1, last1, first2); +__uninitialized_copy_fill(_InputIter __first1, _InputIter __last1, + _ForwardIter __first2, _ForwardIter __last2, + const _Tp& __x) +{ + _ForwardIter __mid2 = uninitialized_copy(__first1, __last1, __first2); __STL_TRY { - uninitialized_fill(mid2, last2, x); + uninitialized_fill(__mid2, __last2, __x); } - __STL_UNWIND(destroy(first2, mid2)); + __STL_UNWIND(destroy(__first2, __mid2)); } __STL_END_NAMESPACE diff --git a/libstdc++/stl/stl_vector.h b/libstdc++/stl/stl_vector.h index cfa7fdb62d3..d1149e9af66 100644 --- a/libstdc++/stl/stl_vector.h +++ b/libstdc++/stl/stl_vector.h @@ -35,12 +35,127 @@ __STL_BEGIN_NAMESPACE #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma set woff 1174 +#pragma set woff 1375 #endif -template -class vector { +// The vector base class serves two purposes. First, its constructor +// and destructor allocate (but don't initialize) storage. This makes +// exception safety easier. Second, the base class encapsulates all of +// the differences between SGI-style allocators and standard-conforming +// allocators. + +#ifdef __STL_USE_STD_ALLOCATORS + +// Base class for ordinary allocators. +template +class _Vector_alloc_base { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return _M_data_allocator; } + + _Vector_alloc_base(const allocator_type& __a) + : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) + {} + +protected: + allocator_type _M_data_allocator; + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + + _Tp* _M_allocate(size_t __n) + { return _M_data_allocator.allocate(__n); } + void _M_deallocate(_Tp* __p, size_t __n) + { if (__p) _M_data_allocator.deallocate(__p, __n); } +}; + +// Specialization for allocators that have the property that we don't +// actually have to store an allocator object. +template +class _Vector_alloc_base<_Tp, _Allocator, true> { +public: + typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type + allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Vector_alloc_base(const allocator_type&) + : _M_start(0), _M_finish(0), _M_end_of_storage(0) + {} + +protected: + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + + typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type; + _Tp* _M_allocate(size_t __n) + { return _Alloc_type::allocate(__n); } + void _M_deallocate(_Tp* __p, size_t __n) + { _Alloc_type::deallocate(__p, __n);} +}; + +template +struct _Vector_base + : public _Vector_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> +{ + typedef _Vector_alloc_base<_Tp, _Alloc, + _Alloc_traits<_Tp, _Alloc>::_S_instanceless> + _Base; + typedef typename _Base::allocator_type allocator_type; + + _Vector_base(const allocator_type& __a) : _Base(__a) {} + _Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) { + _M_start = _M_allocate(__n); + _M_finish = _M_start; + _M_end_of_storage = _M_start + __n; + } + + ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } +}; + +#else /* __STL_USE_STD_ALLOCATORS */ + +template +class _Vector_base { public: - typedef T value_type; + typedef _Alloc allocator_type; + allocator_type get_allocator() const { return allocator_type(); } + + _Vector_base(const _Alloc&) + : _M_start(0), _M_finish(0), _M_end_of_storage(0) {} + _Vector_base(size_t __n, const _Alloc&) + : _M_start(0), _M_finish(0), _M_end_of_storage(0) + { + _M_start = _M_allocate(__n); + _M_finish = _M_start; + _M_end_of_storage = _M_start + __n; + } + + ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } + +protected: + _Tp* _M_start; + _Tp* _M_finish; + _Tp* _M_end_of_storage; + + typedef simple_alloc<_Tp, _Alloc> _M_data_allocator; + _Tp* _M_allocate(size_t __n) + { return _M_data_allocator::allocate(__n); } + void _M_deallocate(_Tp* __p, size_t __n) + { _M_data_allocator::deallocate(__p, __n); } +}; + +#endif /* __STL_USE_STD_ALLOCATORS */ + +template +class vector : protected _Vector_base<_Tp, _Alloc> +{ +private: + typedef _Vector_base<_Tp, _Alloc> _Base; +public: + typedef _Tp value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type* iterator; @@ -50,6 +165,9 @@ public: typedef size_t size_type; typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + allocator_type get_allocator() const { return _Base::get_allocator(); } + #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator const_reverse_iterator; typedef reverse_iterator reverse_iterator; @@ -59,462 +177,632 @@ public: typedef reverse_iterator reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ + protected: - typedef simple_alloc data_allocator; - iterator start; - iterator finish; - iterator end_of_storage; - void insert_aux(iterator position, const T& x); - void deallocate() { - if (start) data_allocator::deallocate(start, end_of_storage - start); - } +#ifdef __STL_HAS_NAMESPACES + using _Base::_M_allocate; + using _Base::_M_deallocate; + using _Base::_M_start; + using _Base::_M_finish; + using _Base::_M_end_of_storage; +#endif /* __STL_HAS_NAMESPACES */ + +protected: + void _M_insert_aux(iterator __position, const _Tp& __x); + void _M_insert_aux(iterator __position); - void fill_initialize(size_type n, const T& value) { - start = allocate_and_fill(n, value); - finish = start + n; - end_of_storage = finish; - } public: - iterator begin() { return start; } - const_iterator begin() const { return start; } - iterator end() { return finish; } - const_iterator end() const { return finish; } - reverse_iterator rbegin() { return reverse_iterator(end()); } - const_reverse_iterator rbegin() const { - return const_reverse_iterator(end()); - } - reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rend() const { - return const_reverse_iterator(begin()); - } - size_type size() const { return size_type(end() - begin()); } - size_type max_size() const { return size_type(-1) / sizeof(T); } - size_type capacity() const { return size_type(end_of_storage - begin()); } - bool empty() const { return begin() == end(); } - reference operator[](size_type n) { return *(begin() + n); } - const_reference operator[](size_type n) const { return *(begin() + n); } - - vector() : start(0), finish(0), end_of_storage(0) {} - vector(size_type n, const T& value) { fill_initialize(n, value); } - vector(int n, const T& value) { fill_initialize(n, value); } - vector(long n, const T& value) { fill_initialize(n, value); } - explicit vector(size_type n) { fill_initialize(n, T()); } - - vector(const vector& x) { - start = allocate_and_copy(x.end() - x.begin(), x.begin(), x.end()); - finish = start + (x.end() - x.begin()); - end_of_storage = finish; - } + iterator begin() { return _M_start; } + const_iterator begin() const { return _M_start; } + iterator end() { return _M_finish; } + const_iterator end() const { return _M_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(_Tp); } + size_type capacity() const + { return size_type(_M_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); } + + explicit vector(const allocator_type& __a = allocator_type()) + : _Base(__a) {} + + vector(size_type __n, const _Tp& __value, + const allocator_type& __a = allocator_type()) + : _Base(__n, __a) + { _M_finish = uninitialized_fill_n(_M_start, __n, __value); } + + explicit vector(size_type __n) + : _Base(__n, allocator_type()) + { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); } + + vector(const vector<_Tp, _Alloc>& __x) + : _Base(__x.size(), __x.get_allocator()) + { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); } + #ifdef __STL_MEMBER_TEMPLATES - template - vector(InputIterator first, InputIterator last) : - start(0), finish(0), end_of_storage(0) - { - range_initialize(first, last, iterator_category(first)); + // Check whether it's an integral type. If so, it's not an iterator. + template + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) : _Base(__a) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_aux(__first, __last, _Integral()); } -#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; + + template + void _M_initialize_aux(_Integer __n, _Integer __value, __true_type) { + _M_start = _M_allocate(__n); + _M_end_of_storage = _M_start + __n; + _M_finish = uninitialized_fill_n(_M_start, __n, __value); + } + + template + void _M_initialize_aux(_InputIterator __first, _InputIterator __last, + __false_type) { + _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first)); } + +#else + vector(const _Tp* __first, const _Tp* __last, + const allocator_type& __a = allocator_type()) + : _Base(__last - __first, __a) + { _M_finish = uninitialized_copy(__first, __last, _M_start); } #endif /* __STL_MEMBER_TEMPLATES */ - ~vector() { - destroy(start, finish); - deallocate(); - } - vector& operator=(const vector& x); - void reserve(size_type n) { - if (capacity() < n) { - const size_type old_size = size(); - iterator tmp = allocate_and_copy(n, start, finish); - destroy(start, finish); - deallocate(); - start = tmp; - finish = tmp + old_size; - end_of_storage = start + n; + + ~vector() { destroy(_M_start, _M_finish); } + + vector<_Tp, _Alloc>& operator=(const vector<_Tp, _Alloc>& __x); + void reserve(size_type __n) { + if (capacity() < __n) { + const size_type __old_size = size(); + iterator __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __tmp; + _M_finish = __tmp + __old_size; + _M_end_of_storage = _M_start + __n; } } + + // assign(), a generalized assignment member function. Two + // versions: one that takes a count, and one that takes a range. + // The range version is a member template, so we dispatch on whether + // or not the type is an integer. + + void assign(size_type __n, const _Tp& __val); + +#ifdef __STL_MEMBER_TEMPLATES + + template + void assign(_InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + template + void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { assign((size_type) __n, (_Tp) __val); } + + template + void _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) + { _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first)); } + + template + void _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template + void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + +#endif /* __STL_MEMBER_TEMPLATES */ + 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; + + void push_back(const _Tp& __x) { + if (_M_finish != _M_end_of_storage) { + construct(_M_finish, __x); + ++_M_finish; } else - insert_aux(end(), x); - } - void swap(vector& x) { - __STD::swap(start, x.start); - __STD::swap(finish, x.finish); - __STD::swap(end_of_storage, x.end_of_storage); - } - iterator insert(iterator position, const T& x) { - size_type n = position - begin(); - if (finish != end_of_storage && position == end()) { - construct(finish, x); - ++finish; + _M_insert_aux(end(), __x); + } + void push_back() { + if (_M_finish != _M_end_of_storage) { + construct(_M_finish); + ++_M_finish; } else - insert_aux(position, x); - return begin() + n; + _M_insert_aux(end()); + } + void swap(vector<_Tp, _Alloc>& __x) { + __STD::swap(_M_start, __x._M_start); + __STD::swap(_M_finish, __x._M_finish); + __STD::swap(_M_end_of_storage, __x._M_end_of_storage); + } + + iterator insert(iterator __position, const _Tp& __x) { + size_type __n = __position - begin(); + if (_M_finish != _M_end_of_storage && __position == end()) { + construct(_M_finish, __x); + ++_M_finish; + } + else + _M_insert_aux(__position, __x); + return begin() + __n; + } + iterator insert(iterator __position) { + size_type __n = __position - begin(); + if (_M_finish != _M_end_of_storage && __position == end()) { + construct(_M_finish); + ++_M_finish; + } + else + _M_insert_aux(__position); + return begin() + __n; } - iterator insert(iterator position) { return insert(position, T()); } #ifdef __STL_MEMBER_TEMPLATES - template - void insert(iterator position, InputIterator first, InputIterator last) { - range_insert(position, first, last, iterator_category(first)); + // Check whether it's an integral type. If so, it's not an iterator. + template + void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__pos, __first, __last, _Integral()); + } + + template + void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, + __true_type) { + insert(__pos, (size_type) __n, (_Tp) __val); + } + + template + void _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) { + _M_range_insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first)); } #else /* __STL_MEMBER_TEMPLATES */ - void insert(iterator position, - const_iterator first, const_iterator 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, size_type __n, const _Tp& __x); + + void pop_back() { + --_M_finish; + destroy(_M_finish); + } + iterator erase(iterator __position) { + if (__position + 1 != end()) + copy(__position + 1, _M_finish, __position); + --_M_finish; + destroy(_M_finish); + return __position; } - void insert (iterator pos, long n, const T& x) { - insert(pos, (size_type) n, x); + iterator erase(iterator __first, iterator __last) { + iterator __i = copy(__last, _M_finish, __first); + destroy(__i, _M_finish); + _M_finish = _M_finish - (__last - __first); + return __first; } - void pop_back() { - --finish; - destroy(finish); - } - iterator erase(iterator position) { - if (position + 1 != end()) - copy(position + 1, finish, position); - --finish; - destroy(finish); - return position; - } - iterator erase(iterator first, iterator last) { - iterator i = copy(last, finish, first); - destroy(i, finish); - finish = finish - (last - first); - return first; - } - void resize(size_type new_size, const T& x) { - if (new_size < size()) - erase(begin() + new_size, end()); + void resize(size_type __new_size, const _Tp& __x) { + if (__new_size < size()) + erase(begin() + __new_size, end()); else - insert(end(), new_size - size(), x); + insert(end(), __new_size - size(), __x); } - void resize(size_type new_size) { resize(new_size, T()); } + void resize(size_type __new_size) { resize(__new_size, _Tp()); } void clear() { erase(begin(), end()); } protected: - iterator allocate_and_fill(size_type n, const T& x) { - iterator result = data_allocator::allocate(n); - __STL_TRY { - uninitialized_fill_n(result, n, x); - return result; - } - __STL_UNWIND(data_allocator::deallocate(result, n)); - } #ifdef __STL_MEMBER_TEMPLATES - template - iterator allocate_and_copy(size_type n, - ForwardIterator first, ForwardIterator last) { - iterator result = data_allocator::allocate(n); + template + iterator _M_allocate_and_copy(size_type __n, _ForwardIterator __first, + _ForwardIterator __last) +{ + iterator __result = _M_allocate(__n); __STL_TRY { - uninitialized_copy(first, last, result); - return result; + uninitialized_copy(__first, __last, __result); + return __result; } - __STL_UNWIND(data_allocator::deallocate(result, n)); + __STL_UNWIND(_M_deallocate(__result, __n)); } #else /* __STL_MEMBER_TEMPLATES */ - iterator allocate_and_copy(size_type n, - const_iterator first, const_iterator last) { - iterator result = data_allocator::allocate(n); + iterator _M_allocate_and_copy(size_type __n, const_iterator __first, + const_iterator __last) + { + iterator __result = _M_allocate(__n); __STL_TRY { - uninitialized_copy(first, last, result); - return result; + uninitialized_copy(__first, __last, __result); + return __result; } - __STL_UNWIND(data_allocator::deallocate(result, n)); + __STL_UNWIND(_M_deallocate(__result, __n)); } #endif /* __STL_MEMBER_TEMPLATES */ #ifdef __STL_MEMBER_TEMPLATES - template - void range_initialize(InputIterator first, InputIterator last, - input_iterator_tag) { - for ( ; first != last; ++first) - push_back(*first); - } - - // This function is only called by the constructor. We have to worry - // about resource leaks, but not about maintaining invariants. - template - void range_initialize(ForwardIterator first, ForwardIterator last, - forward_iterator_tag) { - size_type n = 0; - distance(first, last, n); - start = allocate_and_copy(n, first, last); - finish = start + n; - end_of_storage = finish; - } - - template - void range_insert(iterator pos, - InputIterator first, InputIterator last, - input_iterator_tag); - - template - void range_insert(iterator pos, - ForwardIterator first, ForwardIterator last, - forward_iterator_tag); + template + void _M_range_initialize(_InputIterator __first, + _InputIterator __last, input_iterator_tag) + { + for ( ; __first != __last; ++__first) + push_back(*__first); + } + + // This function is only called by the constructor. + template + void _M_range_initialize(_ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag) + { + size_type __n = 0; + distance(__first, __last, __n); + _M_start = _M_allocate(__n); + _M_end_of_storage = _M_start + __n; + _M_finish = uninitialized_copy(__first, __last, _M_start); + } + + template + void _M_range_insert(iterator __pos, + _InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template + void _M_range_insert(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); #endif /* __STL_MEMBER_TEMPLATES */ }; -template -inline bool operator==(const vector& x, const vector& y) { - return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); +template +inline bool +operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) +{ + return __x.size() == __y.size() && + equal(__x.begin(), __x.end(), __y.begin()); } -template -inline bool operator<(const vector& x, const vector& y) { - return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); +template +inline bool +operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) +{ + return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER -template -inline void swap(vector& x, vector& y) { - x.swap(y); +template +inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y) +{ + __x.swap(__y); } #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */ -template -vector& vector::operator=(const vector& x) { - if (&x != this) { - if (x.size() > capacity()) { - iterator tmp = allocate_and_copy(x.end() - x.begin(), - x.begin(), x.end()); - destroy(start, finish); - deallocate(); - start = tmp; - end_of_storage = start + (x.end() - x.begin()); +template +vector<_Tp,_Alloc>& +vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x) +{ + if (&__x != this) { + const size_type __xlen = __x.size(); + if (__xlen > capacity()) { + iterator __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end()); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __tmp; + _M_end_of_storage = _M_start + __xlen; } - else if (size() >= x.size()) { - iterator i = copy(x.begin(), x.end(), begin()); - destroy(i, finish); + else if (size() >= __xlen) { + iterator __i = copy(__x.begin(), __x.end(), begin()); + destroy(__i, _M_finish); } else { - copy(x.begin(), x.begin() + size(), start); - uninitialized_copy(x.begin() + size(), x.end(), finish); + copy(__x.begin(), __x.begin() + size(), _M_start); + uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish); } - finish = start + x.size(); + _M_finish = _M_start + __xlen; } return *this; } -template -void vector::insert_aux(iterator position, const T& x) { - if (finish != end_of_storage) { - construct(finish, *(finish - 1)); - ++finish; - T x_copy = x; - copy_backward(position, finish - 2, finish - 1); - *position = x_copy; +template +void vector<_Tp, _Alloc>::assign(size_t __n, const value_type& __val) { + if (__n > capacity()) { + vector<_Tp, _Alloc> __tmp(__n, __val, get_allocator()); + __tmp.swap(*this); + } + else if (__n > size()) { + fill(begin(), end(), __val); + _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val); + } + else + erase(fill_n(begin(), __n, __val), end()); +} + +#ifdef __STL_MEMBER_TEMPLATES + +template template +void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last, + input_iterator_tag) { + iterator __cur = begin(); + for ( ; __first != __last && __cur != end(); ++__cur, ++__first) + *__cur = *__first; + if (__first == __last) + erase(__cur, end()); + else + insert(end(), __first, __last); +} + +template template +void +vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIter __first, _ForwardIter __last, + forward_iterator_tag) { + size_type __len = 0; + distance(__first, __last, __len); + + if (__len > capacity()) { + iterator __tmp = _M_allocate_and_copy(__len, __first, __last); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __tmp; + _M_end_of_storage = _M_finish = _M_start + __len; + } + else if (size() >= __len) { + iterator __new_finish = copy(__first, __last, _M_start); + destroy(__new_finish, _M_finish); + _M_finish = __new_finish; + } + else { + _ForwardIter __mid = __first; + advance(__mid, size()); + copy(__first, __mid, _M_start); + _M_finish = uninitialized_copy(__mid, __last, _M_finish); + } +} + +#endif /* __STL_MEMBER_TEMPLATES */ + +template +void +vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x) +{ + if (_M_finish != _M_end_of_storage) { + construct(_M_finish, *(_M_finish - 1)); + ++_M_finish; + _Tp __x_copy = __x; + copy_backward(__position, _M_finish - 2, _M_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; + const size_type __old_size = size(); + const size_type __len = __old_size != 0 ? 2 * __old_size : 1; + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; __STL_TRY { - new_finish = uninitialized_copy(start, position, new_start); - construct(new_finish, x); - ++new_finish; - new_finish = uninitialized_copy(position, finish, new_finish); + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + construct(__new_finish, __x); + ++__new_finish; + __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); } + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(begin(), end()); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; + } +} -# ifdef __STL_USE_EXCEPTIONS - catch(...) { - destroy(new_start, new_finish); - data_allocator::deallocate(new_start, len); - throw; +template +void +vector<_Tp, _Alloc>::_M_insert_aux(iterator __position) +{ + if (_M_finish != _M_end_of_storage) { + construct(_M_finish, *(_M_finish - 1)); + ++_M_finish; + copy_backward(__position, _M_finish - 2, _M_finish - 1); + *__position = _Tp(); + } + else { + const size_type __old_size = size(); + const size_type __len = __old_size != 0 ? 2 * __old_size : 1; + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; + __STL_TRY { + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + construct(__new_finish); + ++__new_finish; + __new_finish = uninitialized_copy(__position, _M_finish, __new_finish); } -# endif /* __STL_USE_EXCEPTIONS */ + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); destroy(begin(), end()); - deallocate(); - start = new_start; - finish = new_finish; - end_of_storage = new_start + len; + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; } } -template -void vector::insert(iterator position, size_type n, const T& x) { - if (n != 0) { - if (size_type(end_of_storage - finish) >= n) { - T x_copy = x; - const size_type elems_after = finish - position; - iterator old_finish = finish; - if (elems_after > n) { - uninitialized_copy(finish - n, finish, finish); - finish += n; - copy_backward(position, old_finish - n, old_finish); - fill(position, position + n, x_copy); +template +void vector<_Tp, _Alloc>::insert(iterator __position, size_type __n, + const _Tp& __x) +{ + if (__n != 0) { + if (size_type(_M_end_of_storage - _M_finish) >= __n) { + _Tp __x_copy = __x; + const size_type __elems_after = _M_finish - __position; + iterator __old_finish = _M_finish; + if (__elems_after > __n) { + uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); + _M_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); + uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy); + _M_finish += __n - __elems_after; + uninitialized_copy(__position, __old_finish, _M_finish); + _M_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; + const size_type __old_size = size(); + const size_type __len = __old_size + max(__old_size, __n); + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; __STL_TRY { - new_finish = uninitialized_copy(start, position, new_start); - new_finish = uninitialized_fill_n(new_finish, n, x); - new_finish = uninitialized_copy(position, finish, new_finish); + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + __new_finish = uninitialized_fill_n(__new_finish, __n, __x); + __new_finish + = uninitialized_copy(__position, _M_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; + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; } } } #ifdef __STL_MEMBER_TEMPLATES -template template -void vector::range_insert(iterator pos, - InputIterator first, InputIterator last, - input_iterator_tag) { - for ( ; first != last; ++first) { - pos = insert(pos, *first); - ++pos; +template template +void +vector<_Tp, _Alloc>::_M_range_insert(iterator __pos, + _InputIterator __first, + _InputIterator __last, + input_iterator_tag) +{ + for ( ; __first != __last; ++__first) { + __pos = insert(__pos, *__first); + ++__pos; } } -template template -void vector::range_insert(iterator position, - ForwardIterator first, - ForwardIterator last, - forward_iterator_tag) { - if (first != last) { - size_type n = 0; - distance(first, last, n); - if (size_type(end_of_storage - finish) >= n) { - const size_type elems_after = finish - position; - iterator old_finish = finish; - if (elems_after > n) { - uninitialized_copy(finish - n, finish, finish); - finish += n; - copy_backward(position, old_finish - n, old_finish); - copy(first, last, position); +template template +void +vector<_Tp, _Alloc>::_M_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(_M_end_of_storage - _M_finish) >= __n) { + const size_type __elems_after = _M_finish - __position; + iterator __old_finish = _M_finish; + if (__elems_after > __n) { + uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); + _M_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); + _ForwardIterator __mid = __first; + advance(__mid, __elems_after); + uninitialized_copy(__mid, __last, _M_finish); + _M_finish += __n - __elems_after; + uninitialized_copy(__position, __old_finish, _M_finish); + _M_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; + const size_type __old_size = size(); + const size_type __len = __old_size + max(__old_size, __n); + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; __STL_TRY { - new_finish = uninitialized_copy(start, position, new_start); - new_finish = uninitialized_copy(first, last, new_finish); - new_finish = uninitialized_copy(position, finish, new_finish); - } -# ifdef __STL_USE_EXCEPTIONS - catch(...) { - destroy(new_start, new_finish); - data_allocator::deallocate(new_start, len); - throw; + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + __new_finish = uninitialized_copy(__first, __last, __new_finish); + __new_finish + = uninitialized_copy(__position, _M_finish, __new_finish); } -# endif /* __STL_USE_EXCEPTIONS */ - destroy(start, finish); - deallocate(); - start = new_start; - finish = new_finish; - end_of_storage = new_start + len; + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; } } } #else /* __STL_MEMBER_TEMPLATES */ -template -void vector::insert(iterator position, - const_iterator first, - const_iterator last) { - if (first != last) { - size_type n = 0; - distance(first, last, n); - if (size_type(end_of_storage - finish) >= n) { - const size_type elems_after = finish - position; - iterator old_finish = finish; - if (elems_after > n) { - uninitialized_copy(finish - n, finish, finish); - finish += n; - copy_backward(position, old_finish - n, old_finish); - copy(first, last, position); +template +void +vector<_Tp, _Alloc>::insert(iterator __position, + const_iterator __first, + const_iterator __last) +{ + if (__first != __last) { + size_type __n = 0; + distance(__first, __last, __n); + if (size_type(_M_end_of_storage - _M_finish) >= __n) { + const size_type __elems_after = _M_finish - __position; + iterator __old_finish = _M_finish; + if (__elems_after > __n) { + uninitialized_copy(_M_finish - __n, _M_finish, _M_finish); + _M_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); + uninitialized_copy(__first + __elems_after, __last, _M_finish); + _M_finish += __n - __elems_after; + uninitialized_copy(__position, __old_finish, _M_finish); + _M_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; + const size_type __old_size = size(); + const size_type __len = __old_size + max(__old_size, __n); + iterator __new_start = _M_allocate(__len); + iterator __new_finish = __new_start; __STL_TRY { - new_finish = uninitialized_copy(start, position, new_start); - new_finish = uninitialized_copy(first, last, new_finish); - new_finish = uninitialized_copy(position, finish, new_finish); - } -# ifdef __STL_USE_EXCEPTIONS - catch(...) { - destroy(new_start, new_finish); - data_allocator::deallocate(new_start, len); - throw; + __new_finish = uninitialized_copy(_M_start, __position, __new_start); + __new_finish = uninitialized_copy(__first, __last, __new_finish); + __new_finish + = uninitialized_copy(__position, _M_finish, __new_finish); } -# endif /* __STL_USE_EXCEPTIONS */ - destroy(start, finish); - deallocate(); - start = new_start; - finish = new_finish; - end_of_storage = new_start + len; + __STL_UNWIND((destroy(__new_start,__new_finish), + _M_deallocate(__new_start,__len))); + destroy(_M_start, _M_finish); + _M_deallocate(_M_start, _M_end_of_storage - _M_start); + _M_start = __new_start; + _M_finish = __new_finish; + _M_end_of_storage = __new_start + __len; } } } @@ -523,6 +811,7 @@ void vector::insert(iterator position, #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) #pragma reset woff 1174 +#pragma reset woff 1375 #endif __STL_END_NAMESPACE diff --git a/libstdc++/stl/tempbuf.h b/libstdc++/stl/tempbuf.h index 8799393f39f..aa4f289c582 100644 --- a/libstdc++/stl/tempbuf.h +++ b/libstdc++/stl/tempbuf.h @@ -30,15 +30,18 @@ #ifndef __SGI_STL_PAIR_H #include #endif -#include -#include -#include +#include /* XXX should use */ +#include /* XXX should use */ +#include /* XXX should use */ #ifndef __TYPE_TRAITS_H #include #endif #ifndef __SGI_STL_INTERNAL_CONSTRUCT_H #include #endif +#ifndef __SGI_STL_INTERNAL_UNINITIALIZED_H +#include +#endif #ifndef __SGI_STL_INTERNAL_TEMPBUF_H #include #endif diff --git a/libstdc++/stl/type_traits.h b/libstdc++/stl/type_traits.h index 40c633913e1..b6a7dfc6de9 100644 --- a/libstdc++/stl/type_traits.h +++ b/libstdc++/stl/type_traits.h @@ -40,13 +40,14 @@ attain their correct values by one of these means: EXAMPLE: //Copy an array of elements which have non-trivial copy constructors -template void copy(T* source,T* destination,int n,__false_type); +template void copy(T* source, T* destination, int n, __false_type); //Copy an array of elements which have trivial copy constructors. Use memcpy. -template void copy(T* source,T* destination,int n,__true_type); +template void copy(T* source, T* destination, int n, __true_type); //Copy an array of any type by using the most efficient copy mechanism template inline void copy(T* source,T* destination,int n) { - copy(source,destination,n,typename __type_traits::has_trivial_copy_constructor()); + copy(source, destination, n, + typename __type_traits::has_trivial_copy_constructor()); } */ @@ -57,7 +58,7 @@ struct __true_type { struct __false_type { }; -template +template struct __type_traits { typedef __true_type this_dummy_member_must_be_first; /* Do not remove this member. It informs a compiler which @@ -90,6 +91,18 @@ struct __type_traits { // have built-in __types_traits support, and essential for compilers // that don't. +#ifndef __STL_NO_BOOL + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#endif /* __STL_NO_BOOL */ + __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; @@ -114,6 +127,18 @@ __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type is_POD_type; }; +#ifdef __STL_HAS_WCHAR_T + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#endif /* __STL_HAS_WCHAR_T */ + __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; @@ -162,6 +187,26 @@ __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type is_POD_type; }; +#ifdef __STL_LONG_LONG + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +#endif /* __STL_LONG_LONG */ + __STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; @@ -188,8 +233,8 @@ __STL_TEMPLATE_NULL struct __type_traits { #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION -template -struct __type_traits { +template +struct __type_traits<_Tp*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; @@ -199,7 +244,31 @@ struct __type_traits { #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ -struct __type_traits { +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { + typedef __true_type has_trivial_default_constructor; + typedef __true_type has_trivial_copy_constructor; + typedef __true_type has_trivial_assignment_operator; + typedef __true_type has_trivial_destructor; + typedef __true_type is_POD_type; +}; + +__STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; @@ -207,7 +276,7 @@ struct __type_traits { typedef __true_type is_POD_type; }; -struct __type_traits { +__STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; @@ -215,7 +284,7 @@ struct __type_traits { typedef __true_type is_POD_type; }; -struct __type_traits { +__STL_TEMPLATE_NULL struct __type_traits { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; @@ -226,6 +295,77 @@ struct __type_traits { #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ +// The following could be written in terms of numeric_limits. +// We're doing it separately to reduce the number of dependencies. + +template struct _Is_integer { + typedef __false_type _Integral; +}; + +#ifndef __STL_NO_BOOL + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +#endif /* __STL_NO_BOOL */ + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +#ifdef __STL_HAS_WCHAR_T + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +#endif /* __STL_HAS_WCHAR_T */ + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +#ifdef __STL_LONG_LONG + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +__STL_TEMPLATE_NULL struct _Is_integer { + typedef __true_type _Integral; +}; + +#endif /* __STL_LONG_LONG */ + #endif /* __TYPE_TRAITS_H */ // Local Variables: -- 2.11.0